En este instructivo, se proporcionan instrucciones para transmitir mensajes HL7v2 a través de conexiones TCP/IP mediante el protocolo de capa inferior mínima (MLLP). Para solicitar que la imagen de MLLP esté firmada por un certificador, sigue los pasos en Transmite mensajes HL7v2 a través de conexiones TCP/IP con una imagen de MLLP firmada.
En este instructivo, se proporcionan instrucciones para ejecutar el adaptador MLLP de código abierto alojados en GitHub en los siguientes entornos:
- De forma local/local.
- En un contenedor en GKE con Cloud VPN.
- En un contenedor en GKE sin Cloud VPN
Objetivos
Después de completar el instructivo, sabrás cómo realizar las siguientes actividades:
- Compila y configura el adaptador de MLLP de forma local con la API de Cloud Healthcare y prueba el envío de mensajes HL7v2 a un almacén HL7v2.
- Implementa el adaptador de MLLP en GKE y envía mensajes HL7v2 desde una instancia de VM de Compute Engine.
- Configura una VPN que asegure la conexión entre una instancia “local” y el adaptador de MLLP y envía mensajes HL7v2 desde la instancia “local”.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
- Cloud Healthcare API
- Google Kubernetes Engine
- Compute Engine
- Cloud VPN
- Pub/Sub
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Antes de comenzar
Antes de comenzar este instructivo, familiarízate con la documentación conceptual sobre el protocolo de capa inferior mínima (MLLP) mediante la revisión de MLLP y el adaptador de MLLP de Google Cloud . La documentación conceptual proporciona una descripción general de MLLP, cómo los sistemas de cuidado pueden enviar y recibir mensajes hacia y desde la API de Cloud Healthcare a través de una conexión MLLP y los conceptos básicos de seguridad de MLLP.
Antes de configurar el adaptador de MLLP, debes elegir o crear un proyecto de Google Cloud y habilitar las API necesarias mediante los siguientes pasos:
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Healthcare API, Google Kubernetes Engine, Container Registry, and Pub/Sub APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Healthcare API, Google Kubernetes Engine, Container Registry, and Pub/Sub APIs.
- Espera a que la API de Kubernetes Engine y los servicios relacionados se habiliten. Esto puede tomar varios minutos.
Elige un shell
Para completar este instructivo, puedes usar Cloud Shell o tu shell local.
Cloud Shell es un entorno de shell que se usa para administrar recursos alojados en Google Cloud. Cloud Shell viene
preinstalado con la gcloud CLI y
el kubectl
herramienta. La CLI de gcloud proporciona la interfaz de línea de comandos principal para Google Cloud. kubectl
proporciona la interfaz de línea de comandos para ejecutar comandos en clústeres de GKE.
Si prefieres usar tu shell local, debes instalar la CLI de gcloud.
Para abrir Cloud Shell o configurar tu shell local, completa los siguientes pasos:
Cloud Shell
Para iniciar Cloud Shell, sigue estos pasos:
Ve a la consola de Google Cloud.
En la esquina superior derecha de la consola, haz clic en el botón Activar Google Cloud Shell:
Se abrirá una sesión de Cloud Shell dentro de un marco en la parte inferior de la consola. Usa este shell para ejecutar los comandos gcloud
y kubectl
.
Shell local
Para instalar la CLI de gcloud y la herramienta de kubectl
, completa los siguientes pasos:
- Instala y, luego, inicializa Google Cloud CLI.
-
If you're using a local shell, then create local authentication credentials for your user account:
gcloud auth application-default login
You don't need to do this if you're using Cloud Shell.
Si solo pruebas el adaptador de manera local, no necesitas completar más pasos y puedes continuar Crea un conjunto de datos. Si implementas el adaptador en GKE, ejecuta el siguiente comando para instalar la herramienta de línea de comandos de
kubectl
:gcloud components install kubectl
Crea un conjunto de datos
Si aún no creaste un conjunto de datos de la API de Cloud Healthcare, sigue estos pasos para crear uno:
Consola
- En la consola de Google Cloud, ve a la página Conjuntos de datos.
- Haga clic en Crear conjunto de datos.
-
En el campo Nombre, ingresa un identificador para el conjunto de datos. El ID del conjunto de datos debe tener lo siguiente:
- Un ID único en su ubicación
- Una string de Unicode de 1 a 256 caracteres que consiste en lo siguiente:
- Números
- Letras
- Guiones bajos
- Guiones:
- Puntos:
-
En la sección Tipo de ubicación, elige uno de los siguientes tipos de ubicaciones:
- Región: El conjunto de datos reside de forma permanente dentro de una región de Google Cloud. Después de la selección, escribe o selecciona la ubicación en el campo Región.
- Multirregión: El conjunto de datos reside de manera permanente en una ubicación que abarca varias regiones de Google Cloud. Después de seleccionar, escribe o selecciona la ubicación multirregional en el campo multirregión.
- Haz clic en Crear.
El conjunto de datos nuevo aparecerá en la lista de conjuntos de datos.
gcloud
Para crear un conjunto de datos, ejecuta el comando gcloud healthcare datasets create
:
gcloud healthcare datasets create DATASET_ID \ --location=LOCATION
Si la solicitud es exitosa, el comando mostrará el siguiente resultado:
Create request issued for: [DATASET_ID] Waiting for operation [OPERATION_ID] to complete...done. Created dataset [DATASET_ID].
Crea una suscripción y un tema de Pub/Sub
Para recibir notificaciones cuando se crean o transfieren mensajes, debes configurar un tema de Pub/Sub con tu almacén HL7v2. Para obtener más información, consulta Configura notificaciones de Pub/Sub.
Para crear un tema, completa los siguientes pasos:
Consola
Ve a la página Temas de Pub/Sub en la consola de Google Cloud.
Haz clic en Crear tema.
Ingresa un nombre de tema con el URI:
projects/PROJECT_ID/topics/TOPIC_NAME
En el ejemplo anterior, PROJECT_ID es el ID del proyecto de Google Cloud.
Haga clic en Crear.
gcloud
Para crear un tema, ejecuta el comando gcloud pubsub topics create
:
gcloud pubsub topics create projects/PROJECT_ID/topics/TOPIC_NAME
Si la solicitud es exitosa, el comando mostrará el siguiente resultado:
Created topic [projects/PROJECT_ID/topics/TOPIC_NAME].
Para crear una suscripción, realiza los pasos que se indican a continuación.
Consola
Ve a la página Temas de Pub/Sub en la consola de Google Cloud.
Haz clic en el tema de tu proyecto.
Haz clic en Crear suscripción.
Ingresa un nombre de suscripción.
projects/PROJECT_ID/subscriptions/SUBSCRIPTION_NAME
Deja el Tipo de entrega configurado en Extraer y, luego, haz clic en Crear.
gcloud
Para crear una suscripción, ejecuta el comando gcloud pubsub subscriptions create
.
gcloud pubsub subscriptions create SUBSCRIPTION_NAME \ --topic=projects/PROJECT_ID/topics/TOPIC_NAME
Si la solicitud es exitosa, el comando mostrará el siguiente resultado:
Created subscription [projects/PROJECT_ID/subscriptions/SUBSCRIPTION_NAME].
Crea una tienda HL7v2 configurada con un tema de Pub/Sub
Crea una tienda HL7v2 y configurarla con un tema de Pub/Sub Para crear una tienda HL7v2, ya debes haber creado un conjunto de datos. A los fines de este instructivo, usa el mismo proyecto para tu almacén de HL7v2 y el tema de Pub/Sub.
Para crear una tienda HL7v2 configurada con un tema de Pub/Sub, completa los siguientes pasos:
curl
curl -X POST \ --data "{ 'notificationConfigs': [ { 'pubsubTopic': 'projects/PROJECT_ID/topics/PUBSUB_TOPIC', 'filter': '' } ] }" \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores?hl7V2StoreId=HL7V2_STORE_ID"
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID", "notificationConfigs": [ { "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC" } ] }
PowerShell
$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-WebRequest ` -Method Post ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -Body "{ 'notificationConfigs': [ { 'pubsubTopic': 'projects/PROJECT_ID/topics/PUBSUB_TOPIC', 'filter': '' } ] }" ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores?hl7V2StoreId=HL7V2_STORE_ID" | Select-Object -Expand Content
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID", "notificationConfigs": [ { "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC" } ] }
Configura permisos de Pub/Sub
Para enviar notificaciones a Pub/Sub cuando se crea o transfiere un mensaje HL7v2, debes configurar los permisos de Pub/Sub en la API de Cloud Healthcare. Este paso se debe realizar una vez por proyecto.
Para agregar la función pubsub.publisher
requerida a la cuenta de servicio de tu proyecto, completa los siguientes pasos:
Consola
En la página IAM de la consola de Google Cloud, verifica que la función Agente de servicio de Healthcare aparezca en la columna Rol para la cuenta de servicio del proyecto correspondiente. El nombre de la cuenta es service-PROJECT_NUMBER@gcp-sa-healthcare.iam.gserviceaccount.com. Para obtener información sobre cómo encontrar el PROJECT_NUMBER, consulta Identifica proyectos.
En la columna Herencia que coincide con la función, haz clic en el ícono de lápiz. Se abrirá el panel Editar permisos.
Haz clic en Agregar otra función y, luego, busca la función de Publicador de Pub/Sub.
Selecciona la función y haz clic en Guardar. La función
pubsub.publisher
se agrega a la cuenta de servicio.
gcloud
Para agregar los permisos de la cuenta de servicio, ejecuta el comando gcloud projects add-iam-policy-binding
. Para obtener más información sobre cómo encontrar PROJECT_ID y PROJECT_NUMBER, consulta Identifica proyectos.
gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-healthcare.iam.gserviceaccount.com \ --role=roles/pubsub.publisher
Extrae la imagen de Docker compilada previamente
El adaptador de MLLP es una aplicación en contenedores almacenada en etapa intermedia en una imagen de Docker compilada previamente en Container Registry.
Para obtener la versión más reciente de la imagen, ejecuta el siguiente comando:
docker pull gcr.io/cloud-healthcare-containers/mllp-adapter:latest
Prueba el adaptador de MLLP de forma local
Cuando pruebes el adaptador de forma local, puedes configurarlo para que se ejecute como receptor, publicador o ambos. Las configuraciones de receptor y publicador tienen las siguientes diferencias clave:
- Cuando el adaptador se ejecuta como un receptor, recibe mensajes HL7v2 de una fuente externa y llama a
messages.ingest
para transferir los mensajes a un almacén HL7v2, lo que crea una notificación de Pub/Sub. La notificación se envía a las aplicaciones suscritas al tema de Pub/Sub del almacén HL7v2. - Cuando el adaptador se ejecuta como publicador, detecta los mensajes HL7v2 que se crearon o transfirieron en un almacén HL7v2 mediante el uso de
messages.create
omessages.ingest
. Después de crear un mensaje, se envía una notificación de Pub/Sub al adaptador y este publica los mensajes en un receptor externo.
En las siguientes secciones, se muestra cómo ejecutar el adaptador para que actúe como receptor o publicador.
Después de verificar que puedes ejecutar el adaptador de MLLP en tu máquina local, puedes continuar con la siguiente sección en Implementa el adaptador de MLLP en Google Kubernetes Engine.
Prueba el adaptador de MLLP de manera local como receptor
Cuando el adaptador recibe un mensaje HL7v2 de una fuente externa, como un centro de atención médica, el adaptador llama a messages.ingest
y transfiere el mensaje HL7v2 a la tienda HL7v2 configurada. Puedes observar esto en el código fuente del adaptador.
Para probar el adaptador de forma local como receptor, completa los siguientes pasos:
En la máquina en la que extrajiste la imagen de Docker compilada con anterioridad, ejecuta el siguiente comando:
docker run \ --network=host \ -v ~/.config:/root/.config \ gcr.io/cloud-healthcare-containers/mllp-adapter \ /usr/mllp_adapter/mllp_adapter \ --hl7_v2_project_id=PROJECT_ID \ --hl7_v2_location_id=LOCATION \ --hl7_v2_dataset_id=DATASET_ID \ --hl7_v2_store_id=HL7V2_STORE_ID \ --export_stats=false \ --receiver_ip=0.0.0.0 \ --port=2575 \ --api_addr_prefix=https://healthcare.googleapis.com:443/v1 \ --logtostderr
Donde:
- PROJECT_ID es el ID del proyecto de Google Cloud que contiene tu almacén HL7v2.
- LOCATION es la región en la que se encuentra tu almacén HL7v2.
- DATASET_ID es el ID del conjunto de datos superior de tu almacén HL7v2.
- HL7V2_STORE_ID es el ID de la tienda HL7v2 al que envías mensajes HL7v2.
Después de ejecutar el comando anterior, el adaptador imprime un mensaje similar al siguiente y comienza a ejecutarse en tu máquina local en la dirección IP 127.0.0.1 en el puerto 2575:
I0000 00:00:00.000000 1 healthapiclient.go:171] Dialing connection to https://healthcare.googleapis.com:443/v1 I0000 00:00:00.000000 1 mllp_adapter.go:89] Either --pubsub_project_id or --pubsub_subscription is not provided, notifications of the new messages are not read and no outgoing messages will be sent to the target MLLP address.
Si encuentras algún error, sigue estos pasos para solucionar el problema:
Si usas macOS y el comando anterior falla con un error
Connection refused
, consulta Error de conexión rechazada cuando se ejecuta de forma local.Si el comando anterior falla con un error
healthapiclient.NewHL7V2Client: oauth2google.DefaultTokenSource: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
, consulta errorcould not find default credentials
cuando se ejecuta de manera local.Si encuentras algún otro error de autenticación, consulta Errores de autenticación.
Para continuar con las pruebas mientras el adaptador se ejecuta como un proceso en primer plano, abre una terminal diferente en tu máquina local.
En la terminal nueva, para instalar Netcat, ejecuta el siguiente comando:
sudo apt install netcat
Descarga el archivo
hl7v2-mllp-sample.txt
y guárdalo en tu máquina local.Para enviar el mensaje HL7v2 al adaptador, ejecuta el siguiente comando en el directorio donde descargaste el archivo. El adaptador de MLLP está escuchando en tu host local en el puerto 2575. El comando envía el mensaje a través del adaptador de MLLP a tu almacén HL7v2.
Linux
echo -n -e "\x0b$(cat hl7v2-mllp-sample.txt)\x1c\x0d" | nc -q1 localhost 2575 | less
Si el mensaje se transfirió correctamente al almacén de HL7v2, el comando mostrará el siguiente resultado:
^KMSH|^~\&|TO_APP|TO_FACILITY|FROM_APP|FROM_FACILITY|19700101010000||ACK|c507a97e-438d-44b0-b236-ea95e5ecbbfb|P|2.5^MMSA|AA|20150503223000^\
Este resultado indica que la tienda HL7v2 respondió con un tipo de respuesta
AA
(Application Accept
), lo que significa que el mensaje se valida y se transfiere correctamente.También puedes verificar que el mensaje se haya enviado de forma correcta si abres la terminal en la que ejecutaste el adaptador. El resultado debería verse como la siguiente muestra:
I0000 00:00:00.000000 1 healthapiclient.go:171] Dialing connection to https://healthcare.googleapis.com:443/v1 I0000 00:00:00.000000 1 mllp_adapter.go:89] Either --pubsub_project_id or --pubsub_subscription is not provided, notifications of the new messages are not read and no outgoing messages will be sent to the target MLLP address. I0213 00:00:00.000000 1 healthapiclient.go:190] Sending message of size 319. I0213 00:00:00.000000 1 healthapiclient.go:223] Message was successfully sent.
El mensaje se almacena en tu almacén de HL7v2, por lo que puedes llamar a
messages.list
para ver el mensaje:curl
curl -X GET \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages"
Si la solicitud es exitosa, el servidor muestra el ID del mensaje en una ruta de recursos:
{ "hl7V2Messages": [ { "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID" } ] }
PowerShell
$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-WebRequest ` -Method Get ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages" | Select-Object -Expand Content
Si la solicitud es exitosa, el servidor muestra el ID del mensaje en una ruta de recursos:
{ "hl7V2Messages": [ { "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID" } ] }
Prueba el adaptador de MLLP de manera local como publicador
Cuando pruebas el adaptador como publicador, debes crear mensajes mediante una llamada a messages.create
o messages.ingest
y suministra un archivo de mensaje como datos binarios.
El adaptador reconoce de forma automática los mensajes de Pub/Sub que se enviaron a través de messages.create
y messages.ingest
.
El adaptador te notifica cuando recupera y envía mensajes de Pub/Sub correctamente. El adaptador es un suscriptor de Pub/Sub, por lo que reconoce de forma automática estos mensajes. Como resultado, se quitan de la cola de mensajes de la suscripción a Pub/Sub que configuraste con el adaptador.
Para extraer la suscripción a Pub/Sub y verificar por separado que los mensajes se publicaron, debes crear una segunda suscripción a Pub/Sub asignada al tema que creaste anteriormente. El adaptador no reconoce automáticamente los mensajes enviados a la segunda suscripción y quedan, por lo que puedes extraerlos.
Para crear una segunda suscripción a Pub/Sub asignada al tema que creaste anteriormente, completa los siguientes pasos:
Consola
Ve a la página Temas de Pub/Sub en la consola de Google Cloud.
Haz clic en el tema de tu proyecto. Este es el tema que usaste para crear la suscripción inicial.
Haz clic en Crear suscripción.
Ingresa un nombre de suscripción.
projects/PROJECT_ID/subscriptions/SECOND_SUBSCRIPTION_NAME
Configura el Tipo de entrega como Extracción.
Haz clic en Crear.
gcloud
Para crear una segunda suscripción a Pub/Sub asignada al tema que creaste anteriormente, ejecuta el comando gcloud pubsub subscriptions create
:
gcloud pubsub subscriptions create SECOND_SUBSCRIPTION_NAME --topic=projects/PROJECT_ID/topics/TOPIC_NAME
Si la solicitud es exitosa, el comando mostrará el siguiente resultado:
Created subscription [projects/PROJECT_ID/subscriptions/SECOND_SUBSCRIPTION_NAME].
Para probar el adaptador de forma local como publicador, completa los siguientes pasos en la máquina en la que extrajiste la imagen precompilada de Docker:
Instala Netcat:
sudo apt install netcat
Descarga el archivo
hl7v2-mllp-ack-sample.txt
y guárdalo en tu máquina local. El archivo contiene un mensaje ACK que el adaptador requiere como respuesta cuando intenta publicar un mensaje.Para permitir que Netcat detecte las conexiones entrantes en el puerto 2525, en el directorio donde descargaste el archivo, ejecuta el comando siguiente.
Linux
echo -n -e "\x0b$(cat hl7v2-mllp-ack-sample.txt)\x1c\x0d" | nc -q1 -lv -p 2525 | less
Después de iniciar Netcat, se muestra un mensaje de resultado similar al del siguiente ejemplo:
listening on [any] 2525 ...
Netcat se ejecuta como un proceso en primer plano, por lo que para continuar con las pruebas, abre otra terminal en tu máquina local.
Para iniciar el adaptador, ejecuta el siguiente comando en la terminal nueva:
docker run \ --network=host \ gcr.io/cloud-healthcare-containers/mllp-adapter \ /usr/mllp_adapter/mllp_adapter \ --hl7_v2_project_id=PROJECT_ID \ --hl7_v2_location_id=LOCATION \ --hl7_v2_dataset_id=DATASET_ID \ --hl7_v2_store_id=HL7V2_STORE_ID \ --export_stats=false \ --receiver_ip=127.0.0.1 --port 2575 \ --mllp_addr=127.0.0.1:2525 \ --pubsub_project_id=PROJECT_ID \ --pubsub_subscription=PUBSUB_SUBSCRIPTION \ --api_addr_prefix=https://healthcare.googleapis.com:443/v1 \ --logtostderr
Donde:
- PROJECT_ID es el ID del proyecto de Google Cloud que contiene tu almacén HL7v2.
- LOCATION es la región en la que se encuentra tu almacén HL7v2.
- DATASET_ID es el ID del conjunto de datos superior de tu almacén HL7v2.
- HL7V2_STORE_ID es el ID de la tienda HL7v2 al que envías mensajes HL7v2.
- PROJECT_ID es el ID del proyecto de Google Cloud que contiene el tema de Pub/Sub.
- PUBSUB_SUBSCRIPTION es el nombre de la primera suscripción que creaste asociada a tu tema de Pub/Sub. El adaptador consume mensajes de esta suscripción y los reconoce automáticamente, por lo tanto, para ver los mensajes publicados en el tema, debes extraer los mensajes de la segunda suscripción que creaste antes.
Después de ejecutar el comando anterior, el adaptador comienza a ejecutarse en tu máquina local en la dirección IP 127.0.0.1 en el puerto 2575.
Si encuentras algún error, sigue estos pasos para solucionar el problema:
Si usas macOS y el comando anterior falla con un error
Connection refused
, consulta Error de conexión rechazada cuando se ejecuta de forma local.Si el comando anterior falla con un error
healthapiclient.NewHL7V2Client: oauth2google.DefaultTokenSource: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
, consulta errorcould not find default credentials
cuando se ejecuta de manera local.Si encuentras algún otro error de autenticación, consulta Errores de autenticación.
El adaptador se ejecuta como un proceso en primer plano, por lo tanto, para continuar con la prueba, abre una terminal diferente en tu máquina local.
Descarga el archivo
hl7v2-sample.json
y guárdalo en tu máquina local. En el directorio donde descargaste el archivo, llama al métodomessages.create
para crear el mensaje en un almacén HL7v2:curl
Para crear un mensaje HL7v2, realiza una solicitud
POST
y especifica la siguiente información:- El nombre del conjunto de datos superior
- El nombre del almacén de HL7v2
- Un mensaje
- Un token de acceso
En el siguiente ejemplo, se muestra una solicitud
POST
concurl
y un archivo JSON de ejemplo llamadohl7v2-sample.json
.curl -X POST \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ --data-binary @hl7v2-sample.json \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages"
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID", "data": "TVNIfF5+XCZ8QXxTRU5EX0ZBQ0lMSVRZfEF8QXwyMDE4MDEwMTAwMDAwMHx8VFlQRV5BfDIwMTgwMTAxMDAwMDAwfFR8MC4wfHx8QUF8fDAwfEFTQ0lJDUVWTnxBMDB8MjAxODAxMDEwNDAwMDANUElEfHwxNAExMTFeXl5eTVJOfDExMTExMTExXl5eXk1STn4xMTExMTExMTExXl5eXk9SR05NQlI=", "sendFacility": "SEND_FACILITY", "sendTime": "2018-01-01T00:00:00Z", "messageType": "TYPE", "createTime": "1970-01-01T00:00:00Z", "patientIds": [ { "value": "14\u0001111", "type": "MRN" }, { "value": "11111111", "type": "MRN" }, { "value": "1111111111", "type": "ORGNMBR" } ] }
PowerShell
Para crear un mensaje HL7v2, realiza una solicitud
POST
y especifica la siguiente información:- El nombre del conjunto de datos superior
- El nombre del almacén de HL7v2
- Un mensaje
- Un token de acceso
En el siguiente ejemplo, se muestra una solicitud
POST
mediante Windows PowerShell y un archivo JSON de muestra llamadohl7v2-sample.json
.$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-WebRequest ` -Method Post ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -InFile hl7v2-sample.json ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages" | Select-Object -Expand Content
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID", "data": "TVNIfF5+XCZ8QXxTRU5EX0ZBQ0lMSVRZfEF8QXwyMDE4MDEwMTAwMDAwMHx8VFlQRV5BfDIwMTgwMTAxMDAwMDAwfFR8MC4wfHx8QUF8fDAwfEFTQ0lJDUVWTnxBMDB8MjAxODAxMDEwNDAwMDANUElEfHwxNAExMTFeXl5eTVJOfDExMTExMTExXl5eXk1STn4xMTExMTExMTExXl5eXk9SR05NQlI=", "sendFacility": "SEND_FACILITY", "sendTime": "2018-01-01T00:00:00Z", "messageType": "TYPE", "createTime": "1970-01-01T00:00:00Z", "patientIds": [ { "value": "14\u0001111", "type": "MRN" }, { "value": "11111111", "type": "MRN" }, { "value": "1111111111", "type": "ORGNMBR" } ] }
Después de crear el mensaje, el adaptador de MLLP muestra una respuesta similar a la siguiente:
I0214 00:00:00.000000 1 healthapiclient.go:244] Started to fetch message from the Cloud Healthcare API HL7V2 Store I0214 00:00:00.000000 1 healthapiclient.go:283] Message was successfully fetched from the Cloud Healthcare API HL7V2 Store.
En la terminal en la que ejecutaste Netcat, se exhibe un resultado similar a la siguiente muestra. Este resultado indica que se publicó el mensaje:
connect to [127.0.0.1] from localhost [127.0.0.1] 39522 ^KMSH|^~\&|A|SEND_FACILITY|A|A|20180101000000||TYPE^A|20180101000000|T|0.0|||AA||00|ASCII^MEVN|A00|20180101040000^MPID||14^A111^^^^MRN|11111111^^^^MRN~1111111111^^^^ORGNMBR^\
Esto corresponde al valor en el campo
data
de la respuesta que recibiste cuando creaste el mensaje. Es igual que el valordata
en el archivohl7v2-sample.json
.Para ver el mensaje que el adaptador publicó en el tema de Pub/Sub, ejecuta el comando
gcloud pubsub subscriptions pull
en la segunda suscripción a Pub/Sub que creaste:gcloud pubsub subscriptions pull --auto-ack SECOND_SUBSCRIPTION
El comando muestra el siguiente resultado sobre el mensaje HL7v2 creado. Observa el valor
publish=true
en la columnaATTRIBUTES
, que indica que el mensaje se publicó en Pub/Sub:┌-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┐ | DATA | MESSAGE_ID | ATTRIBUTES | ├-----------------------------------------------------------------------------------------------------------------|-----------------|---------------| | projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/HL7V2_MESSAGE_ID | 123456789012345 | msgType=ADT | | | | publish=true | └-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┘
Publica mensajes en diferentes receptores externos
Puedes configurar el almacén HL7v2 con varios temas de Pub/Sub y usar filtros para enviar notificaciones a diferentes temas de Pub/Sub. Luego, puedes ejecutar un adaptador de MLLP para cada tema de Pub/Sub a fin de publicar los mensajes en un receptor externo diferente.
Si deseas configurar la tienda HL7v2 con varios temas de Pub/Sub y un filtro para cada tema, completa los siguientes pasos:
Crea dos temas de Pub/Sub y una suscripción para cada tema. Para obtener más información, consulta Crea un tema y una suscripción de Pub/Sub.
Ejecuta el siguiente comando:
curl
curl -X PATCH \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ --data "{ 'notificationConfigs': [ { 'pubsubTopic': 'projects/PROJECT_ID/topics/PUBSUB_TOPIC', 'filter' : 'sendFacility=\"SEND_FACILITY_1\"' }, { 'pubsubTopic': 'projects/PROJECT_ID/topics/SECOND_PUBSUB_TOPIC', 'filter': 'sendFacility=\"SEND_FACILITY_2\"' } ] }" "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID?updateMask=notificationConfigs"
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID", "notificationConfigs": [ { "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC", "filter": "sendFacility=\"SEND_FACILITY_1\"" }, { "pubsubTopic": "projects/PROJECT_ID/topics/SECOND_PUBSUB_TOPIC", "filter": "sendFacility=\"SEND_FACILITY_2\"" } ] }
PowerShell
$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-WebRequest ` -Method Patch ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -Body "{ 'notificationConfigs': [ { 'pubsubTopic' : 'projects/PROJECT_ID/topics/PUBSUB_TOPIC', 'filter': 'sendFacility=\"SEND_FACILITY_1\"' }, { 'pubsubTopic' : 'projects/PROJECT_ID/topics/SECOND_PUBSUB_TOPIC', 'filter' : 'sendFacility=\"SEND_FACILITY_2\"' } ] }" ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores?hl7V2StoreId=HL7V2_STORE_ID?updateMask=notificationConfigs" | Select-Object -Expand Content
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID", "notificationConfigs": [ { "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC", "filter": "sendFacility=\"SEND_FACILITY_1\"" }, { "pubsubTopic": "projects/PROJECT_ID/topics/SECOND_PUBSUB_TOPIC", "filter": "sendFacility=\"SEND_FACILITY_2\"" } ] }
Prueba el enrutamiento de mensajes
Para probar el enrutamiento de los mensajes, completa los pasos en las siguientes secciones.
Configura y, luego, inicia el primer receptor y adaptador
Para configurar y, luego, iniciar el primer receptor y adaptador, completa los siguientes pasos:
En la máquina donde extrajiste la imagen precompilada de Docker, ejecuta el siguiente comando para instalar Netcat:
sudo apt install netcat
Descarga
hl7v2-mllp-ack-sample.txt
, si aún no lo hiciste. El archivo contiene un mensajeACK
que el adaptador usa como respuesta cuando intenta publicar un mensaje.Para configurar el puerto 2525 del primer receptor, ejecuta el siguiente comando:
Linux
echo -n -e "\x0b$(cat hl7v2-mllp-ack-sample.txt)\x1c\x0d" | nc -q1 -lv -p 2525 | less
Cuando se inicia el proceso de Netcat, se muestra el siguiente resultado:
listening on [any] 2525 ...
Para iniciar el primer adaptador, ejecuta el siguiente comando en una terminal nueva:
docker run \ --network=host \ gcr.io/cloud-healthcare-containers/mllp-adapter \ /usr/mllp_adapter/mllp_adapter \ --hl7_v2_project_id=PROJECT_ID \ --hl7_v2_location_id=LOCATION \ --hl7_v2_dataset_id=DATASET_ID \ --hl7_v2_store_id=HL7V2_STORE_ID \ --export_stats=false \ --receiver_ip=127.0.0.1 --port 2575 \ --mllp_addr=127.0.0.1:2525 \ --pubsub_project_id=PROJECT_ID \ --pubsub_subscription=PUBSUB_SUBSCRIPTION \ --api_addr_prefix=https://healthcare.googleapis.com:443/v1 \ --logtostderr
Donde:
- PROJECT_ID es el ID del proyecto de Google Cloud que contiene tu almacén HL7v2.
- LOCATION es la región en la que se encuentra tu almacén HL7v2.
- DATASET_ID es el ID del conjunto de datos superior de tu almacén HL7v2.
- HL7V2_STORE_ID es el ID de la tienda HL7v2 al que envías mensajes HL7v2.
- PROJECT_ID es el ID del proyecto de Google Cloud que contiene el tema de Pub/Sub.
- PUBSUB_SUBSCRIPTION es el nombre de la primera suscripción que creaste y que está asociada a tu primer tema de Pub/Sub. El adaptador consume mensajes de esta suscripción y los reconoce de forma automática.
Después de ejecutar este comando, el adaptador comienza a ejecutarse en tu máquina local en 127.0.0.1:2575. Publica mensajes nuevos en el primer receptor externo en el puerto 2525.
Configura y, luego, inicia el segundo receptor y adaptador
Para configurar y, luego, iniciar el segundo receptor y adaptador, completa los siguientes pasos:
En la máquina donde extrajiste la imagen precompilada de Docker, ejecuta el siguiente comando para instalar Netcat:
sudo apt install netcat
Descarga
hl7v2-mllp-ack-sample.txt
, si aún no lo hiciste. El archivo contiene un mensajeACK
que el adaptador usa como respuesta cuando intenta publicar un mensaje.A fin de configurar el puerto 2526 para el segundo receptor, ejecuta el siguiente comando.
Linux
echo -n -e "\x0b$(cat hl7v2-mllp-ack-sample.txt)\x1c\x0d" | nc -q1 -lv -p 2526 | less
Cuando se inicia el proceso de Netcat, se muestra el siguiente resultado:
listening on [any] 2526 ...
Para iniciar el segundo adaptador, ejecuta el siguiente comando en una terminal nueva:
docker run \ --network=host \ gcr.io/cloud-healthcare-containers/mllp-adapter \ /usr/mllp_adapter/mllp_adapter \ --hl7_v2_project_id=PROJECT_ID \ --hl7_v2_location_id=LOCATION \ --hl7_v2_dataset_id=DATASET_ID \ --hl7_v2_store_id=HL7V2_STORE_ID \ --export_stats=false \ --receiver_ip=127.0.0.1 --port 2576 \ --mllp_addr=127.0.0.1:2526 \ --pubsub_project_id=PROJECT_ID \ --pubsub_subscription=SECOND_PUBSUB_SUBSCRIPTION \ --api_addr_prefix=https://healthcare.googleapis.com:443/v1 \ --logtostderr
Donde:
- PROJECT_ID es el ID del proyecto de Google Cloud que contiene tu almacén HL7v2.
- LOCATION es la región en la que se encuentra tu almacén HL7v2.
- DATASET_ID es el ID del conjunto de datos superior de tu almacén HL7v2.
- HL7V2_STORE_ID es el ID de la tienda HL7v2 al que envías mensajes HL7v2.
- PROJECT_ID es el ID del proyecto de Google Cloud que contiene el tema de Pub/Sub.
- SECOND_PUBSUB_SUBSCRIPTION es el nombre de la segunda suscripción que creaste y que está asociada a tu segundo tema de Pub/Sub. El adaptador consume mensajes de esta suscripción y los reconoce de forma automática.
Después de ejecutar este comando, el adaptador comienza a ejecutarse en tu máquina local en la dirección IP del puerto 127.0.0.1:2576. Publica mensajes nuevos en el segundo receptor externo en el puerto 2526.
Publica un mensaje en el primer receptor
Para crear un mensaje que solo se publicará en el primer receptor externo, completa los siguientes pasos:
Descargar
hl7v2-sample1.json
.En el directorio donde descargaste
hl7v2-sample1.json
, llama al métodomessages.create
para crear el mensaje en una tienda HL7v2:curl
Para crear un mensaje de HL7v2, realiza una solicitud
POST
y especifica la siguiente información:- El nombre del conjunto de datos superior
- El nombre del almacén de HL7v2
- Un mensaje
- Un token de acceso
En el siguiente ejemplo, se muestra una solicitud
POST
mediantecurl
y un archivo JSON de muestra,hl7v2-sample1.json
.curl -X POST \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ --data-binary @hl7v2-sample1.json \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages"
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID", "data": "TVNIfF5+XCZ8QXxTRU5EX0ZBQ0lMSVRZXzF8QXxBfDIwMTgwMTAxMDAwMDAwfHxUWVBFXkF8MjAxODAxMDEwMDAwMDB8VHwwLjB8fHxBQXx8MDB8QVNDSUkNRVZOfEEwMHwyMDE4MDEwMTA0MDAwMA1QSUR8fDE0ATExMV5eXl5NUk58MTExMTExMTFeXl5eTVJOfjExMTExMTExMTFeXl5eT1JHTk1CUg==", "sendFacility": "SEND_FACILITY_1", "sendTime": "2018-01-01T00:00:00Z", "messageType": "TYPE", "createTime": "1970-01-01T00:00:00Z", "patientIds": [ { "value": "14\u0001111", "type": "MRN" }, { "value": "11111111", "type": "MRN" }, { "value": "1111111111", "type": "ORGNMBR" } ] }
PowerShell
Para crear un mensaje de HL7v2, realiza una solicitud
POST
y especifica la siguiente información:- El nombre del conjunto de datos superior
- El nombre del almacén de HL7v2
- Un mensaje
- Un token de acceso
En el siguiente ejemplo, se muestra una solicitud
POST
mediante Windows PowerShell y un archivo JSON de muestra llamadohl7v2-sample1.json
.$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-WebRequest ` -Method Post ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -InFile hl7v2-sample1.json ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages" | Select-Object -Expand Content
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID", "data": "TVNIfF5+XCZ8QXxTRU5EX0ZBQ0lMSVRZXzF8QXxBfDIwMTgwMTAxMDAwMDAwfHxUWVBFXkF8MjAxODAxMDEwMDAwMDB8VHwwLjB8fHxBQXx8MDB8QVNDSUkNRVZOfEEwMHwyMDE4MDEwMTA0MDAwMA1QSUR8fDE0ATExMV5eXl5NUk58MTExMTExMTFeXl5eTVJOfjExMTExMTExMTFeXl5eT1JHTk1CUg==", "sendFacility": "SEND_FACILITY_1", "sendTime": "2018-01-01T00:00:00Z", "messageType": "TYPE", "createTime": "1970-01-01T00:00:00Z", "patientIds": [ { "value": "14\u0001111", "type": "MRN" }, { "value": "11111111", "type": "MRN" }, { "value": "1111111111", "type": "ORGNMBR" } ] }
En esta respuesta,
sendFacility
se configura comoSEND_FACILITY_1
, por lo tanto, la notificación de Pub/Sub solo se envía al primer tema de Pub/Sub. Después de crear el mensaje, el primer adaptador de MLLP muestra la siguiente respuesta:I0214 00:00:00.000000 1 healthapiclient.go:266] Started to fetch message. I0214 00:00:00.000000 1 healthapiclient.go:283] Message was successfully fetched.
El segundo adaptador de MLLP no muestra ninguna respuesta porque no se envía ninguna notificación al segundo tema de Pub/Sub.
En la terminal en la que ejecutaste el primer proceso de Netcat, se muestra el siguiente resultado. Este resultado indica que se publicó el mensaje.
connect to [127.0.0.1] from localhost [127.0.0.1] 39522 ^KMSH|^~\&|A|SEND_FACILITY_1|A|A|20180101000000||TYPE^A|20180101000000|T|0.0|||AA||00|ASCII^MEVN|A00|20180101040000^MPID||14^A111^^^^MRN|11111111^^^^MRN~1111111111^^^^ORGNMBR^\
Este resultado corresponde al valor en el campo
data
de la respuesta que recibiste cuando creaste el mensaje. Es igual que el valordata
en el archivohl7v2-sample1.json
.
Publica un mensaje en el segundo receptor
Para crear un mensaje que solo se publicará en el segundo receptor externo, completa los siguientes pasos:
Abre una terminal nueva en la máquina local.
Para crear un mensaje que solo se publicará en el segundo receptor externo, descarga
hl7v2-sample2.json
.En el directorio donde descargaste
hl7v2-sample2.json
, llama al métodomessages.create
para crear el mensaje en una tienda HL7v2:curl
Para crear un mensaje de HL7v2, realiza una solicitud
POST
y especifica la siguiente información:- El nombre del conjunto de datos superior
- El nombre del almacén de HL7v2
- Un mensaje
- Un token de acceso
En el siguiente ejemplo, se muestra una solicitud
POST
mediantecurl
y un archivo JSON de muestra,hl7v2-sample2.json
.curl -X POST \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ --data-binary @hl7v2-sample2.json \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages"
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID", "data": "TVNIfF5+XCZ8QXxTRU5EX0ZBQ0lMSVRZXzJ8QXxBfDIwMTgwMTAxMDAwMDAwfHxUWVBFXkF8MjAxODAxMDEwMDAwMDB8VHwwLjB8fHxBQXx8MDB8QVNDSUkNRVZOfEEwMHwyMDE4MDEwMTA0MDAwMA1QSUR8fDE0ATExMV5eXl5NUk58MTExMTExMTFeXl5eTVJOfjExMTExMTExMTFeXl5eT1JHTk1CUg==", "sendFacility": "SEND_FACILITY_2", "sendTime": "2018-01-01T00:00:00Z", "messageType": "TYPE", "createTime": "1970-01-01T00:00:00Z", "patientIds": [ { "value": "14\u0001111", "type": "MRN" }, { "value": "11111111", "type": "MRN" }, { "value": "1111111111", "type": "ORGNMBR" } ] }
PowerShell
Para crear un mensaje HL7v2, realiza una solicitud
POST
y especifica la siguiente información:- El nombre del conjunto de datos superior
- El nombre del almacén de HL7v2
- Un mensaje
- Un token de acceso
En el siguiente ejemplo, se muestra una solicitud
POST
mediante Windows PowerShell y un archivo JSON de muestra,hl7v2-sample2.json
.$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-WebRequest ` -Method Post ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -InFile hl7v2-sample2.json ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages" | Select-Object -Expand Content
Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID", "data": "TVNIfF5+XCZ8QXxTRU5EX0ZBQ0lMSVRZXzJ8QXxBfDIwMTgwMTAxMDAwMDAwfHxUWVBFXkF8MjAxODAxMDEwMDAwMDB8VHwwLjB8fHxBQXx8MDB8QVNDSUkNRVZOfEEwMHwyMDE4MDEwMTA0MDAwMA1QSUR8fDE0ATExMV5eXl5NUk58MTExMTExMTFeXl5eTVJOfjExMTExMTExMTFeXl5eT1JHTk1CUg==", "sendFacility": "SEND_FACILITY_2", "sendTime": "2018-01-01T00:00:00Z", "messageType": "TYPE", "createTime": "1970-01-01T00:00:00Z", "patientIds": [ { "value": "14\u0001111", "type": "MRN" }, { "value": "11111111", "type": "MRN" }, { "value": "1111111111", "type": "ORGNMBR" } ] }
Ten en cuenta que SendFacility es
SEND_FACILITY_2
, por lo tanto, la notificación de Pub/Sub solo se envía al segundo tema de Pub/Sub. Después de crear el mensaje, el primer adaptador de MLLP no muestra ninguna respuesta, mientras que el segundo adaptador de MLLP muestra la siguiente respuesta:I0214 00:00:00.000000 1 healthapiclient.go:266] Started to fetch message. I0214 00:00:00.000000 1 healthapiclient.go:283] Message was successfully fetched.
En la terminal en la que ejecutaste el segundo proceso de Netcat, se muestra el siguiente resultado. Este resultado indica que se publicó el mensaje.
connect to [127.0.0.1] from localhost [127.0.0.1] 39522 ^KMSH|^~\&|A|SEND_FACILITY_2|A|A|20180101000000||TYPE^A|20180101000000|T|0.0|||AA||00|ASCII^MEVN|A00|20180101040000^MPID||14^A111^^^^MRN|11111111^^^^MRN~1111111111^^^^ORGNMBR^\
Este resultado corresponde al valor en el campo
data
de la respuesta que recibiste cuando creaste el mensaje. Es igual que el valordata
en el archivohl7v2-sample2.json
.
Implementa el adaptador de MLLP en Google Kubernetes Engine
Cuando transmites mensajes HL7v2 a través de MLLP desde tu centro de atención, una configuración posible es enviar los mensajes a un adaptador que se implementa en Google Cloud y puede reenviarlos a la API de Cloud Healthcare.
El adaptador de MLLP se ejecuta como una aplicación sin estado en un clúster de GKE. Un clúster de GKE es un grupo administrado de instancias de VM para ejecutar aplicaciones en contenedores. Las aplicaciones sin estado son aplicaciones que no almacenan los datos ni el estado de la aplicación en el clúster o en almacenamiento continuo. En cambio, los datos y el estado de la aplicación se quedan con el cliente. Esto hace que las aplicaciones sin estado sean más escalables.
GKE usa Implementación para implementar aplicaciones sin estado como claves Pods: Los Deployments administran el estado deseado de tu aplicación: cuántos Pods deben ejecutar tu aplicación, qué versión de imagen del contenedor se debe ejecutar, cómo se deben etiquetar los Pods, etcétera. El estado deseado puede ser cambian de forma dinámica a través de actualizaciones en el historial Especificación del pod.
Al mismo tiempo que implementas el adaptador, creas un Servicio controlador que te permite conectar el adaptador a la API de Cloud Healthcare mediante el balanceo de cargas interno.
Si es la primera vez que usas GKE, deberías completar la guía de inicio rápido de GKE para aprender cómo funciona el producto.
Agrega permisos de la API de Pub/Sub a la cuenta de servicio de GKE
Como se indica en la documentación de GKE Autentica Cloud Platform con cuentas de servicio, cada nodo en un clúster de contenedores es una instancia de Compute Engine. Por lo tanto, cuando el adaptador de MLLP se ejecuta en un clúster de contenedor, hereda automáticamente los permisos de las instancias de Compute Engine en las que se implementa.
Google Cloud crea automáticamente una cuenta de servicio llamada “Cuenta de servicio predeterminada de Compute Engine” y GKE asocia esta cuenta de servicio con los nodos que crea GKE. Según cómo esté configurado tu proyecto, es posible que la cuenta de servicio predeterminada tenga o no permisos para usar otras API de Cloud Platform. GKE también asigna algunos permisos de acceso limitado a las instancias de Compute Engine.
Para obtener mejores resultados, no te autentiques en otros servicios de Google Cloud (como Pub/Sub) desde los Pods que se ejecutan en GKE mediante la actualización de los permisos de la cuenta de servicio predeterminada o la asignación de más permisos de acceso a instancias de Compute Engine. En su lugar, crea tus propias cuentas de servicio.
Debes otorgar los permisos de Pub/Sub necesarios al clúster del contenedor, pero también tienes la opción de otorgar permisos para escribir métricas en Cloud Monitoring.
Para crear una cuenta de servicio nueva que contenga solo los permisos que requiere el clúster del contenedor, completa los siguientes pasos:
Console
Crear una cuenta de servicio:
En la consola de Google Cloud, ve a la página Crear cuenta de servicio.
Selecciona un proyecto
Ingresa un nombre en el campo Nombre de cuenta de servicio. La consola de Google Cloud completa el campo ID de cuenta de servicio según este nombre.
Opcional: en el campo Descripción de la cuenta de servicio, ingresa una descripción.
Haga clic en Crear.
Haz clic en el campo Seleccionar una función.
En Todas las funciones, haz clic en Pub/Sub > Suscriptor de Pub/Sub.
Haz clic en Agregar otra función y, luego, en el campo Seleccionar una función.
En Todas las funciones, haz clic en Cloud Healthcare > Transferencia de mensajes de Healthcare HL7v2.
Si deseas habilitar Monitoring, haz clic en Agregar otra función y, luego, en el campo Seleccionar una función (opcional).
En Todas las funciones, haz clic en Monitoring > Escritor de métricas de Monitoring.
Haga clic en Continuar.
Haz clic en Listo para terminar de crear la cuenta de servicio.
No cierres la ventana del navegador. Usarás la ventana en el siguiente procedimiento.
gcloud
Para crear la cuenta de servicio, ejecuta el comando
gcloud iam service-accounts create
:gcloud iam service-accounts create SERVICE_ACCOUNT_NAME
El resultado es la cuenta de servicio:
Created service account SERVICE_ACCOUNT_NAME.
Para otorgar cada función a la cuenta de servicio, ejecuta el comando
gcloud projects add-iam-policy-binding
.gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \ --role=roles/pubsub.subscriber gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \ --role=roles/healthcare.hl7V2Ingest gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \ --role=roles/monitoring.metricWriter
En el resultado, se incluye la política actualizada:
bindings: - members: - user:SERVICE_ACCOUNT_NAME role: roles/pubsub.publisher - members: - user:SERVICE_ACCOUNT_NAME roles/healthcare.hl7V2Ingest - members: - user:SERVICE_ACCOUNT_NAME roles/monitoring.metricWriter etag: ETAG version: 1
Cómo crear el clúster
Para crear el clúster en GKE, ejecuta el comando gcloud container clusters create
:
gcloud container clusters create mllp-adapter \ --zone=COMPUTE_ZONE \ --service-account CLIENT_EMAIL
Donde:
- COMPUTE_ZONE es la zona en la que se implementa tu clúster. Una zona es una ubicación regional aproximada en la que residen tus clústeres y los respectivos recursos. Por ejemplo,
us-west1-a
es una zona en la regiónus-west
. Si estableciste una zona predeterminada congcloud config set compute/zone
, el valor de esta marca anula el valor predeterminado. - CLIENT_EMAIL es el identificador de la cuenta de servicio que deseas. usar. Usa el formato SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com.
El comando exhibe un resultado similar a la siguiente muestra:
Creating cluster mllp-adapter in COMPUTE_ZONE... Cluster is being configured... Cluster is being deployed... Cluster is being health-checked... Cluster is being health-checked (master is healthy)...done. Created [https://container.googleapis.com/v1/projects/PROJECT_ID/zones/COMPUTE_ZONE/clusters/mllp-adapter]. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/COMPUTE_ZONE/mllp-adapter?project=PROJECT_ID kubeconfig entry generated for mllp-adapter. NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS mllp-adapter COMPUTE_ZONE 1.11.7-gke.4 203.0.113.1 n1-standard-1 1.11.7-gke.4 3 RUNNING
Después de crear el clúster, GKE crea tres instancias de VM de Compute Engine. Para verificarlo, enumera las instancias con el siguiente comando:
gcloud compute instances list
Configura la implementación
Cuando implementas una aplicación en GKE, debes definir propiedades de la implementación mediante un archivo de manifiesto de implementación, que suele ser un archivo YAML. Para obtener una muestra, consulta Crea una implementación.
Abre otra terminal.
Mediante un editor de texto, crea un archivo de manifiesto de implementación llamado
mllp_adapter.yaml
con el siguiente contenido:
apiVersion: apps/v1 kind: Deployment metadata: name: mllp-adapter-deployment spec: replicas: 1 selector: matchLabels: app: mllp-adapter template: metadata: labels: app: mllp-adapter spec: containers: - name: mllp-adapter imagePullPolicy: Always image: gcr.io/cloud-healthcare-containers/mllp-adapter ports: - containerPort: 2575 protocol: TCP name: "port" command: - "/usr/mllp_adapter/mllp_adapter" - "--port=2575" - "--hl7_v2_project_id=PROJECT_ID" - "--hl7_v2_location_id=LOCATION" - "--hl7_v2_dataset_id=DATASET_ID" - "--hl7_v2_store_id=HL7V2_STORE_ID" - "--api_addr_prefix=https://healthcare.googleapis.com:443/v1" - "--logtostderr" - "--receiver_ip=0.0.0.0"
Donde:
- PROJECT_ID es el ID del proyecto de Google Cloud que contiene tu almacén HL7v2.
- LOCATION es la región en la que se encuentra tu almacén HL7v2.
- DATASET_ID es el ID del conjunto de datos superior de tu almacén HL7v2.
- HL7V2_STORE_ID es el ID de la tienda HL7v2 al que envías mensajes HL7v2.
La implementación tiene las siguientes propiedades:
spec: replicas:
es la cantidad de pods replicados que administra la implementación.spec: template: metadata: labels:
es la etiqueta asignada a cada pod, que la implementación usa para administrar los pods.spec: template: spec:
es la especificación de pod, que define cómo debe ejecutarse cada pod.spec: containers
incluye el nombre del contenedor que se ejecutará en cada pod y la imagen de contenedor que se debe ejecutar.
Para obtener más información sobre la especificación de implementación, consulta la referencia de la API de Deployment.
Configura el servicio
A fin de que el adaptador de MLLP sea accesible para las aplicaciones fuera del clúster (como un centro de atención), debes configurar un balanceador de cargas interno.
Si no configuraste una VPN, las aplicaciones pueden acceder al adaptador de MLLP a través del balanceador de cargas interno, siempre que las aplicaciones usen la misma red de VPC y se encuentren en la misma región de Google Cloud. Por ejemplo, a fin de que el adaptador sea accesible para una instancia de VM de Compute Engine en la misma región y en la misma red de VPC, puedes agregar un balanceador de cargas interno al recurso del servicio del clúster.
En el directorio en el que creaste el archivo de manifiesto de implementación, usa el editor de texto para crear un archivo de manifiesto de Service llamado mllp_adapter_service.yaml
con el siguiente contenido. Este archivo es responsable de configurar el balanceo de cargas interno:
apiVersion: v1
kind: Service
metadata:
name: mllp-adapter-service
annotations:
cloud.google.com/load-balancer-type: "Internal"
spec:
type: LoadBalancer
ports:
- name: port
port: 2575
targetPort: 2575
protocol: TCP
selector:
app: mllp-adapter
El Service tiene las siguientes propiedades:
metadata: name:
es el nombre que eliges para Service. En este caso, esmllp-adapter-service
.metadata: annotations:
es una anotación que especifica que se debe configurar un balanceador de cargas interno.spec: type:
es el tipo de balanceador de cargas.ports: port:
se usa para especificar el puerto en el que Service puede recibir tráfico de otros servicios en el mismo clúster. Se usa el puerto de MLLP predeterminado de2575
.ports: targetPort:
se usa para especificar el puerto en cada Pod en el que se ejecuta el servicio.spec: selector: app:
especifica los Pods a los que se orienta el Service.
Si bien es posible especificar una dirección IP para el balanceador de cargas (con el campo clusterIP
), el balanceador de cargas puede generar su propia dirección IP a la que puedes enviar mensajes. Por ahora, permite que el clúster genere la dirección IP, que usarás más adelante en este instructivo.
Para obtener más información sobre el balanceo de cargas interno, consulta la documentación de GKE.
Para obtener más información sobre la especificación del servicio, consulta la referencia de la API de servicio.
Implementa la implementación
Para implementar el adaptador en un clúster de GKE, ejecuta el siguiente comando en el directorio que contiene el archivo de manifiesto de implementación mllp_adapter.yaml
:
kubectl apply -f mllp_adapter.yaml
El comando muestra el siguiente resultado:
deployment.extensions "mllp-adapter-deployment" created
Inspecciona la implementación
Después de crear la implementación, puedes usar la herramienta de kubectl
para inspeccionarla.
Para obtener información detallada sobre la implementación, ejecuta el siguiente comando:
kubectl describe deployment mllp-adapter
Para enumerar el Pod creado por la implementación, ejecuta el siguiente comando:
kubectl get pods -l app=mllp-adapter
Para obtener información sobre el Pod creado, sigue estos pasos:
kubectl describe pod POD_NAME
Si la implementación se realizó de forma correcta, la última parte del resultado del comando anterior debería contener la siguiente información:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 1m default-scheduler Successfully assigned default/mllp-adapter-deployment-85b46f8-zxw68 to gke-mllp-adapter-default-pool-9c42852d-95sn
Normal Pulling 1m kubelet, gke-mllp-adapter-default-pool-9c42852d-95sn pulling image "gcr.io/cloud-healthcare-containers/mllp-adapter"
Normal Pulled 1m kubelet, gke-mllp-adapter-default-pool-9c42852d-95sn Successfully pulled image "gcr.io/cloud-healthcare-containers/mllp-adapter"
Normal Created 1m kubelet, gke-mllp-adapter-default-pool-9c42852d-95sn Created container
Normal Started 1m kubelet, gke-mllp-adapter-default-pool-9c42852d-95sn Started container
Implementa el servicio y crea el balanceador de cargas interno
Para crear el balanceador de cargas interno, en el directorio que contiene el archivo de manifiesto del Service mllp_adapter_service.yaml
, ejecuta el siguiente comando:
kubectl apply -f mllp_adapter_service.yaml
El comando muestra el siguiente resultado:
service "mllp-adapter-service" created
Inspecciona el servicio
Después de crear el servicio, inspecciónalo para verificar que se haya configurado correctamente.
Para inspeccionar el balanceador de cargas interno, ejecuta el siguiente comando:
kubectl describe service mllp-adapter-service
El resultado del comando es similar al siguiente ejemplo:
Name: mllp-adapter-service
Namespace: default
Labels: <none>
Annotations: cloud.google.com/load-balancer-type=Internal
kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"cloud.google.com/load-balancer-type":"Internal"},"name":"mllp-adapter-service","namespa...
Selector: app=mllp-adapter
Type: LoadBalancer
IP: 203.0.113.1
LoadBalancer Ingress: 203.0.113.1
Port: port 2575/TCP
TargetPort: 2575/TCP
NodePort: port 30660/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal EnsuringLoadBalancer 1m service-controller Ensuring load balancer
Normal EnsuredLoadBalancer 1m service-controller Ensured load balancer
La dirección IP de LoadBalancer Ingress
puede tardar hasta un minuto en propagarse. Usarás esta dirección IP y el puerto 2575
para acceder al Service desde fuera del clúster en el paso siguiente.
Crea una VM de Compute Engine y envía mensajes
Más adelante en este instructivo, probaste el adaptador de MLLP de manera local y enviaste mensajes HL7v2 a tu almacén HL7v2, ahora enviarás mensajes desde una VM de Compute Engine al adaptador de AAML que se ejecuta en GKE. Luego, los mensajes se reenvían a un almacén HL7v2.
Para enviar solicitudes de la instancia nueva al clúster de GKE, la instancia y las instancias existentes deben estar en la misma región y usar la misma red de VPC.
Al final de esta sección, enumerarás las notificaciones publicadas en tu tema de Pub/Sub y los mensajes HL7v2 en tu almacén HL7v2. La instancia de VM de Compute Engine debe tener permisos para realizar estas tareas. Antes de crear la instancia, crea una cuenta de servicio nueva con los permisos necesarios; para ello, completa los pasos siguientes:
Console
Crear una cuenta de servicio:
En la consola de Google Cloud, ve a la página Crear cuenta de servicio.
Selecciona un proyecto
Ingresa un nombre en el campo Nombre de cuenta de servicio. La consola de Google Cloud completa el campo ID de cuenta de servicio según este nombre.
Opcional: en el campo Descripción de la cuenta de servicio, ingresa una descripción.
Haga clic en Crear.
Haz clic en el campo Seleccionar una función.
En Todas las funciones, haz clic en Pub/Sub > Suscriptor de Pub/Sub.
Haz clic en Agregar otra función y, luego, en el campo Seleccionar una función.
En Todas las funciones, haz clic en Cloud Healthcare > Consumidor de mensajes HL7v2 de Healthcare.
Haga clic en Continuar.
Haz clic en Listo para terminar de crear la cuenta de servicio.
No cierres la ventana del navegador. Usarás la ventana en el siguiente procedimiento.
gcloud
Para crear la cuenta de servicio, ejecuta el comando
gcloud iam service-accounts create
:gcloud iam service-accounts create SERVICE_ACCOUNT_NAME
El resultado es la cuenta de servicio:
Created service account SERVICE_ACCOUNT_NAME.
Para otorgar cada función a la cuenta de servicio, ejecuta el comando
gcloud projects add-iam-policy-binding
.gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \ --role=roles/pubsub.publisher gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \ --role=roles/healthcare.hl7V2Consumer
En el resultado, se incluye la política actualizada:
bindings: - members: - user:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com role: roles/pubsub.publisher - members: - user:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com roles/healthcare.hl7V2Consumer etag: ETAG version: 1
En los siguientes pasos, se muestra cómo crear una instancia de máquina virtual de Linux en Compute Engine:
Consola
En la consola de Google Cloud, ve a la página Instancias de VM.
Haga clic en Crear instancia.
Elige una región y una zona para la instancia que coincide con la zona que seleccionaste cuando creaste el clúster. Por ejemplo, si usaste
us-central1-a
para COMPUTE_ZONE cuando creaste el clúster, en la pantalla de creación de la instancia, seleccionaus-central1 (Iowa)
para la región yus-central1-a
para la zona.En la sección Disco de arranque, haz clic en Cambiar para configurar el disco de arranque.
En la pestaña Imágenes públicas, elige la versión 9 del sistema operativo Debian.
Haga clic en Seleccionar.
En la sección Identidad y acceso a la API, selecciona la cuenta de servicio que creaste.
En la sección Firewall, selecciona Permitir el tráfico HTTP.
Haga clic en Crear para crear la instancia.
gcloud
Para crear una instancia de procesamiento, ejecuta el método gcloud compute instances create
con las siguientes opciones:
- La ZONE que seleccionaste cuando creaste el clúster
- La etiqueta
http-server
para permitir el tráfico HTTP - El SERVICE_ACCOUNT que creaste
gcloud compute instances create COMPUTE_NAME \ --project=PROJECT_ID \ --zone=ZONE \ --image-family=debian-10 \ --image-project=debian-cloud \ --tags=http-server \ --service-account=SERVICE_ACCOUNT
El resultado es similar al siguiente ejemplo:
Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/COMPUTE_NAME]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS COMPUTE_NAME ZONE n1-standard-1 INTERNAL_IP EXTERNAL_IP RUNNING
La instancia tardará unos momentos en iniciarse. Una vez que se inicia la instancia, se mostrará en la página Instancias de VM con un ícono de estado verde.
De forma predeterminada, la instancia usa la misma red de VPC predeterminada que usa el clúster, lo que significa que el tráfico se puede enviar desde la instancia al clúster.
Para conectarte a la instancia, completa los siguientes pasos:
Consola
En la consola de Google Cloud, ve a la página Instancias de VM.
En la lista de instancias de máquina virtual, haz clic en SSH en la fila de la instancia que creaste.
gcloud
Para conectarte a la instancia, ejecuta el comando gcloud compute ssh
:
gcloud compute ssh INSTANCE_NAME \ --project PROJECT_ID \ --zone ZONE
Ahora tienes una ventana de la terminal para interactuar con tu instancia de Linux.
En la ventana de la terminal, instala Netcat:
sudo apt install netcat
Descarga el archivo
hl7v2-mllp-sample.txt
y guárdalo en la instancia. Para obtener información sobre la codificación y los terminadores de segmentos que se usan en el archivo, consulta Codificación y separadores de segmentos de los mensajes HL7v2.Para comenzar a enviar mensajes HL7v2 a través del adaptador de MLLP a tu almacén de HL7v2, en el directorio donde descargaste el archivo, ejecuta el siguiente comando. Usa el valor de
LoadBalancer Ingress
que se mostró cuando inspeccionaste el Service.echo -n -e "\x0b$(cat hl7v2-mllp-sample.txt)\x1c\x0d" | nc LOAD_BALANCER_INGRESS_IP_ADDRESS 2575
Después de ejecutar el comando, el mensaje se envía a través del adaptador de MLLP a tu almacén de HL7v2. Si el mensaje se transfirió correctamente al almacén de HL7v2, el comando mostrará el siguiente resultado:
MSA|AA|20150503223000|ILITY|FROM_APP|FROM_FACILITY|20190312162410||ACK|f4c59243-19c2-4373-bea0-39c1b2ba616b|P|2.5
Este resultado indica que la tienda HL7v2 respondió con un tipo de respuesta
AA
(Application Accept
), lo que significa que el mensaje se valida y se transfiere correctamente.Para ver el mensaje publicado en el tema de Pub/Sub, ejecuta el comando
gcloud pubsub subscriptions pull
:gcloud pubsub subscriptions pull --auto-ack PUBSUB_SUBSCRIPTION
El comando muestra el siguiente resultado sobre el mensaje HL7v2 transferido:
┌-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┐ | DATA | MESSAGE_ID | ATTRIBUTES | ├-----------------------------------------------------------------------------------------------------------------|-----------------|---------------| | projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/HL7V2_MESSAGE_ID | 123456789012345 | msgType=ADT | └-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┘
También puedes enumerar los mensajes en tu almacén HL7v2 para ver si el mensaje se agregó:
curl
curl -X GET \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages"
Si la solicitud es exitosa, el servidor muestra el ID del mensaje en una ruta del recurso:
{ "hl7V2Messages": [ { "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID" } ] }
PowerShell
$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-WebRequest ` -Method Get ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages" | Select-Object -Expand Content
Si la solicitud es exitosa, el servidor muestra el ID del mensaje en una ruta del recurso:
{ "hl7V2Messages": [ { "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID" } ] }
Después de completar esta sección, implementaste correctamente el adaptador de MLLP en GKE y enviaste un mensaje HL7v2 desde una instancia remota a través del adaptador y la API de Cloud Healthcare.
En el resto de este instructivo, aprenderás a encriptar de manera segura los mensajes HL7v2 transmitidos mediante la configuración de una VPN entre una instancia de Compute Engine, que actúa como una instancia “local” y el adaptador.
Configura una VPN
Utilizar una VPN te permite extender la red privada a la que envías mensajes HL7v2 a través de una red pública, como Internet. Mediante una VPN, puedes enviar mensajes desde el centro de atención con el adaptador de MLLP y Google Cloud. Los sistemas en este flujo actúan como si estuvieran en una sola red privada.
Hay dos métodos para proteger tu conexión MLLP mediante VPN:
- Usa Cloud VPN
- Usar la solución de VPN de extremo a extremo Strongswan en Docker
Configura Cloud VPN
Cloud VPN conecta de forma segura tu red local a tu red de nube privada virtual (VPC) de Google Cloud a través de una conexión de VPN IPsec. Una puerta de enlace VPN encripta el tráfico que viaja entre las dos redes; luego, la otra puerta de enlace VPN lo desencripta. Esto protege tus datos mientras viajan por Internet o a través de una red de centros de atención.
En este instructivo, cada puerta de enlace VPN que configuras se encuentra en una red y subred personalizadas diferentes en una región de Google Cloud diferente.
La puerta de enlace VPN configurada en us-central1
actúa como la puerta de enlace de Cloud VPN en el lado de Google Cloud, mientras que la puerta de enlace de Cloud VPN en europe-west1
simula tu puerta de enlace “local”.
Referencia de nombres y direcciones
Como referencia, este instructivo usa los siguientes nombres y direcciones IP:
Lado de Google Cloud
- Nombre de la red:
cloud-vpn-network
- Nombre de la subred:
subnet-us-central-10-0-1
- Región:
us-central1
- Rango de subred:
10.0.1.0/24
- Nombre de dirección IP externa:
cloud-vpn-ip
- Nombre de puerta de enlace de VPN:
vpn-us-central
- Nombre de túnel VPN:
vpn-us-central-tunnel-1
Lado "local"
- Nombre de la red:
on-prem-vpn-network
- Nombre de la subred:
subnet-europe-west-10-0-2
- Región:
europe-west1
- Rango de subred:
10.0.2.0/24
- Nombre de dirección IP externa:
on-prem-vpn-ip
- Nombre de puerta de enlace de VPN:
vpn-europe-west
- Nombre de túnel VPN:
vpn-europe-west-tunnel-1
Crea redes y subredes de VPC personalizadas
El primer paso para configurar Cloud VPN es crear dos redes de VPC. Una red, llamada on-prem-vpn-network
, se configura en el entorno “local” y se ejecuta en una instancia de VM de Compute Engine llamada on-prem-instance
. La otra red, llamada cloud-vpn-network
, es la que usa el clúster de GKE que ejecuta el adaptador de MLLP. Te conectarás a la VM on-prem-instance
y enviarás mensajes HL7v2 al adaptador de MLLP que se ejecuta en la red cloud-vpn-network
a través del balanceador de cargas interno del adaptador de MLLP.
Crea dos redes de VPC personalizadas y sus subredes; para ello, completa los siguientes pasos:
Para crear la primera red de VPC,
cloud-vpn-network
, ejecuta el siguiente comando:gcloud compute networks create cloud-vpn-network \ --project=PROJECT_ID \ --subnet-mode=custom
Para crear la subred
subnet-us-central-10-0-1
en la redcloud-vpn-network
, ejecuta el siguiente comando:gcloud compute networks subnets create subnet-us-central-10-0-1 \ --project=PROJECT_ID \ --region=us-central1 \ --network=cloud-vpn-network \ --range=10.0.1.0/24
Para crear la red de VPC
on-prem-vpn-network
, ejecuta el siguiente comando:gcloud compute networks create on-prem-vpn-network \ --project=PROJECT_ID \ --subnet-mode=custom
Para crear la subred
subnet-europe-west-10-0-2
en la red de VPCon-prem-vpn-network
, ejecuta el siguiente comando:gcloud compute networks subnets create subnet-europe-west-10-0-2 \ --project=PROJECT_ID \ --region=europe-west1 \ --network=on-prem-vpn-network \ --range=10.0.2.0/24
Crea una dirección IP externa
Antes de crear las puertas de enlace VPN, sigue estos pasos para reservar una dirección IP externa:
A fin de reservar una dirección IP externa regional (estática) para la dirección
cloud-vpn-ip
, ejecuta el siguiente comando:gcloud compute addresses create cloud-vpn-ip \ --project=PROJECT_ID \ --region=us-central1
A fin de reservar una dirección IP externa regional (estática) para la dirección
on-prem-vpn-ip
, ejecuta el siguiente comando:gcloud compute addresses create on-prem-vpn-ip \ --project=PROJECT_ID \ --region=europe-west1
Toma nota de estas direcciones IP externas a fin de que puedas usarlas para configurar las puertas de enlace de VPN en la siguiente sección. Para recuperar las direcciones IP externas, ejecuta el siguiente comando:
Dirección IP de Cloud VPN:
gcloud compute addresses describe cloud-vpn-ip \ --project PROJECT_ID \ --region us-central1 \ --format='flattened(address)'
Dirección IP de VPN “local”:
gcloud compute addresses describe on-prem-vpn-ip \ --project PROJECT_ID \ --region europe-west1 \ --format='flattened(address)'
Los comandos muestran un resultado similar al siguiente:
address: 203.0.113.1
Crea túneles, rutas y puertas de enlace VPN
Completa los siguientes pasos a fin de crear la puerta de enlace, el túnel y la ruta de VPN para Cloud VPN:
Crea una clave precompartida criptográficamente segura (secreto compartido) mediante las instrucciones que se proporcionan en Genera una clave precompartida segura. En esta sección, se hace referencia a esta clave como SHARED_SECRET.
Para crear el objeto puerta de enlace VPN de destino, ejecuta el siguiente comando:
gcloud compute target-vpn-gateways create vpn-us-central \ --project PROJECT_ID \ --region us-central1 \ --network cloud-vpn-network
Para crear tres reglas de reenvío, ejecuta los siguientes comandos y reemplaza la variable CLOUD_VPN_EXTERNAL_ADDRESS por el valor de la dirección IP de Cloud VPN en la sección anterior:
Envía tráfico de ESP (IPsec) a la puerta de enlace:
gcloud compute forwarding-rules create vpn-us-central-rule-esp \ --project PROJECT_ID \ --region us-central1 \ --address CLOUD_VPN_EXTERNAL_ADDRESS \ --ip-protocol ESP \ --target-vpn-gateway vpn-us-central
Envía tráfico UDP 500 a la puerta de enlace:
gcloud compute forwarding-rules create vpn-us-central-rule-udp500 \ --project PROJECT_ID \ --region us-central1 \ --address CLOUD_VPN_EXTERNAL_ADDRESS \ --ip-protocol UDP \ --ports 500 \ --target-vpn-gateway vpn-us-central
Envía tráfico UDP 4,500 a la puerta de enlace:
gcloud compute forwarding-rules create vpn-us-central-rule-udp4500 \ --project PROJECT_ID \ --region us-central1 \ --address CLOUD_VPN_EXTERNAL_ADDRESS \ --ip-protocol UDP \ --ports 4500 \ --target-vpn-gateway vpn-us-central
Para crear un túnel en la puerta de enlace de Cloud VPN, ejecuta el siguiente comando. Reemplaza ON_PREM_VPN_IP por el valor de la dirección IP de VPN “local” de la sección anterior.
gcloud compute vpn-tunnels create vpn-us-central-tunnel-1 \ --project PROJECT_ID \ --region us-central1 \ --peer-address ON_PREM_VPN_IP \ --shared-secret SHARED_SECRET \ --ike-version 2 \ --local-traffic-selector 0.0.0.0/0 \ --target-vpn-gateway vpn-us-central
A fin de crear una ruta estática para
10.0.2.0/24
, ejecuta el siguiente comando:gcloud compute routes create "vpn-us-central-tunnel-1-route-1" \ --project PROJECT_ID \ --network "cloud-vpn-network" \ --next-hop-vpn-tunnel "vpn-us-central-tunnel-1" \ --next-hop-vpn-tunnel-region "us-central1" \ --destination-range "10.0.2.0/24"
Completa los siguientes pasos a fin de crear la puerta de enlace VPN, el túnel y la ruta para la VPN “local”:
Para crear el objeto puerta de enlace VPN de destino, ejecuta el siguiente comando:
gcloud compute target-vpn-gateways create "vpn-europe-west" \ --project PROJECT_ID \ --region "europe-west1" \ --network "on-prem-vpn-network"
Para crear tres reglas de reenvío, ejecuta los siguientes comandos y reemplaza la variable ON_PREMISES_VPN_EXTERNAL_ADDRESS por el valor de la dirección IP VPN “local” de la sección anterior:
Envía tráfico de ESP (IPsec) a la puerta de enlace:
gcloud compute forwarding-rules create vpn-europe-west-rule-esp \ --project PROJECT_ID \ --region europe-west1 \ --address ON_PREMISES_VPN_EXTERNAL_ADDRESS \ --ip-protocol ESP \ --target-vpn-gateway vpn-europe-west
Envía tráfico UDP 500 a la puerta de enlace:
gcloud compute forwarding-rules create vpn-europe-west-rule-udp500 \ --project PROJECT_ID \ --region europe-west1 \ --address ON_PREMISES_VPN_EXTERNAL_ADDRESS \ --ip-protocol UDP \ --ports 500 \ --target-vpn-gateway vpn-europe-west
Envía tráfico UDP 4,500 a la puerta de enlace:
gcloud compute forwarding-rules create vpn-europe-west-rule-udp4500 \ --project PROJECT_ID \ --region europe-west1 \ --address ON_PREMISES_VPN_EXTERNAL_ADDRESS \ --ip-protocol UDP \ --ports 4500 \ --target-vpn-gateway vpn-europe-west
Para crear un túnel en la puerta de enlace “local”, ejecuta el siguiente comando:
gcloud compute vpn-tunnels create vpn-europe-west-tunnel-1 \ --project PROJECT_ID \ --region europe-west1 \ --peer-address CLOUD_VPN_IP \ --shared-secret SHARED_SECRET \ --ike-version 2 \ --local-traffic-selector 0.0.0.0/0 \ --target-vpn-gateway vpn-europe-west
A fin de crear una ruta estática para
10.0.1.0/24
, ejecuta el siguiente comando:gcloud compute routes create "vpn-europe-west-tunnel-1-route-1" \ --project PROJECT_ID \ --network "on-prem-vpn-network" \ --next-hop-vpn-tunnel "vpn-europe-west-tunnel-1" \ --next-hop-vpn-tunnel-region "europe-west1" \ --destination-range "10.0.1.0/24"
Has creado las puertas de enlace de Cloud VPN y las puertas de enlace "locales", y, también, iniciaste sus túneles. Las puertas de enlace de VPN no se conectarán hasta que hayas creado reglas de firewall para permitir el tráfico a través del túnel entre ellas.
Crea reglas de firewall
Debes crear reglas de firewall para ambos lados del túnel VPN. Estas reglas permiten que todo el tráfico de TCP, ICMP y UDP ingrese desde la subred en un lado del túnel VPN hasta el otro.
Para crear las reglas de firewall de la subred de Cloud VPN, ejecuta el siguiente comando:
gcloud compute firewall-rules create allow-tcp-udp-icmp-cloud-vpn \ --project=PROJECT_ID \ --direction=INGRESS \ --priority=1000 \ --network=cloud-vpn-network \ --action=ALLOW \ --rules=tcp,udp,icmp \ --source-ranges=10.0.2.0/24
Para crear las reglas de firewall de la subred “local”, ejecuta el siguiente comando:
gcloud compute firewall-rules create allow-tcp-udp-icmp-on-prem-vpn \ --project=PROJECT_ID \ --direction=INGRESS \ --priority=1000 \ --network=on-prem-vpn-network \ --action=ALLOW \ --rules=tcp,udp,icmp \ --source-ranges=10.0.1.0/24
Crea una regla de firewall que te permita establecer una conexión SSH a la instancia de VM en el puerto 22 mediante la ejecución del siguiente comando:
gcloud compute firewall-rules create on-prem-vpn-allow-ssh \ --project=PROJECT_ID \ --direction=INGRESS \ --priority=1000 \ --network=on-prem-vpn-network \ --action=ALLOW \ --rules=tcp:22 \ --source-ranges=0.0.0.0/0
Verifica el estado del túnel VPN
Para verificar que tu túnel esté activado, completa los siguientes pasos:
Ve a la página VPN en la consola de Google Cloud.
Haz clic en la pestaña Túneles de VPN de Google.
En el campo Estado de cada túnel, busca una marca de verificación verde y la palabra “Establecido”. Si estos elementos están allí, tus puertas de enlace han negociado un túnel. Si no aparece una marca después de unos minutos, consulta Solución de problemas.
Para obtener información de registro adicional relacionada con tus túneles VPN, consulta Comprobación de registros VPN en la página Solución de problemas. Por ejemplo, puedes ver las métricas sobre los paquetes descartados, el estado del túnel, los bytes recibidos y los bytes enviados.
Ahora que configuraste Cloud VPN correctamente con las puertas de enlace, los túneles y las reglas de firewall necesarias, puedes crear una conexión segura entre la instancia de VM “local” y el adaptador de MLLP que se ejecuta en GKE.
Combina la implementación en GKE y Cloud VPN
Antes en este instructivo probaste el adaptador de MLLP de forma local y enviaste mensajes HL7v2 a través de una conexión que no es de VPN al adaptador de MLLP, ahora enviarás mensajes desde una VM de Compute Engine a través de una conexión segura mediante Cloud VPN al adaptador MLLP que se ejecuta en GKE. Luego, los mensajes se reenvían a un almacén HL7v2.
Vuelve a crear la implementación
Primero, vuelve a crear la implementación en GKE para que el clúster use los parámetros que configuraste en Configuración de Cloud VPN:
Para borrar el clúster
mllp-adapter
que creaste, ejecuta el comandogcloud container clusters delete
. Ingresa el valor COMPUTE_ZONE que usaste cuando creaste el clúster.gcloud container clusters delete mllp-adapter --zone=COMPUTE_ZONE
Sigue los pasos en Implementa el adaptador de MLLP en Kubernetes Engine, pero cuando crees el clúster en GKE, agrega la red
cloud-vpn-network
y la subredsubnet-us-central-10-0-1
que creaste en Crea redes y subredes VPN personalizadas.Asegúrate de que el comando de creación del clúster se vea de la siguiente manera:
gcloud container clusters create mllp-adapter \ --zone=COMPUTE_ZONE \ --service-account=CLIENT_EMAIL \ --network=cloud-vpn-network \ --subnetwork=subnet-us-central-10-0-1
Donde:
COMPUTE_ZONE es la zona en la que se implementa tu clúster. Cuando configuraste Cloud VPN en la sección anterior, configuraste la red “del lado de Google Cloud” para usar
us-central1
. En la red del “lado de Google Cloud”, se ejecuta el clúster de GKE. Usa cualquiera de las siguientes zonas enus-central1
:us-central1-c
,us-central1-a
,us-central1-f
,us-central1-b
.CLIENT_EMAIL es el identificador de la cuenta de servicio que deseas. usar. Usa el formato SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com.
Crea una nueva VM de Compute Engine con la configuración de red
En los siguientes pasos, se muestra cómo crear una instancia de máquina virtual de Linux en Compute Engine con la consola de Google Cloud. A diferencia de la VM de Compute Engine que creaste, esta VM usa la configuración de red “del lado local” para comunicarse con el clúster de GKE a través de una VPN.
Consola
En la consola de Google Cloud, ve a la página Instancias de VM.
Haga clic en Crear instancia.
Elige un Región y Zona para la instancia que coincide con la configuración de red del “lado local”:
europe-west1 (Belgium)
para la Región yeurope-west1-b
la Zona.En la sección Boot disk, haga clic en Change para configurar el disco de arranque.
En la pestaña Imágenes públicas, elige la versión 9 del sistema operativo Debian.
Haga clic en Seleccionar.
En la sección Identidad y acceso a la API, selecciona la cuenta de servicio que creaste.
En la sección Firewall, selecciona Permitir el tráfico HTTP.
Expande la sección Administración, seguridad, discos, redes, instancia única.
En Interfaces de red en la pestaña Herramientas de redes, especifica los detalles de red para la configuración de red “del lado local”:
- En el campo Red, selecciona on-prem-vpn-network.
- En el campo Subred, seleccione subnet-europe-west-10-0-2 (10.0.2.0/24).
Haga clic en Crear para crear la instancia.
La instancia tardará unos momentos en iniciarse. Cuando esté lista, aparecerá en la página de instancias de VM con un ícono de estado verde.
gcloud
Para crear una instancia de procesamiento, ejecuta el método gcloud compute instances create
con las siguientes opciones:
- El ZONE que coincide con la configuración de red “del lado local”:
europe-west1-b
para la Zona. - Permite el tráfico HTTP mediante la especificación de la etiqueta
http-server
- El SERVICE_ACCOUNT que creaste
gcloud compute instances create COMPUTE_NAME \ --project=PROJECT_ID --zone=ZONE --image-family=debian-10 \ --tags=http-server,https-server --service-account=SERVICE_ACCOUNT
El resultado es similar al siguiente ejemplo:
Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/COMPUTE_NAME]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS COMPUTE_NAME ZONE n1-standard-1 INTERNAL_IP EXTERNAL_IP RUNNING
Para conectarte a la instancia, completa los siguientes pasos:
Consola
En la consola de Google Cloud, ve a la página Instancias de VM.
En la lista de instancias de máquina virtual, haz clic en SSH en la fila de la instancia que creaste.
gcloud
Para conectarte a la instancia, ejecuta el comando gcloud compute ssh
:
gcloud compute ssh INSTANCE_NAME \ --project PROJECT_ID \ --zone ZONE
Ahora tienes una ventana de la terminal para interactuar con tu instancia de Linux.
En la ventana de la terminal, instala Netcat:
sudo apt install netcat
Descarga el archivo
hl7v2-mllp-sample.txt
y guárdalo en la instancia.Para comenzar a enviar mensajes HL7v2 a través del adaptador de MLLP a tu almacén de HL7v2, en el directorio donde descargaste el archivo, ejecuta el siguiente comando. Usa el valor de
LoadBalancer Ingress
que se mostró cuando inspeccionaste el Service.echo -n -e "\x0b$(cat hl7v2-mllp-sample.txt)\x1c\x0d" | nc LOAD_BALANCER_INGRESS_IP_ADDRESS 2575
Después de ejecutar el comando, el mensaje se envía a través del adaptador de MLLP a tu almacén de HL7v2. Si el mensaje se transfirió correctamente al almacén de HL7v2, el comando mostrará el siguiente resultado:
MSA|AA|20150503223000|ILITY|FROM_APP|FROM_FACILITY|20190312162410||ACK|f4c59243-19c2-4373-bea0-39c1b2ba616b|P|2.5
Este resultado indica que la tienda HL7v2 respondió con un tipo de respuesta
AA
(Application Accept
), lo que significa que el mensaje se valida y se transfiere correctamente.Para ver el mensaje publicado en el tema de Pub/Sub, ejecuta el comando
gcloud pubsub subscriptions pull
:gcloud pubsub subscriptions pull --auto-ack PUBSUB_SUBSCRIPTION
El comando muestra el siguiente resultado sobre el mensaje HL7v2 transferido:
┌-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┐ | DATA | MESSAGE_ID | ATTRIBUTES | ├-----------------------------------------------------------------------------------------------------------------|-----------------|---------------| | projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/HL7V2_MESSAGE_ID | 123456789012345 | msgType=ADT | └-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┘
También puedes enumerar los mensajes en tu almacén HL7v2 para ver si el mensaje se agregó:
curl
curl -X GET \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages"
Si la solicitud es exitosa, el servidor muestra el ID del mensaje en una ruta del recurso:
{ "hl7V2Messages": [ { "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID" } ] }
PowerShell
$cred = gcloud auth application-default print-access-token $headers = @{ Authorization = "Bearer $cred" } Invoke-WebRequest ` -Method Get ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages" | Select-Object -Expand Content
Si la solicitud es exitosa, el servidor muestra el ID del mensaje en una ruta de recursos:
{ "hl7V2Messages": [ { "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID" } ] }
Después de completar esta sección, implementaste correctamente el adaptador de MLLP en GKE y, mediante una VPN, enviaste de forma segura un mensaje HL7v2 desde una instancia “local” a través del adaptador y a la API de Cloud Healthcare.
Limpia
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos utilizados en este instructivo, puedes limpiar los recursos que creaste en Google Cloud.
Borra el proyecto
Sigue los pasos que figuran a continuación para borrar el proyecto que creaste en este instructivo:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Soluciona problemas
Fallas del adaptador
Después de implementar el adaptador de MLLP en GKE, el adaptador encuentra una falla.
- Sigue los pasos en Soluciona problemas con cargas de trabajo implementadas.
Error Connection refused
cuando se ejecuta de manera local
Cuando pruebas el adaptador de MLLP de forma local, experimentas un error Connection refused
.
Este error se produce con algunos usuarios de macOS. En lugar de usar la marca
--network=host
, usa-p 2575:2575
. Además, en lugar de configurar--receiver_ip=127.0.0.0
, configura--receiver_ip=0.0.0.0
. El comando debería verse de la siguiente manera:docker run \ -p 2575:2575 \ gcr.io/cloud-healthcare-containers/mllp-adapter \ /usr/mllp_adapter/mllp_adapter \ --hl7_v2_project_id=PROJECT_ID \ --hl7_v2_location_id=LOCATION \ --hl7_v2_dataset_id=DATASET_ID \ --hl7_v2_store_id=HL7V2_STORE_ID \ --export_stats=false \ --receiver_ip=0.0.0.0 \ --pubsub_project_id=PROJECT_ID \ --pubsub_subscription=PUBSUB_SUBSCRIPTION \ --api_addr_prefix=https://healthcare.googleapis.com:443/v1 \ --logtostderr
Error could not find default credentials
cuando se ejecuta de manera local
Cuando pruebas el adaptador MLLP de forma local,
encontrar el error
healthapiclient.NewHL7V2Client: oauth2google.DefaultTokenSource: google: could not find default credentials.
Este error se produce cuando el adaptador no puede encontrar tu Credenciales de ADC. Asegúrate de configurar las credenciales predeterminadas de la aplicación en tu entorno local.
Errores de autenticación
Si encuentras algún error de autenticación cuando pruebas el adaptador de MLLP de forma local que no se incluye en el resto de esta sección, vuelve a ejecutar el comando docker run
y agrega la marca -v ~/.config:/root/.config
al final del comando, de la siguiente manera:
docker run \
-v ~/.config:/root/.config \
...