透過 TCP/IP 連線傳送 HL7v2 訊息

本教學課程將說明如何使用基本較低層通訊協定 (MLLP),透過 TCP/IP 連線傳送 HL7v2 訊息。如要要求 MLLP 映像檔由認證者簽署,請按照「使用已簽署的 MLLP 映像檔,透過 TCP/IP 連線傳送 HL7v2 訊息」中的步驟操作。

本教學課程提供在下列環境中執行 GitHub 代管的開放原始碼 MLLP 轉接器的操作說明:

目標

完成本教學課程後,您將會學到以下內容:

費用

在本文件中,您會使用 Google Cloud的下列計費元件:

  • Cloud Healthcare API
  • Google Kubernetes Engine
  • Compute Engine
  • Cloud VPN
  • Pub/Sub

您可以使用 Pricing Calculator 根據預測用量產生預估費用。 新 Google Cloud 使用者可能符合申請免費試用的資格。

事前準備

開始本教學課程之前,請先詳閱 MLLP 和 Google Cloud MLLP 轉接器的概念說明文件,熟悉最小底層通訊協定 (MLLP) 的概念。概念說明文件概略說明 MLLP、醫療照護系統如何透過 MLLP 連線傳送及接收 Cloud Healthcare API 訊息,以及 MLLP 安全性的基本概念。

如要設定 MLLP 轉接器,您必須選擇或建立Google Cloud 專案,並完成下列步驟啟用必要的 API:

  1. 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.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Cloud Healthcare API, Google Kubernetes Engine, Container Registry, and Pub/Sub APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Cloud Healthcare API, Google Kubernetes Engine, Container Registry, and Pub/Sub APIs.

    Enable the APIs

  8. 等待 Kubernetes Engine API 和相關服務完成啟用。這可能需要幾分鐘的時間。
  9. 選擇殼層

    您可以使用 Cloud Shell 或本機殼層來完成本教學課程。

    Cloud Shell 是殼層環境,用於管理託管在 Google Cloud上的資源。Cloud Shell 已預先安裝 gcloud CLIkubectl 工具。gcloud CLI 提供 Google Cloud的主要指令列介面。kubectl 提供指令列介面,可用於執行 GKE 叢集相關指令。

    如果您想要使用本機殼層,則必須安裝 gcloud CLI。

    如要開啟 Cloud Shell 或設定本機殼層,請完成下列步驟:

    Cloud Shell

    如要啟動 Cloud Shell,請完成下列步驟:

    1. 前往 Google Cloud 控制台。

      Google Cloud 主控台

    2. 在主控台的右上角,按一下「Activate Google Cloud Shell」(啟用 Google Cloud Shell) 按鈕:

    主控台底部的頁框中會開啟一個 Cloud Shell 工作階段。您可以使用這個殼層來執行 gcloudkubectl 指令。

    本機殼層

    如要安裝 gcloud CLI 和 kubectl 工具,請完成下列步驟:

    1. 安裝並初始化 Google Cloud CLI
    2. 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.

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    3. 如果您只想在本機測試轉接器,則不需要完成其他步驟,可以直接繼續建立資料集。如果您要將轉接器部署至 GKE,請執行下列指令來安裝 kubectl 指令列工具:

      gcloud components install kubectl

    建立資料集

    如果您尚未建立 Cloud Healthcare API 資料集,請完成下列步驟建立資料集:

    控制台

    1. 在 Google Cloud 控制台中,前往「Datasets」(資料集) 頁面。

      前往「資料集」

    2. 按一下「建立資料集」
    3. 在「Name」欄位中,輸入資料集的 ID。資料集 ID 必須符合下列規定:
      • 位置中的專屬 ID
      • 由 1 到 256 個字元組成的 Unicode 字串,包括以下內容:
        • Numbers
        • 信件
        • 底線
        • 破折號
        • 週期
    4. 在「Location type」(位置類型) 專區中,選擇下列其中一種位置類型:
      • 區域:資料集會永久保留在一個 Google Cloud 區域內。選取後,請在「區域」欄位中輸入或選取位置。
      • 多地區:資料集永久位於跨越多個 Google Cloud 區域的一個位置。選取後,在「Multi-region field」中輸入或選取多區域位置。
    5. 按一下「建立」

    新的資料集會顯示在資料集清單中。

    gcloud

    如要建立資料集,請執行 gcloud healthcare datasets create 指令:

    gcloud healthcare datasets create DATASET_ID \
        --location=LOCATION

    如果要求成功,指令會傳回以下輸出內容:

    Create request issued for: [DATASET_ID]
    Waiting for operation [OPERATION_ID] to complete...done.
    Created dataset [DATASET_ID].

    建立 Pub/Sub 主題和訂閱項目

    如要在訊息建立或擷取時接收通知,您必須使用 HL7v2 儲存庫設定 Pub/Sub 主題。詳情請參閱「設定 Pub/Sub 通知」。

    如要建立主題,請完成下列步驟:

    控制台

    1. 前往 Google Cloud 控制台的 Pub/Sub「主題」頁面。

      前往 Pub/Sub 主題頁面

    2. 按一下 [Create Topic] (建立主題)

    3. 使用 URI 輸入主題名稱:

      projects/PROJECT_ID/topics/TOPIC_NAME

      其中 PROJECT_ID 是您的 Google Cloud 專案 ID。

    4. 按一下 [建立]。

    gcloud

    如要建立主題,請執行 gcloud pubsub topics create 指令:

    gcloud pubsub topics create projects/PROJECT_ID/topics/TOPIC_NAME

    如果要求成功,指令會傳回以下輸出內容:

    Created topic [projects/PROJECT_ID/topics/TOPIC_NAME].

    如要建立訂閱項目,請完成下列步驟:

    控制台

    1. 前往 Google Cloud 控制台的 Pub/Sub「主題」頁面。

      前往 Pub/Sub 主題頁面

    2. 按一下專案的主題。

    3. 按一下 [Create Subscription] (建立訂閱)

    4. 輸入訂閱名稱:

      projects/PROJECT_ID/subscriptions/SUBSCRIPTION_NAME

    5. 將「傳送類型」設為「提取」,然後按一下「建立」

    gcloud

    如要建立訂閱項目,請執行 gcloud pubsub subscriptions create 指令:

    gcloud pubsub subscriptions create SUBSCRIPTION_NAME \
        --topic=projects/PROJECT_ID/topics/TOPIC_NAME

    如果要求成功,指令會傳回以下輸出內容:

    Created subscription [projects/PROJECT_ID/subscriptions/SUBSCRIPTION_NAME].

    建立使用 Pub/Sub 主題設定的 HL7v2 儲存庫

    建立 HL7v2 儲存庫,並使用 Pub/Sub 主題進行設定。如要建立 HL7v2 儲存庫,您必須先建立資料集。為了達到本教學課程的目的,請使用同一個專案來儲存 HL7v2 和 Pub/Sub 主題。

    如要建立使用 Pub/Sub 主題設定的 HL7v2 儲存庫,請完成下列步驟:

    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"

    如果要求成功,伺服器會以 JSON 格式傳回:

    {
      "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

    如果要求成功,伺服器會以 JSON 格式傳回:

    {
      "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID",
      "notificationConfigs": [
        {
          "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC"
        }
      ]
    }
    

    設定 Pub/Sub 權限

    如要在建立或擷取 HL7v2 訊息時傳送通知至 Pub/Sub,您需要在 Cloud Healthcare API 上設定 Pub/Sub 權限。每個專案都必須執行這項操作一次。

    如要將必要的 pubsub.publisher 角色新增至專案的服務帳戶,請完成下列步驟:

    控制台

    1. 在 Google Cloud 主控台的 IAM 頁面中,確認相關專案服務帳戶的「Role」欄中是否顯示「Healthcare Service Agent」角色。帳戶名稱為 service-PROJECT_NUMBER@gcp-sa-healthcare.iam.gserviceaccount.com。如要瞭解如何找出 PROJECT_NUMBER,請參閱「識別專案」。

    2. 在與角色相符的「Inheritance」欄中,按一下鉛筆圖示。「Edit permissions」窗格隨即開啟。

    3. 按一下「Add another role」(新增其他角色),然後搜尋「Pub/Sub Publisher」(Pub/Sub 發布者) 角色。

    4. 選取角色,然後點選 [Save] (儲存)。服務帳戶已新增 pubsub.publisher 角色。

    gcloud

    如要新增服務帳戶權限,請執行 gcloud projects add-iam-policy-binding 指令。如要瞭解如何找出 PROJECT_IDPROJECT_NUMBER,請參閱「識別專案」一節。

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-healthcare.iam.gserviceaccount.com \
        --role=roles/pubsub.publisher

    提取預先建構的 Docker 映像檔

    MLLP 轉接器是容器化應用程式,會在 Container Registry 中預先建構的 Docker 映像檔中排程。

    如要拉取最新版本的映像檔,請執行下列指令:

    docker pull gcr.io/cloud-healthcare-containers/mllp-adapter:latest
    

    在本機測試 MLLP 轉接器

    在本機測試轉接程式時,您可以將轉接程式設為接收器發布端或兩者皆是。接收器和發布端設定有下列主要差異:

    • 當轉接程式以接收器身分執行時,會從外部來源接收 HL7v2 訊息,並呼叫 messages.ingest 將訊息擷取至 HL7v2 儲存庫,藉此建立 Pub/Sub 通知。系統會將通知傳送至訂閱 HL7v2 儲存庫 Pub/Sub 主題的應用程式。
    • 當配接器以發布端的形式執行時,會監聽使用 messages.createmessages.ingest 在 HL7v2 儲存庫中建立或擷取的 HL7v2 訊息。建立訊息後,系統會將 Pub/Sub 通知傳送至轉接程式,轉接程式會將訊息發布至外部接收器。

    以下各節將說明如何執行轉接程式,讓其充當接收器發布者

    確認您可以在本機電腦上執行 MLLP 轉接器後,請繼續閱讀下一節,瞭解如何將 MLLP 轉接器部署至 Google Kubernetes Engine

    在本機上測試 MLLP 轉接器做為接收器

    當轉接程式從外部來源 (例如護理中心) 接收 HL7v2 訊息時,會呼叫 messages.ingest,並將 HL7v2 訊息擷取至已設定的 HL7v2 儲存庫。您可以在轉接程式的原始碼中觀察這項現象。

    如要在本機測試做為接收器的轉接器,請完成下列步驟:

    1. 在您提取預先建構的 Docker 映像檔的機器上,執行下列指令:

      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

      其中:

      • PROJECT_ID 是包含 HL7v2 儲存庫的 Google Cloud 專案 ID。
      • LOCATION 是 HL7v2 儲存庫所在的地區。
      • DATASET_ID 是 HL7v2 儲存庫的父項資料集 ID。
      • HL7V2_STORE_ID 是您要傳送 HL7v2 訊息的 HL7v2 儲存庫 ID。

      執行上述指令後,轉接器會列印類似以下的訊息,並開始在本機電腦上執行,位址為 127.0.0.1 IP 位址,位於 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.
      

      如果發生任何錯誤,請按照下列疑難排解步驟操作:

    2. 如要在轉接程式以前景程序執行時繼續測試,請在本機電腦上開啟其他終端機。

    3. 在新終端機中,如要安裝 Netcat,請執行下列指令:

      sudo apt install netcat
      
    4. 下載 hl7v2-mllp-sample.txt 檔案,並儲存在本機。

    5. 如要將 HL7v2 訊息傳送至轉接器,請在下載檔案的目錄中執行下列指令。MLLP 轉接器會在本機主機的 2575 通訊埠上監聽。這個指令會透過 MLLP 轉接器將訊息傳送至 HL7v2 儲存庫。

      Linux

      echo -n -e "\x0b$(cat hl7v2-mllp-sample.txt)\x1c\x0d" | nc -q1 localhost 2575 | less
      

      如果訊息已成功擷取至 HL7v2 儲存庫,指令會傳回以下輸出內容:

      ^KMSH|^~\&|TO_APP|TO_FACILITY|FROM_APP|FROM_FACILITY|19700101010000||ACK|c507a97e-438d-44b0-b236-ea95e5ecbbfb|P|2.5^MMSA|AA|20150503223000^\
      

      這項輸出內容表示 HL7v2 儲存庫已使用 AA (Application Accept) 回應類型回應,這表示訊息已通過驗證並成功攝入。

    6. 您也可以開啟執行轉接程式的終端機,確認訊息是否已成功傳送。輸出內容應如下所示:

       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.
      
    7. 訊息會儲存在 HL7v2 儲存庫中,因此您可以呼叫 messages.list 來查看訊息:

      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"

      如果要求成功,伺服器會以資源路徑傳回訊息 ID:

      {
        "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

      如果要求成功,伺服器會以資源路徑傳回訊息 ID:

      {
        "hl7V2Messages": [
          {
            "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID"
          }
        ]
      }
      

    在本機上以發布者的身分測試 MLLP 轉接器

    當您以發布端的身份測試轉接器時,請呼叫 messages.createmessages.ingest,並以二進位資料的形式提供訊息檔案,藉此建立訊息。

    轉接器會自動確認透過 messages.createmessages.ingest 傳送的 Pub/Sub 訊息。

    當轉接程式成功擷取及傳送 Pub/Sub 訊息時,會通知您。此轉接器是 Pub/Sub 訂閱者,因此會自動確認這些訊息。因此,系統會從您使用轉接程式所設定的 Pub/Sub 訂閱中,移除這些訊息的佇列。

    如要從 Pub/Sub 訂閱項目提取資料,並個別驗證訊息是否已發布,您必須建立第二個 Pub/Sub 訂閱項目,並指派給先前建立的主題。傳送至第二個訂閱項目的訊息不會自動由轉接器確認,而是會保留,以便您擷取。

    如要為先前建立的主題指派第二個 Pub/Sub 訂閱項目,請完成下列步驟:

    控制台

    1. 前往 Google Cloud 控制台的 Pub/Sub「主題」頁面。

      前往 Pub/Sub 主題頁面

    2. 按一下專案的主題。這是您用來建立初始訂閱的主題。

    3. 按一下 [Create Subscription] (建立訂閱項目)

    4. 輸入訂閱名稱:

      projects/PROJECT_ID/subscriptions/SECOND_SUBSCRIPTION_NAME

      將「Delivery Type」保留為「提取」

    5. 按一下 [Create] (建立)。

    gcloud

    如要為先前建立的主題建立第二個 Pub/Sub 訂閱項目,請執行 gcloud pubsub subscriptions create 指令:

    gcloud pubsub subscriptions create SECOND_SUBSCRIPTION_NAME --topic=projects/PROJECT_ID/topics/TOPIC_NAME

    如果要求成功,指令會傳回以下輸出內容:

    Created subscription [projects/PROJECT_ID/subscriptions/SECOND_SUBSCRIPTION_NAME].

    如要以發布者的身分在本機測試轉接器,請在您擷取預先建構的 Docker 映像檔的電腦上完成下列步驟:

    1. 安裝 Netcat

      sudo apt install netcat
      
    2. 下載 hl7v2-mllp-ack-sample.txt 檔案,並儲存在本機。檔案包含 ACK 訊息,此訊息是轉接程式嘗試發布訊息時所需的回應。

    3. 如要讓 Netcat 在通訊埠 2525 上監聽傳入的連線,請在下載檔案的目錄中執行下列指令。

      Linux

      echo -n -e "\x0b$(cat hl7v2-mllp-ack-sample.txt)\x1c\x0d" | nc -q1 -lv -p 2525 | less
      

      啟動 Netcat 後,會顯示類似以下範例的輸出訊息:

      listening on [any] 2525 ...
      
    4. Netcat 會做為前景程序執行,因此如要繼續進行測試,請在本機電腦上開啟其他終端機。

    5. 如要啟動轉接器,請在新終端機中執行下列指令:

      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

      其中:

      • PROJECT_ID 是包含 HL7v2 儲存庫的 Google Cloud 專案 ID。
      • LOCATION 是 HL7v2 儲存庫所在的地區。
      • DATASET_ID 是 HL7v2 儲存庫的父項資料集 ID。
      • HL7V2_STORE_ID 是您要傳送 HL7v2 訊息的 HL7v2 儲存庫 ID。
      • PROJECT_ID 是包含 Pub/Sub 主題的 Google Cloud 專案 ID。
      • PUBSUB_SUBSCRIPTION 是您建立的與 Pub/Sub 主題相關聯的第一個訂閱項目名稱。此轉接器會使用來自此訂閱項目的訊息,並自動確認訊息,因此如要查看發布至主題的訊息,您必須從先前建立的第二個訂閱項目提取訊息。

      執行上述指令後,轉接器就會開始在本機電腦上執行,IP 位址為 127.0.0.1,通訊埠為 2575。

      如果發生任何錯誤,請按照下列疑難排解步驟操作:

      轉接器會做為前景程序執行,因此如要繼續測試,請在本機電腦上開啟其他終端機。

    6. 下載 hl7v2-sample.json 檔案,並儲存在本機。在下載檔案的目錄中,呼叫 messages.create 方法,即可在 HL7v2 儲存庫中建立訊息:

      curl

      如要建立 HL7v2 訊息,請提出 POST 要求,並指定下列資訊:

      • 父項資料集的名稱
      • HL7v2 儲存庫的名稱
      • 訊息
      • 存取權杖

      以下範例顯示使用 curlPOST 要求,以及名為 hl7v2-sample.json 的 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"

      如果要求成功,伺服器會以 JSON 格式傳回:

      {
        "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

      如要建立 HL7v2 訊息,請提出 POST 要求,並指定下列資訊:

      • 父項資料集的名稱
      • HL7v2 儲存庫的名稱
      • 訊息
      • 存取權杖

      以下範例顯示使用 Windows PowerShell 的 POST 要求,以及名為 hl7v2-sample.json 的範例 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

      如果要求成功,伺服器會以 JSON 格式傳回:

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

      建立訊息後,MLLP 轉接器會傳回類似以下的回應:

      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.
      
    7. 在您執行 Netcat 的終端機中,會顯示類似下列範例的輸出內容。這項輸出結果表示訊息已發布:

      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^\
      

      這會對應至您建立訊息時收到的回應中 data 欄位的值。這與 hl7v2-sample.json 檔案中的 data 值相同。

    8. 如要查看轉接器發布至 Pub/Sub 主題的訊息,請在您建立的第二個 Pub/Sub 訂閱項目上執行 gcloud pubsub subscriptions pull 指令:

      gcloud pubsub subscriptions pull --auto-ack SECOND_SUBSCRIPTION

      指令會傳回以下關於建立的 HL7v2 訊息的輸出內容。請注意 ATTRIBUTES 欄中的 publish=true 值,這表示訊息已發布至 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  |
      └-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┘

    將訊息發布至不同的外部接收器

    您可以為 HL7v2 儲存庫設定多個 Pub/Sub 主題,並使用篩選器將通知傳送至不同的 Pub/Sub 主題。接著,您可以為每個 Pub/Sub 主題執行 MLLP 轉接器,將訊息發布至不同的外部接收器。

    如要設定包含多個 Pub/Sub 主題和每個主題的篩選器的 HL7v2 儲存庫,請完成下列步驟:

    1. 建立兩個 Pub/Sub 主題,並為每個主題建立訂閱項目。詳情請參閱「建立 Pub/Sub 主題和訂閱項目」。

    2. 執行下列指令:

      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"

      如果要求成功,伺服器會以 JSON 格式傳回:

      {
        "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

      如果要求成功,伺服器會以 JSON 格式傳回:

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

    測試訊息轉送

    如要測試訊息路由,請完成下列各節中的步驟。

    設定及啟動第一個接收器和轉接器

    如要設定及啟動第一個接收器和轉接器,請完成下列步驟:

    1. 在您提取預先建構 Docker 映像檔的機器上,執行下列指令來安裝 Netcat

      sudo apt install netcat
      
    2. 如果尚未下載 hl7v2-mllp-ack-sample.txt,請下載該檔案。這個檔案包含 ACK 訊息,可用於在適配器嘗試發布訊息時,做為回應。

    3. 如要為第一個接收器設定 2525 通訊埠,請執行下列指令:

      Linux

      echo -n -e "\x0b$(cat hl7v2-mllp-ack-sample.txt)\x1c\x0d" | nc -q1 -lv -p 2525 | less
      

      Netcat 程序啟動後,系統會顯示以下輸出內容:

      listening on [any] 2525 ...
      
    4. 如要啟動第一個轉接器,請在新的終端機中執行下列指令:

      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

      其中:

      • PROJECT_ID 是包含 HL7v2 儲存庫的 Google Cloud 專案 ID。
      • LOCATION 是 HL7v2 儲存庫所在的地區。
      • DATASET_ID 是 HL7v2 儲存庫的父項資料集 ID。
      • HL7V2_STORE_ID 是您要傳送 HL7v2 訊息的 HL7v2 儲存庫 ID。
      • PROJECT_ID 是包含 Pub/Sub 主題的 Google Cloud 專案 ID。
      • PUBSUB_SUBSCRIPTION 是您建立的第一個訂閱項目名稱,與第一個 Pub/Sub 主題相關聯。此轉接程式會使用來自此訂閱項目的訊息,並自動確認訊息。

      執行這項指令後,轉接器就會開始在本機電腦上執行,位址為 127.0.0.1:2575。它會將新訊息發布至位於通訊埠 2525 的第一個外部接收器。

    設定及啟動第二個接收器和轉接器

    如要設定及啟動第二個接收器和轉接器,請完成下列步驟:

    1. 在您提取預先建構 Docker 映像檔的機器上,執行下列指令來安裝 Netcat

      sudo apt install netcat
      
    2. 如果尚未下載 hl7v2-mllp-ack-sample.txt,請下載該檔案。這個檔案包含 ACK 訊息,可用於在適配器嘗試發布訊息時,做為回應。

    3. 如要為第二個接收器設定 2526 通訊埠,請執行下列指令。

      Linux

      echo -n -e "\x0b$(cat hl7v2-mllp-ack-sample.txt)\x1c\x0d" | nc -q1 -lv -p 2526 | less
      

      Netcat 程序啟動後,系統會顯示以下輸出內容:

      listening on [any] 2526 ...
      
    4. 如要啟動第二個轉接器,請在新的終端機中執行下列指令:

      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

      其中:

      • PROJECT_ID 是包含 HL7v2 儲存庫的 Google Cloud 專案 ID。
      • LOCATION 是 HL7v2 儲存庫所在的地區。
      • DATASET_ID 是 HL7v2 儲存庫的父項資料集 ID。
      • HL7V2_STORE_ID 是您要傳送 HL7v2 訊息的 HL7v2 儲存庫 ID。
      • PROJECT_ID 是包含 Pub/Sub 主題的 Google Cloud 專案 ID。
      • SECOND_PUBSUB_SUBSCRIPTION 是您建立的第二個訂閱項目名稱,與第二個 Pub/Sub 主題相關聯。此轉接程式會使用來自此訂閱的訊息,並自動確認訊息。

      執行這項指令後,轉接器就會開始在本機電腦上執行,端口為 127.0.0.1:2576 IP 位址。並將新訊息發布至位於 2526 通訊埠的第二個外部接收器。

    將訊息發布給第一個接收者

    如要建立只會發布至第一個外部接收器的訊息,請完成下列步驟:

    1. 下載 hl7v2-sample1.json

    2. 在下載 hl7v2-sample1.json 的資料夾中,呼叫 messages.create 方法,即可在 HL7v2 儲存庫中建立訊息:

      curl

      如要建立 HL7v2 訊息,請提出 POST 要求,並指定下列資訊:

      • 父項資料集的名稱
      • HL7v2 儲存庫的名稱
      • 訊息
      • 存取權杖

      以下範例顯示使用 curlPOST 要求,以及 JSON 範例檔案 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"

      如果要求成功,伺服器會以 JSON 格式傳回:

      {
       "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

      如要建立 HL7v2 訊息,請提出 POST 要求,並指定下列資訊:

      • 父項資料集的名稱
      • HL7v2 儲存庫的名稱
      • 訊息
      • 存取權杖

      以下範例顯示使用 Windows PowerShell 的 POST 要求,以及名為 hl7v2-sample1.json 的範例 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

      如果要求成功,伺服器會以 JSON 格式傳回:

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

      在這個回應中,sendFacility 已設為 SEND_FACILITY_1,因此 Pub/Sub 通知只會傳送至第一個 Pub/Sub 主題。建立訊息後,第一個 MLLP 轉接器會傳回以下回應:

      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.
      

      由於沒有傳送通知至第二個 Pub/Sub 主題,因此第二個 MLLP 轉接器不會傳回任何回應。

      在您執行第一個 Netcat 程序的終端機中,會顯示下列輸出內容。這項輸出結果表示訊息已發布。

      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^\
      

      這個輸出內容會與您建立訊息時收到的回應中 data 欄位中的值相符。這與 hl7v2-sample1.json 檔案中的 data 值相同。

    將訊息發布至第二個接收者

    如要建立只會發布至第二個外部接收器的訊息,請完成下列步驟:

    1. 在本機上開啟新的終端機。

    2. 如要建立只會發布給第二個外部接收者的訊息,請下載 hl7v2-sample2.json

    3. 在下載 hl7v2-sample2.json 的資料夾中,呼叫 messages.create 方法,即可在 HL7v2 儲存庫中建立訊息:

      curl

      如要建立 HL7v2 訊息,請提出 POST 要求,並指定下列資訊:

      • 父項資料集的名稱
      • HL7v2 儲存庫的名稱
      • 訊息
      • 存取權杖

      以下範例顯示使用 curlPOST 要求,以及 JSON 範例檔案 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"

      如果要求成功,伺服器會以 JSON 格式傳回:

      {
       "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

      如要建立 HL7v2 訊息,請提出 POST 要求,並指定下列資訊:

      • 父項資料集的名稱
      • HL7v2 儲存庫的名稱
      • 訊息
      • 存取權杖

      以下範例顯示使用 Windows PowerShell 的 POST 要求,以及 JSON 範例檔案 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

      如果要求成功,伺服器會以 JSON 格式傳回:

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

      請注意,sendFacility 為 SEND_FACILITY_2,因此 Pub/Sub 通知只會傳送至第二個 Pub/Sub 主題。建立訊息後,第一個 MLLP 轉接器不會傳回任何回應,而第二個 MLLP 轉接器會傳回以下回應:

      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.
      

      在您執行第二個 Netcat 程序的終端機中,會顯示下列輸出內容。這項輸出結果表示訊息已發布。

      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^\
      

      這個輸出內容會與您建立訊息時收到的回應中 data 欄位中的值相符。這與 hl7v2-sample2.json 檔案中的 data 值相同。

    將 MLLP 轉接器部署至 Google Kubernetes Engine

    從護理中心透過 MLLP 傳送 HL7v2 訊息時,一種可能的設定是將訊息傳送至在Google Cloud 中部署的轉接器,並可將訊息轉送至 Cloud Healthcare API。

    MLLP 轉接器會在 GKE 叢集中以無狀態應用程式的形式執行。GKE 叢集是用於執行容器化應用程式的 VM 執行個體群組。無狀態應用程式是指不會將資料或應用程式狀態儲存到叢集或永久儲存空間的應用程式。資料和應用程式狀態將留在用戶端,這使得無狀態應用程式更具擴充性。

    GKE 使用 Deployment 控制器將無狀態應用程式部署為統一且非唯一的 Pod。Deployment 管理應用程式的「所需狀態」:應用程式中應執行的 Pod 數量、應執行的容器映像檔版本、應標記的 Pod 內容等等。您可以透過更新部署的 Pod 規格來動態變更所需狀態。

    在部署轉接器的同時,您可以建立 Service 控制器,以便使用內部負載平衡將轉接器連結至 Cloud Healthcare API。

    如果您是第一次使用 GKE,請先完成 GKE 快速入門導覽課程,瞭解產品的運作方式。

    為 GKE 服務帳戶新增 Pub/Sub API 權限

    使用服務帳戶向 Cloud Platform 驗證身分一文所述,容器叢集中的每個節點都是一個 Compute Engine 執行個體。因此,當 MLLP 轉接器在容器叢集中執行時,會自動繼承其部署的 Compute Engine 執行個體範圍。

    Google Cloud 會自動建立名為「Compute Engine 預設服務帳戶」的服務帳戶,GKE 會將這個服務帳戶與 GKE 建立的節點建立關聯。視專案的設定而定,預設服務帳戶不一定具備使用其他 Cloud Platform API 的權限。GKE 也會指派一些有限的存取權範圍給 Compute Engine 執行個體。

    為獲得最佳結果,請勿透過更新預設服務帳戶的權限,或指派更多存取權範圍給 Compute Engine 執行個體,從在 GKE 上執行的 Pod 驗證其他 Google Cloud 服務 (例如 Pub/Sub)。請改為建立自己的服務帳戶

    您必須向容器叢集授予必要的 Pub/Sub 權限,但也可以選擇授予寫入指標至 Cloud Monitoring 的權限。

    如要建立新的服務帳戶,並只包含容器叢集所需的範圍,請完成下列步驟:

    控制台

    建立服務帳戶:

    1. 前往 Google Cloud 控制台的「Create service account」(建立服務帳戶) 頁面。

      前往「Create service account」(建立服務帳戶)

    2. 選取專案。

    3. 在「Service account name」(服務帳戶名稱) 欄位中輸入名稱。Google Cloud 控制台會根據這個名稱填入「Service account ID」欄位。

      選用:在「服務帳戶說明」欄位中輸入說明。

    4. 按一下 [建立]。

    5. 按一下「請選擇角色」欄位。

      在「所有角色」下方,依序點選「Pub/Sub」 >「Pub/Sub 訂閱者」

    6. 按一下「新增其他角色」,然後點選「選取角色」欄位。

      在「所有角色」下方,依序點選「Cloud Healthcare」 >「Healthcare HL7v2 訊息擷取」

    7. 選用:如要啟用監控功能,請按一下「新增其他角色」,然後點選「選取角色」欄位。

      在「所有角色」下方,依序點選「監控」 >「監控指標寫入者」

    8. 按一下「繼續」

    9. 按一下「Done」(完成),即完成建立服務帳戶。

      請勿關閉瀏覽器視窗。您將在下一個程序中使用這個視窗。

    gcloud

    1. 如要建立服務帳戶,請執行 gcloud iam service-accounts create 指令。

      gcloud iam service-accounts create SERVICE_ACCOUNT_NAME

      輸出即為服務帳戶。

      Created service account SERVICE_ACCOUNT_NAME.
    2. 如要將各個角色授予服務帳戶,請執行 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

      輸出內容包含更新後的政策:

      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

    正在建立叢集

    如要在 GKE 中建立叢集,請執行 gcloud container clusters create 指令:

    gcloud container clusters create mllp-adapter \
        --zone=COMPUTE_ZONE \
        --service-account CLIENT_EMAIL

    其中:

    • COMPUTE_ZONE 是叢集部署的區域。區域是叢集及其資源的大致區域位置。舉例來說,us-west1-aus-west 區域中的一個可用區。如果您已使用 gcloud config set compute/zone 設定預設區域,則此標記的值會覆寫預設值。
    • CLIENT_EMAIL 是您要使用的服務帳戶 ID。格式為 SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com。

    指令會傳回類似以下範例的輸出內容:

    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

    建立叢集後,GKE 會建立三個 Compute Engine VM 執行個體。您可以使用下列指令列出執行個體,藉此驗證此情況:

    gcloud compute instances list
    

    設定部署作業

    將應用程式部署至 GKE 時,您可以使用部署資訊清單檔案 (通常為 YAML 檔案) 定義部署作業的屬性。如需範例,請參閱「建立部署作業」。

    1. 開啟另一個終端機。

    2. 使用文字編輯器,建立名為 mllp_adapter.yaml 的部署資訊清單檔案,並加入下列內容:

    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"

    其中:

    • PROJECT_ID 是包含 HL7v2 儲存庫的 Google Cloud 專案 ID。
    • LOCATION 是 HL7v2 儲存庫所在的地區。
    • DATASET_ID 是 HL7v2 儲存庫的父項資料集 ID。
    • HL7V2_STORE_ID 是您要傳送 HL7v2 訊息的 HL7v2 儲存庫 ID。

    部署作業具有下列屬性:

    • spec: replicas: 是部署作業管理的複製 Pod 數量。
    • spec: template: metadata: labels: 是指派給每個 Pod 的標籤,讓部署作業用來管理 Pod。
    • spec: template: spec:Pod 規格,定義了每個 Pod 的執行方式。
    • spec: containers 包含要在每個 Pod 中執行的容器名稱,以及應執行的容器映像檔。

    如要進一步瞭解部署規格,請參閱 Deployment API 參考資料

    設定服務

    如要讓叢集外部的應用程式 (例如客戶服務中心) 能夠存取 MLLP 轉接器,您必須設定內部負載平衡器

    如果您尚未設定 VPN,只要應用程式使用相同的虛擬私有雲網路,且位於相同的 Google Cloud 區域,即可透過內部負載平衡器存取 MLLP 轉接器。舉例來說,如要讓轉接器可存取位於相同地區和虛擬私有雲網路中的 Compute Engine VM 執行個體,您可以將內部負載平衡器新增至叢集的 Service 資源。

    在建立部署資訊清單檔案的目錄中,使用文字編輯器建立名為 mllp_adapter_service.yaml 的服務資訊清單檔案,並加入下列內容。這個檔案負責設定內部負載平衡:

    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
    

    服務具有下列屬性:

    • metadata: name: 是您為服務選擇的名稱。在本例中為 mllp-adapter-service
    • metadata: annotations: 是註解,指定要設定內部負載平衡器。
    • spec: type: 是負載平衡器的類型。
    • ports: port: 可用於指定服務可接收來自同一叢集中其他服務的流量。系統會使用 2575 的預設 MLLP 通訊埠。
    • ports: targetPort: 用於指定服務執行的每個 Pod 上的通訊埠。
    • spec: selector: app: 可指定 Service 的目標 Pod。

    雖然您可以為負載平衡器指定 IP 位址 (使用 clusterIP 欄位),但負載平衡器可以產生自己的 IP 位址,讓您傳送訊息。目前讓叢集產生 IP 位址,您稍後會在本教學課程中使用。

    如要進一步瞭解內部負載平衡,請參閱 GKE 說明文件。

    如要進一步瞭解服務規格,請參閱 Service API 參考資料

    部署部署作業

    如要將轉接器部署至 GKE 叢集,請在包含 mllp_adapter.yaml 部署資訊清單檔案的目錄中,執行下列指令:

    kubectl apply -f mllp_adapter.yaml
    

    指令傳回下列結果:

    deployment.extensions "mllp-adapter-deployment" created
    

    檢查部署

    建立部署作業後,您可以使用 kubectl 工具進行檢查。

    如要取得部署作業的詳細資訊,請執行下列指令:

    kubectl describe deployment mllp-adapter
    

    如要列出部署作業建立的 Pod,請執行下列指令:

    kubectl get pods -l app=mllp-adapter
    

    如要取得已建立 Pod 的相關資訊,請執行下列操作:

    kubectl describe pod POD_NAME

    如果部署成功,先前指令的輸出內容最後部分應包含以下資訊:

    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
    

    部署服務並建立內部負載平衡器

    如要建立內部負載平衡器,請在包含 mllp_adapter_service.yaml 服務資訊清單檔案的目錄中執行下列指令:

    kubectl apply -f mllp_adapter_service.yaml
    

    指令傳回下列結果:

    service "mllp-adapter-service" created
    

    檢查服務

    建立服務後,請檢查服務,確認已成功設定。

    如要檢查內部負載平衡器,請執行下列指令:

    kubectl describe service mllp-adapter-service
    

    這個指令的輸出內容會類似以下範例:

    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
    

    系統最多可能需要一分鐘的時間才能填入 LoadBalancer Ingress IP 位址。您將在下一個步驟中,使用這個 IP 位址和 2575 通訊埠,從叢集外部存取服務。

    建立 Compute Engine VM 並傳送訊息

    在本教學課程稍早的部分,您在本機測試 MLLP 轉接器,並將 HL7v2 訊息傳送至 HL7v2 儲存庫,現在您將從 Compute Engine VM 將訊息傳送至在 GKE 上執行的 MLLP 轉接器。然後將訊息轉送至 HL7v2 儲存庫。

    如要將要求從新執行個體傳送至 GKE 叢集,該執行個體和現有執行個體必須位於相同的區域,並使用相同的虛擬私有雲網路

    在本節結尾,您將列出發布至 Pub/Sub 主題的通知,以及 HL7v2 儲存庫中的 HL7v2 訊息。您必須授予 Compute Engine VM 執行個體執行這些工作的權限。建立執行個體前,請先完成下列步驟,建立具備必要權限的新服務帳戶:

    控制台

    建立服務帳戶:

    1. 前往 Google Cloud 控制台的「Create service account」(建立服務帳戶) 頁面。

      前往「Create service account」(建立服務帳戶)

    2. 選取專案。

    3. 在「Service account name」(服務帳戶名稱) 欄位中輸入名稱。Google Cloud 控制台會根據這個名稱填入「Service account ID」欄位。

      選用:在「服務帳戶說明」欄位中輸入說明。

    4. 按一下 [建立]。

    5. 按一下「請選擇角色」欄位。

      在「所有角色」下方,依序點選「Pub/Sub」 >「Pub/Sub 訂閱者」

    6. 按一下「新增其他角色」,然後點選「選取角色」欄位。

      在「所有角色」下方,依序點選「Cloud Healthcare」 >「Healthcare HL7v2 訊息使用者」

    7. 按一下「繼續」

    8. 按一下「Done」(完成),即完成建立服務帳戶。

      請勿關閉瀏覽器視窗。您將在下一個程序中使用這個視窗。

    gcloud

    1. 如要建立服務帳戶,請執行 gcloud iam service-accounts create 指令。

      gcloud iam service-accounts create SERVICE_ACCOUNT_NAME

      輸出即為服務帳戶。

      Created service account SERVICE_ACCOUNT_NAME.
    2. 如要將各個角色授予服務帳戶,請執行 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

      輸出內容包含更新後的政策:

      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

    請按照下列步驟在 Compute Engine 中建立 Linux 虛擬機器執行個體:

    控制台

    1. 前往 Google Cloud 控制台的「VM Instances」(VM 執行個體) 頁面

      前往「VM Instances」(VM 執行個體) 頁面

    2. 點選「建立執行個體」

    3. 為執行個體選擇與建立叢集時所選區域相符的區域可用區。舉例來說,如果您在建立叢集時,將 COMPUTE_ZONE 設為 us-central1-a,請在執行個體建立畫面中,將區域設為 us-central1 (Iowa),並將可用區設為 us-central1-a

    4. 在「Boot disk」(開機磁碟) 區段中,按一下 [Change] (變更) 開始設定您的開機磁碟。

    5. 在「Public images」(公開映像檔) 分頁中,選擇 Debian 作業系統的 9 版本。

    6. 按一下 [選取]。

    7. 在「Identity and API access」(身分及 API 存取權) 部分,選取您建立的服務帳戶。

    8. 在「Firewall」(防火牆) 區段中,選取 [Allow HTTP traffic] (允許 HTTP 流量)

    9. 按一下「建立」,建立執行個體。

    gcloud

    如要建立運算執行個體,請搭配下列選項執行 gcloud compute instances create 方法:

    • 您在建立叢集時選取的 ZONE
    • 允許 HTTP 流量的 http-server 標記
    • 您建立的 SERVICE_ACCOUNT
    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

    輸出結果會與下列範例類似:

    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

    啟動執行個體會花費一些時間。執行個體啟動後,就會列在「VM 執行個體」頁面中,並顯示綠色的狀態圖示。

    根據預設,執行個體會使用叢集使用的預設 VPC 網路,這表示流量可從執行個體傳送至叢集。

    如要連線至執行個體,請完成下列步驟:

    控制台

    1. 前往 Google Cloud 控制台的「VM Instances」(VM 執行個體) 頁面

      前往「VM Instances」(VM 執行個體) 頁面

    2. 在虛擬機器執行個體清單中,按一下您建立的執行個體列中的「SSH」SSH

    gcloud

    如要連線至執行個體,請執行 gcloud compute ssh 指令:

    gcloud compute ssh INSTANCE_NAME \
        --project PROJECT_ID \
        --zone ZONE

    您現在擁有一個終端機視窗,可讓您與 Linux 執行個體互動。

    1. 在終端機視窗中,安裝 Netcat

      sudo apt install netcat
      
    2. 下載 hl7v2-mllp-sample.txt 檔案並儲存到執行個體。如要瞭解檔案中使用的編碼和區段結束符號,請參閱「HL7v2 訊息區段分隔符和編碼」。

    3. 如要開始透過 MLLP 轉接器將 HL7v2 訊息傳送至 HL7v2 儲存庫,請在下載檔案的目錄中執行下列指令。使用檢查服務時顯示的 LoadBalancer Ingress 值。

      echo -n -e "\x0b$(cat hl7v2-mllp-sample.txt)\x1c\x0d" | nc LOAD_BALANCER_INGRESS_IP_ADDRESS 2575

      執行指令後,系統會透過 MLLP 轉接器將訊息傳送至 HL7v2 儲存庫。如果訊息已成功擷取至 HL7v2 儲存庫,指令會傳回以下輸出內容:

      MSA|AA|20150503223000|ILITY|FROM_APP|FROM_FACILITY|20190312162410||ACK|f4c59243-19c2-4373-bea0-39c1b2ba616b|P|2.5
      

      這項輸出內容表示 HL7v2 儲存庫已以 AA (Application Accept) 回應類型回應,表示訊息已通過驗證並成功攝入。

    4. 如要查看已發布至 Pub/Sub 主題的訊息,請執行 gcloud pubsub subscriptions pull 指令:

      gcloud pubsub subscriptions pull --auto-ack PUBSUB_SUBSCRIPTION

      指令會傳回以下關於擷取的 HL7v2 訊息輸出內容:

      ┌-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┐
      |                                                               DATA                                              |    MESSAGE_ID   |   ATTRIBUTES  |
      ├-----------------------------------------------------------------------------------------------------------------|-----------------|---------------|
      | projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/HL7V2_MESSAGE_ID | 123456789012345 | msgType=ADT   |
      └-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┘
    5. 您也可以在 HL7v2 儲存庫中列出訊息,查看是否已新增訊息:

      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"

      如果要求成功,伺服器會以資源路徑傳回訊息的 ID:

      {
        "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

      如果要求成功,伺服器會以資源路徑傳回訊息的 ID:

      {
        "hl7V2Messages": [
          {
            "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID"
          }
        ]
      }
      

    完成本節後,您已成功將 MLLP 轉接器部署至 GKE,並透過轉接器從遠端執行個體傳送 HL7v2 訊息至 Cloud Healthcare API。

    在本教學課程的其餘部分,您將瞭解如何在 Compute Engine 執行個體 (做為「內部部署」執行個體) 和轉接程式之間設定 VPN,藉此安全地加密傳送的 HL7v2 訊息。

    設定 VPN

    使用 VPN 可讓您擴展私人網路,在其中透過公用網路 (例如網際網路) 傳送 HL7v2 訊息。使用 VPN 時,您可以透過 MLLP 轉接器從護理中心傳送訊息至Google Cloud。這個流程中的系統會以單一私人網路的形式運作。

    您可以透過兩種方法使用 VPN 保護 MLLP 連線:

    設定 Cloud VPN

    Cloud VPN 可透過 IPsec VPN 連線,將您的內部部署網路安全連線至Google Cloud 虛擬私有雲 (VPC) 網路。在兩個網路之間傳輸的流量會由一個 VPN 閘道加密,然後由另一個 VPN 閘道解密。這可確保您的資料在網際網路或客戶服務中心網路中傳輸時安全無虞。

    在本教學課程中,您設定的每個 VPN 閘道都位於不同自訂網路和子網路,且位於不同的 Google Cloud 區域。

    us-central1 中設定的 VPN 閘道可做為 Google Cloud 端的 Cloud VPN 閘道,而 europe-west1 中的 Cloud VPN 閘道則會模擬您的「內部部署」閘道。

    命名與定址參考資料

    本教學課程使用下列命名與 IP 定址方法做為參考:

    Google Cloud 側

    • 聯播網名稱:cloud-vpn-network
    • 子網路名稱:subnet-us-central-10-0-1
    • 區域:us-central1
    • 子網路範圍:10.0.1.0/24
    • 外部 IP 位址名稱:cloud-vpn-ip
    • VPN 閘道名稱:vpn-us-central
    • VPN 通道名稱:vpn-us-central-tunnel-1

    「內部部署」端

    • 聯播網名稱:on-prem-vpn-network
    • 子網路名稱:subnet-europe-west-10-0-2
    • 區域:europe-west1
    • 子網路範圍:10.0.2.0/24
    • 外部 IP 位址名稱:on-prem-vpn-ip
    • VPN 閘道名稱:vpn-europe-west
    • VPN 通道名稱:vpn-europe-west-tunnel-1

    建立自訂虛擬私人雲端網路與子網路

    設定 Cloud VPN 的第一步是建立兩個 VPC 網路。在「內部部署」環境中設定名為 on-prem-vpn-network 的網路,並在名為 on-prem-instance 的 Compute Engine VM 執行個體上執行。另一個網路 (稱為 cloud-vpn-network) 是執行 MLLP 轉接器的 GKE 叢集所使用的網路。您將連線至 on-prem-instance VM,並透過 MLLP 轉接器的內部負載平衡器,將 HL7v2 訊息傳送至在 cloud-vpn-network 網路下執行的 MLLP 轉接器。

    請完成下列步驟,建立兩個自訂虛擬私有雲網路及其子網路:

    1. 如要建立第一個 VPC 網路 cloud-vpn-network,請執行下列指令:

      gcloud compute networks create cloud-vpn-network \
         --project=PROJECT_ID \
         --subnet-mode=custom
    2. 如要為 cloud-vpn-network 網路建立 subnet-us-central-10-0-1 子網路,請執行下列指令:

      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
    3. 如要建立 on-prem-vpn-network 虛擬私有雲網路,請執行下列指令:

      gcloud compute networks create on-prem-vpn-network \
         --project=PROJECT_ID \
         --subnet-mode=custom
    4. 如要為 on-prem-vpn-network VPC 網路建立 subnet-europe-west-10-0-2 子網路,請執行下列指令:

      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

    建立外部 IP 位址

    建立 VPN 閘道前,請完成下列步驟,為每個閘道保留外部 IP 位址:

    1. 如要為 cloud-vpn-ip 位址預留地區外部 (靜態) IP 位址,請執行下列指令:

      gcloud compute addresses create cloud-vpn-ip \
         --project=PROJECT_ID \
         --region=us-central1
    2. 如要為 on-prem-vpn-ip 位址預留地區外部 (靜態) IP 位址,請執行下列指令:

      gcloud compute addresses create on-prem-vpn-ip \
         --project=PROJECT_ID \
         --region=europe-west1
    3. 請記下外部 IP 位址,以便在下一節設定 VPN 閘道時使用。如要擷取外部 IP 位址,請執行下列指令:

      Cloud VPN IP 位址

      gcloud compute addresses describe cloud-vpn-ip  \
         --project PROJECT_ID \
         --region us-central1 \
         --format='flattened(address)'

      「內部部署」VPN IP 位址

      gcloud compute addresses describe on-prem-vpn-ip \
         --project PROJECT_ID \
         --region europe-west1 \
         --format='flattened(address)'

      指令會傳回類似以下的輸出內容:

      address: 203.0.113.1
      

    建立 VPN 閘道、通道和路徑

    請完成下列步驟,為 Cloud VPN 建立 VPN 閘道、通道和路由:

    1. 請按照「產生高強度的預先共用金鑰」一文的操作說明,建立加密高強度的預先共用金鑰 (共用密鑰)。本節將此鍵參照為 SHARED_SECRET

    2. 如要建立「目標 VPN 閘道」物件,請執行下列指令:

      gcloud compute target-vpn-gateways create vpn-us-central \
         --project PROJECT_ID \
         --region us-central1 \
         --network cloud-vpn-network
    3. 如要建立三個轉送規則,請執行下列指令,並將 CLOUD_VPN_EXTERNAL_ADDRESS 變數替換為前一節中 Cloud VPN IP 位址的值:

      將 ESP (IPsec) 流量傳送至閘道

      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

      將 UDP 500 流量傳送至閘道

      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

      將 UDP 4500 流量傳送至閘道

      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
    4. 如要建立通往 Cloud VPN 閘道的通道,請執行下列指令。將 ON_PREM_VPN_IP 替換為上一個部分的「內部部署」VPN IP 位址

      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
    5. 如要建立前往 10.0.2.0/24 的靜態路徑,請執行下列指令:

      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"

    請完成下列步驟,為「內部部署」VPN 建立 VPN 閘道、通道和路由:

    1. 如要建立「目標 VPN 閘道」物件,請執行下列指令:

      gcloud compute target-vpn-gateways create "vpn-europe-west" \
         --project PROJECT_ID \
         --region "europe-west1" \
         --network "on-prem-vpn-network"
    2. 如要建立三個轉送規則,請執行下列指令,並將 ON_PREMISES_VPN_EXTERNAL_ADDRESS 變數替換為上一個章節中 「內部部署」VPN IP 位址的值:

      將 ESP (IPsec) 流量傳送至閘道

      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

      將 UDP 500 流量傳送至閘道

      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

      將 UDP 4500 流量傳送至閘道

      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
    3. 如要建立通往「內部」閘道的通道,請執行下列指令:

      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
    4. 如要建立前往 10.0.1.0/24 的靜態路徑,請執行下列指令:

      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"

    您已建立 Cloud VPN 和「地端部署」閘道,並啟動通道。在您建立允許流量流經這兩者之間通道的防火牆規則前,VPN 閘道並不會連線。

    建立防火牆規則

    您必須為 VPN 通道的兩端建立防火牆規則。這些規則允許所有 TCP、UDP 與 ICMP 流量從 VPN 通道一端上的子網路輸入至另一端。

    1. 如要為 Cloud VPN 子網路建立防火牆規則,請執行下列指令:

      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
    2. 如要為「內部部署」子網路建立防火牆規則,請執行下列指令:

      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
    3. 請執行下列指令,建立防火牆規則,讓您透過 SSH 連線至通訊埠 22 的 VM 執行個體:

      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

    檢查 VPN 通道的狀態

    如要確認您的通道是否正常運作,請完成下列步驟:

    1. 前往 Google Cloud 控制台的 VPN 頁面。

      前往 VPN 頁面

    2. 按一下「Google VPN 通道」分頁標籤。

    3. 在每個通道的「狀態」欄位中,尋找綠色的勾號以及「已建立」字樣。如果有這些項目,即表示您的閘道已完成通道的交涉。如果在幾分鐘之後仍然沒有出現勾號,請參閱疑難排解

      如需 VPN 通道的其他記錄資訊,請參閱疑難排解頁面的「查閱 VPN 記錄」一文。例如,您可以查看有關已遺失的封包、通道狀態、收到的位元組與傳送的位元組等指標。

    您已成功設定 Cloud VPN,並設定必要的閘道、通道和防火牆規則,因此可以建立「地端部署」VM 執行個體與在 GKE 上執行的 MLLP 轉接器之間的安全連線。

    結合部署至 GKE 和 Cloud VPN

    在本教學課程的稍早部分,您在本機測試 MLLP 轉接器,並透過非 VPN 連線將 HL7v2 訊息傳送至 MLLP 轉接器。現在,您將透過使用 Cloud VPN 的安全連線,從 Compute Engine VM 傳送訊息至在 GKE 上執行的 MLLP 轉接器。然後將訊息轉送至 HL7v2 儲存庫。

    重新建立部署

    首先,請在 GKE 上重新建立部署作業,讓叢集使用您在設定 Cloud VPN 中設定的設定:

    1. 如要刪除您建立的 mllp-adapter 叢集,請執行 gcloud container clusters delete 指令。輸入您在建立叢集時使用的 COMPUTE_ZONE 值。

      gcloud container clusters delete mllp-adapter --zone=COMPUTE_ZONE
    2. 請按照「將 MLLP 轉接器部署至 Kubernetes Engine」一文中的步驟操作,但在 GKE 中建立叢集時,請新增您在「建立自訂 VPN 網路和子網路」中建立的 cloud-vpn-network 網路和 subnet-us-central-10-0-1 子網路。

      請確認叢集建立指令如下所示:

      gcloud container clusters create mllp-adapter \
         --zone=COMPUTE_ZONE \
         --service-account=CLIENT_EMAIL \
         --network=cloud-vpn-network \
         --subnetwork=subnet-us-central-10-0-1

      其中:

      • COMPUTE_ZONE 是叢集部署的區域。在上一節中設定 Cloud VPN 時,您已將「Google Cloud side」網路設為使用 us-central1。這個「Google Cloud side」網路是 GKE 叢集執行的網路。在 us-central1 中使用下列任一區域:us-central1-cus-central1-aus-central1-fus-central1-b

      • CLIENT_EMAIL 是您要使用的服務帳戶 ID。格式為 SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com。

    建立新的 Compute Engine VM 並設定網路

    下列步驟說明如何使用 Google Cloud 控制台在 Compute Engine 中建立 Linux 虛擬機器執行個體。與您建立的 Compute Engine VM 不同,這個 VM 會使用「內部部署」網路設定,透過 VPN 與 GKE 叢集通訊。

    控制台

    1. 前往 Google Cloud 控制台的「VM Instances」(VM 執行個體) 頁面

      前往「VM Instances」(VM 執行個體) 頁面

    2. 點選「建立執行個體」

    3. 為執行個體選擇與「內部」網路設定相符的區域可用區區域europe-west1 (Belgium)可用區europe-west1-b

    4. 在「開機磁碟」專區中,按一下「變更」來開始設定開機磁碟。

    5. 在「Public images」(公開映像檔) 分頁中,選擇 Debian 作業系統的 9 版。

    6. 按一下 [選取]。

    7. 在「Identity and API access」(身分及 API 存取權) 區段中,選取您建立的服務帳戶。

    8. 在「Firewall」(防火牆) 區段中,選取 [Allow HTTP traffic] (允許 HTTP 流量)

    9. 展開 [Management, security, disks, networking, sole tenancy] (管理、安全性、磁碟、網路、單獨租用) 區段。

    10. 在「Networking」分頁的「Network interfaces」下方,指定「`on-premises` (內部)」網路設定的網路詳細資料:

      1. 在「Network」(網路) 欄位中,選取「on-prem-vpn-network」
      2. 在「Subnetwork」(子網路) 欄位中,選取「subnet-europe-west-10-0-2 (10.0.2.0/24)」
    11. 按一下「建立」,建立執行個體。

    啟動執行個體會花費一些時間。當執行個體準備就緒時,將列在「VM Instances」(VM 執行個體) 頁面中,並顯示綠色的狀態圖示。

    gcloud

    如要建立運算執行個體,請搭配下列選項執行 gcloud compute instances create 方法:

    • 「內部」網路設定相符的 ZONEZoneeurope-west1-b
    • 指定 http-server 標記,允許 HTTP 流量
    • 您建立的 SERVICE_ACCOUNT
    gcloud compute instances create COMPUTE_NAME \
       --project=PROJECT_ID
       --zone=ZONE
       --image-family=debian-10 \
       --tags=http-server,https-server
       --service-account=SERVICE_ACCOUNT

    輸出結果會與下列範例類似:

    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

    如要連線至執行個體,請完成下列步驟:

    控制台

    1. 前往 Google Cloud 控制台的「VM Instances」(VM 執行個體) 頁面

      前往「VM Instances」(VM 執行個體) 頁面

    2. 在虛擬機器執行個體清單中,按一下您建立的執行個體列中的「SSH」SSH

    gcloud

    如要連線至執行個體,請執行 gcloud compute ssh 指令:

    gcloud compute ssh INSTANCE_NAME \
        --project PROJECT_ID \
        --zone ZONE

    您現在擁有一個終端機視窗,可讓您與 Linux 執行個體互動。

    1. 在終端機視窗中,安裝 Netcat

      sudo apt install netcat
      
    2. 下載 hl7v2-mllp-sample.txt 檔案並儲存到執行個體。

    3. 如要開始透過 MLLP 轉接器將 HL7v2 訊息傳送至 HL7v2 儲存庫,請在下載檔案的目錄中執行下列指令。使用檢查服務時顯示的 LoadBalancer Ingress 值。

      echo -n -e "\x0b$(cat hl7v2-mllp-sample.txt)\x1c\x0d" | nc LOAD_BALANCER_INGRESS_IP_ADDRESS 2575

      執行指令後,系統會透過 MLLP 轉接器將訊息傳送至 HL7v2 儲存庫。如果訊息已成功擷取至 HL7v2 儲存庫,指令會傳回以下輸出內容:

      MSA|AA|20150503223000|ILITY|FROM_APP|FROM_FACILITY|20190312162410||ACK|f4c59243-19c2-4373-bea0-39c1b2ba616b|P|2.5
      

      這項輸出內容表示 HL7v2 儲存庫已以 AA (Application Accept) 回應類型回應,代表訊息已通過驗證並成功攝入。

    4. 如要查看已發布至 Pub/Sub 主題的訊息,請執行 gcloud pubsub subscriptions pull 指令:

      gcloud pubsub subscriptions pull --auto-ack PUBSUB_SUBSCRIPTION

      指令會傳回以下關於擷取的 HL7v2 訊息輸出內容:

      ┌-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┐
      |                                                               DATA                                              |    MESSAGE_ID   |   ATTRIBUTES  |
      ├-----------------------------------------------------------------------------------------------------------------|-----------------|---------------|
      | projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/HL7V2_MESSAGE_ID | 123456789012345 | msgType=ADT   |
      └-----------------------------------------------------------------------------------------------------------------|-----------------|---------------┘
    5. 您也可以在 HL7v2 儲存庫中列出訊息,查看是否已新增訊息:

      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"

      如果要求成功,伺服器會以資源路徑傳回訊息的 ID:

      {
        "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

      如果要求成功,伺服器會以資源路徑傳回訊息 ID:

      {
        "hl7V2Messages": [
          {
            "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/MESSAGE_ID"
          }
        ]
      }
      

    完成本節後,您已成功將 MLLP 轉接器部署至 GKE,並透過 VPN 從「內部部署」執行個體透過轉接器安全地傳送 HL7v2 訊息至 Cloud Healthcare API。

    清除所用資源

    為避免系統向您的 Google Cloud 帳戶收取您在本教學課程中使用資源的費用,您可以清除在Google Cloud上建立的資源。

    刪除專案

    請按照下列步驟刪除您在本教學課程中建立的專案:

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    疑難排解

    轉接器故障

    將 MLLP 轉接程式部署至 GKE 後,轉接程式發生錯誤。

    在本機執行時發生 Connection refused 錯誤

    在本機測試 MLLP 轉接程式時,您遇到 Connection refused 錯誤。

    • 部分 Mac OS 使用者會發生這個錯誤。請改用 -p 2575:2575,而非 --network=host 旗標。此外,請將 --receiver_ip=0.0.0.0 設為 --receiver_ip=0.0.0.0,而非 --receiver_ip=127.0.0.0。指令應如下所示:

      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

    在本機執行時發生 could not find default credentials 錯誤

    在本機測試 MLLP 轉接器時,您會遇到 healthapiclient.NewHL7V2Client: oauth2google.DefaultTokenSource: google: could not find default credentials. 錯誤。

    當轉接程式找不到您的本機 ADC 憑證時,就會發生這個錯誤。確認您已在本機環境中設定應用程式預設憑證

    驗證錯誤

    如果您在本機測試 MLLP 轉接器時遇到任何驗證錯誤,且未在本節的其他部分中說明,請重新執行 docker run 指令,並在指令結尾加上 -v ~/.config:/root/.config 標記,如下所示:

    docker run \
    -v ~/.config:/root/.config \
    ...