TCP/IP ์—ฐ๊ฒฐ์„ ํ†ตํ•ด HL7v2 ๋ฉ”์‹œ์ง€ ์ „์†ก

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” Minimal Lower Layer Protocol(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

ํ”„๋กœ์ ํŠธ ์‚ฌ์šฉ๋Ÿ‰์„ ๊ธฐ์ค€์œผ๋กœ ์˜ˆ์ƒ ๋น„์šฉ์„ ์‚ฐ์ถœํ•˜๋ ค๋ฉด ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Google Cloud ์‹ ๊ทœ ์‚ฌ์šฉ์ž๋Š” ๋ฌด๋ฃŒ ์ฒดํ—˜ํŒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๊ธฐ ์ „์—

์ด ํŠœํ† ๋ฆฌ์–ผ์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— MLLP ๋ฐ Google Cloud MLLP ์–ด๋Œ‘ํ„ฐ๋ฅผ ๊ฒ€ํ† ํ•˜์—ฌ Minimal Lower Layer Protocol(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. Verify 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. Verify 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 ๋ฐ ๊ด€๋ จ ์„œ๋น„์Šค๊ฐ€ ์‚ฌ์šฉ ์„ค์ •๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ๋ช‡ ๋ถ„ ์ •๋„ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์…ธ ์„ ํƒ

์ด ํŠœํ† ๋ฆฌ์–ผ์„ ์™„๋ฃŒํ•˜๋ ค๋ฉด Cloud Shell ๋˜๋Š” ๋กœ์ปฌ ์…ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Cloud Shell์€ Google Cloud์—์„œ ํ˜ธ์ŠคํŒ…๋˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์…ธ ํ™˜๊ฒฝ์ž…๋‹ˆ๋‹ค. Cloud Shell์—๋Š” gcloud CLI ๋ฐ kubectl ๋„๊ตฌ๊ฐ€ ์‚ฌ์ „ ์„ค์น˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. 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 ์„ธ์…˜์ด ์ฝ˜์†” ์•„๋ž˜์ชฝ ํ”„๋ ˆ์ž„ ์•ˆ์—์„œ ์—ด๋ฆฝ๋‹ˆ๋‹ค. ์ด ์…ธ์„ ์‚ฌ์šฉํ•˜์—ฌ gcloud ๋ฐ kubectl ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋กœ์ปฌ ์…ธ

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 ์ฝ˜์†”์—์„œ ๋ฐ์ดํ„ฐ ์„ธํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    ๋ฐ์ดํ„ฐ ์„ธํŠธ๋กœ ์ด๋™

  2. ๋ฐ์ดํ„ฐ ์„ธํŠธ ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  3. ์ด๋ฆ„ ํ•„๋“œ์— ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ์‹๋ณ„์ž๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์„ธํŠธ ID์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ํ•ด๋‹น ์œ„์น˜์˜ ๊ณ ์œ  ID
    • ๋‹ค์Œ์œผ๋กœ ๊ตฌ์„ฑ๋œ 1~256์ž์˜ ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž์—ด:
      • ์ˆซ์ž
      • ํŽธ์ง€
      • ๋ฐ‘์ค„
      • ๋Œ€์‹œ
      • ๋งˆ์นจํ‘œ
  4. ์œ„์น˜ ์œ ํ˜• ์„น์…˜์—์„œ ๋‹ค์Œ ์œ„์น˜ ์œ ํ˜• ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฆฌ์ „: ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ Google Cloud ๋ฆฌ์ „ ํ•˜๋‚˜ ๋‚ด์— ์˜๊ตฌ์ ์œผ๋กœ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ํƒํ•œ ํ›„ ๋ฆฌ์ „ ํ•„๋“œ์— ์œ„์น˜๋ฅผ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฉ€ํ‹ฐ ๋ฆฌ์ „: ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ์—ฌ๋Ÿฌ Google Cloud ๋ฆฌ์ „์— ๊ฑธ์ณ ์žˆ๋Š” ํ•˜๋‚˜์˜ ์œ„์น˜ ๋‚ด์— ์˜๊ตฌ์ ์œผ๋กœ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ํƒํ•œ ํ›„ ๋ฉ€ํ‹ฐ ๋ฆฌ์ „ ํ•„๋“œ์— ๋ฉ€ํ‹ฐ ๋ฆฌ์ „ ์œ„์น˜๋ฅผ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  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. ์ฃผ์ œ ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  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. ๊ตฌ๋… ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  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 ํŽ˜์ด์ง€์—์„œ Healthcare ์„œ๋น„์Šค ์—์ด์ „ํŠธ ์—ญํ• ์ด ๊ด€๋ จ ํ”„๋กœ์ ํŠธ ์„œ๋น„์Šค ๊ณ„์ •์˜ ์—ญํ•  ์—ด์— ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์ • ์ด๋ฆ„์€ service-PROJECT_NUMBER@gcp-sa-healthcare.iam.gserviceaccount.com์ž…๋‹ˆ๋‹ค. PROJECT_NUMBER ์ฐพ๊ธฐ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ”„๋กœ์ ํŠธ ์‹๋ณ„์„ ์ฐธ์กฐํ•˜์„ธ์š”.

  2. ์—ญํ• ๊ณผ ์ผ์น˜ํ•˜๋Š” ์ƒ์† ์—ด์—์„œ ์—ฐํ•„ ์•„์ด์ฝ˜์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ๊ถŒํ•œ ์ˆ˜์ • ์ฐฝ์ด ์—ด๋ฆฝ๋‹ˆ๋‹ค.

  3. ๋‹ค๋ฅธ ์—ญํ•  ์ถ”๊ฐ€๋ฅผ ํด๋ฆญํ•œ ๋‹ค์Œ Pub/Sub ๊ฒŒ์‹œ์ž ์—ญํ• ์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

  4. ์—ญํ• ์„ ์„ ํƒํ•˜๊ณ  ์ €์žฅ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. pubsub.publisher ์—ญํ• ์ด ์„œ๋น„์Šค ๊ณ„์ •์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

gcloud

์„œ๋น„์Šค ๊ณ„์ • ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด gcloud projects add-iam-policy-binding ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. PROJECT_ID ๋ฐ PROJECT_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 ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ HL7v2 ์ €์žฅ์†Œ์— ์ˆ˜์ง‘ํ•˜๋„๋ก messages.ingest๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ, Pub/Sub ์•Œ๋ฆผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ์•Œ๋ฆผ์€ HL7v2 ์ €์žฅ์†Œ์˜ Pub/Sub ์ฃผ์ œ๋ฅผ ๊ตฌ๋…ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.
  • ์–ด๋Œ‘ํ„ฐ๊ฐ€ ๊ฒŒ์‹œ์ž๋กœ ์‹คํ–‰๋  ๋•Œ๋Š” messages.create ๋˜๋Š” messages.ingest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HL7v2 ์ €์žฅ์†Œ์— ์ƒ์„ฑ๋˜์—ˆ๊ฑฐ๋‚˜ ์ˆ˜์ง‘๋œ HL7v2 ๋ฉ”์‹œ์ง€๋ฅผ ๋ฆฌ์Šจํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€๊ฐ€ ์ƒ์„ฑ๋œ ๋‹ค์Œ์—๋Š” Pub/Sub ์•Œ๋ฆผ์ด ์–ด๋Œ‘ํ„ฐ๋กœ ์ „์†ก๋˜๊ณ  ์–ด๋Œ‘ํ„ฐ๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ์™ธ๋ถ€ ์ˆ˜์‹ ์ž์— ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์ˆ˜์‹ ์ž ๋˜๋Š” ๊ฒŒ์‹œ์ž ์—ญํ• ์„ ํ•˜๋„๋ก ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋กœ์ปฌ ๋จธ์‹ ์—์„œ MLLP ์–ด๋Œ‘ํ„ฐ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•œ ํ›„์—๋Š” Google Kubernetes Engine์— MLLP ์–ด๋Œ‘ํ„ฐ ๋ฐฐํฌ์— ๊ด€ํ•œ ๋‹ค์Œ ์„น์…˜์„ ๊ณ„์† ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋กœ์ปฌ์—์„œ 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์ž…๋‹ˆ๋‹ค.

    ์ด์ „ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ์–ด๋Œ‘ํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ํฌํŠธ 2575์˜ 127.0.0.1 IP ์ฃผ์†Œ์—์„œ ๋กœ์ปฌ ๋จธ์‹ ์—์„œ ์‹คํ–‰๋˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

    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.create ๋˜๋Š” messages.ingest๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋ฉ”์‹œ์ง€ ํŒŒ์ผ์„ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋กœ ์ œ๊ณตํ•˜์—ฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์–ด๋Œ‘ํ„ฐ๊ฐ€ messages.create ๋ฐ messages.ingest๋ฅผ ํ†ตํ•ด ์ „์†ก๋œ Pub/Sub ๋ฉ”์‹œ์ง€๋ฅผ ์ž๋™์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์–ด๋Œ‘ํ„ฐ๊ฐ€ Pub/Sub ๋ฉ”์‹œ์ง€๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์ธ์ถœํ•˜๊ณ  ์ „์†กํ•˜๋ฉด ์•Œ๋ฆผ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์–ด๋Œ‘ํ„ฐ๊ฐ€ Pub/Sub ๊ตฌ๋…์ž์ด๋ฏ€๋กœ ์ด๋Ÿฌํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ž๋™์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์–ด๋Œ‘ํ„ฐ๋กœ ๊ตฌ์„ฑํ•œ Pub/Sub ๊ตฌ๋…์˜ ๋ฉ”์‹œ์ง€ ํ์—์„œ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

Pub/Sub ๊ตฌ๋…์—์„œ ๊ฐ€์ ธ์˜ค๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ๊ฒŒ์‹œ๋˜์—ˆ๋Š”์ง€ ๋ณ„๋„๋กœ ํ™•์ธํ•˜๋ ค๋ฉด ์ด์ „์— ๋งŒ๋“  ์ฃผ์ œ์— ํ• ๋‹น๋œ ๋‘ ๋ฒˆ์งธ Pub/Sub ๊ตฌ๋…์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ๊ตฌ๋…์œผ๋กœ ์ „์†ก๋œ ๋ฉ”์‹œ์ง€๋Š” ์–ด๋Œ‘ํ„ฐ์—์„œ ์ž๋™์œผ๋กœ ํ™•์ธ๋˜์ง€ ์•Š๊ณ  ๊ณ„์† ์œ ์ง€๋˜๋ฏ€๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ „์— ๋งŒ๋“  ์ฃผ์ œ์— ํ• ๋‹น๋œ ๋‘ ๋ฒˆ์งธ Pub/Sub ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•˜์„ธ์š”.

์ฝ˜์†”

  1. Google Cloud ์ฝ˜์†”์—์„œ Pub/Sub ์ฃผ์ œ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    Pub/Sub ์ฃผ์ œ ํŽ˜์ด์ง€๋กœ ์ด๋™

  2. ํ”„๋กœ์ ํŠธ ์ฃผ์ œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์ตœ์ดˆ ๊ตฌ๋…์„ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•œ ์ฃผ์ œ์ž…๋‹ˆ๋‹ค.

  3. ๊ตฌ๋… ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  4. ๊ตฌ๋… ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    projects/PROJECT_ID/subscriptions/SECOND_SUBSCRIPTION_NAME

    ์ „์†ก ์œ ํ˜•์„ ๊ฐ€์ ธ์˜ค๊ธฐ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  5. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

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 ์ฃผ์ œ์™€ ์—ฐ๊ฒฐ๋˜์–ด ๋งŒ๋“  ์ฒซ ๋ฒˆ์งธ ๊ตฌ๋… ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ์–ด๋Œ‘ํ„ฐ๋Š” ์ด ๊ตฌ๋…์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์†Œ๋น„ํ•˜๊ณ  ์ž๋™์œผ๋กœ ํ™•์ธํ•˜๋ฏ€๋กœ ์ฃผ์ œ์— ๊ฒŒ์‹œ๋œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋ ค๋ฉด ์ด์ „์— ๋งŒ๋“  ๋‘ ๋ฒˆ์งธ ๊ตฌ๋…์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ์ด์ „ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ์–ด๋Œ‘ํ„ฐ๋Š” ํฌํŠธ 2575์˜ 127.0.0.1 IP ์ฃผ์†Œ์—์„œ ๋กœ์ปฌ ๋จธ์‹ ์—์„œ ์‹คํ–‰๋˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

    ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋‹ค์Œ ๋ฌธ์ œ ํ•ด๊ฒฐ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

    ์–ด๋Œ‘ํ„ฐ๋Š” ํฌ๊ทธ๋ผ์šด๋“œ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ๊ณ„์†ํ•˜๋ ค๋ฉด ๋กœ์ปฌ ๋จธ์‹ ์—์„œ ๋‹ค๋ฅธ ํ„ฐ๋ฏธ๋„์„ ์—ฝ๋‹ˆ๋‹ค.

  6. hl7v2-sample.json ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์ด๋ฅผ ๋กœ์ปฌ ๋จธ์‹ ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•œ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ messages.create ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ HL7v2 ์ €์žฅ์†Œ์— ๋ฉ”์‹œ์ง€๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    curl

    HL7v2 ๋ฉ”์‹œ์ง€๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด POST ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋‹ค์Œ ์ •๋ณด๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

    • ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ์ด๋ฆ„
    • HL7v2 ์ €์žฅ์†Œ์˜ ์ด๋ฆ„
    • ๋ฉ”์‹œ์ง€
    • ์•ก์„ธ์Šค ํ† ํฐ

    ๋‹ค์Œ ์ƒ˜ํ”Œ์€ curl์„ ์‚ฌ์šฉํ•˜๋Š” POST ์š”์ฒญ๊ณผ 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 ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•ด ๋‹ค์Œ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€๊ฐ€ Pub/Sub์— ๊ฒŒ์‹œ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ATTRIBUTES ์—ด์˜ publish=true ๊ฐ’์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    โ”Œ-----------------------------------------------------------------------------------------------------------------|-----------------|---------------โ”
    |                                                               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  |
    โ””-----------------------------------------------------------------------------------------------------------------|-----------------|---------------โ”˜

๋‹ค๋ฅธ ์™ธ๋ถ€ ์ˆ˜์‹ ์ž์— ๋ฉ”์‹œ์ง€ ๊ฒŒ์‹œ

์—ฌ๋Ÿฌ Pub/Sub ์ฃผ์ œ๋กœ HL7v2 ์ €์žฅ์†Œ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„œ๋กœ ๋‹ค๋ฅธ Pub/Sub ์ฃผ์ œ๋กœ ์•Œ๋ฆผ์„ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ํ›„ ๊ฐ Pub/Sub ์ฃผ์ œ์— ๋Œ€ํ•ด MLLP ์–ด๋Œ‘ํ„ฐ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์„œ๋กœ ๋‹ค๋ฅธ ์™ธ๋ถ€ ์ˆ˜์‹ ์ž์— ๋ฉ”์‹œ์ง€๋ฅผ ๊ฒŒ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ Pub/Sub ์ฃผ์ œ์™€ ๊ฐ ์ฃผ์ œ์— ๋Œ€ํ•œ ํ•„ํ„ฐ๋กœ HL7v2 ์ €์žฅ์†Œ๋ฅผ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

  1. Pub/Sub ์ฃผ์ œ๋ฅผ 2๊ฐœ ๋งŒ๋“ค๊ณ  ๊ฐ ์ฃผ์ œ์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ๊ตฌ๋…์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ 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 ์ €์žฅ์†Œ์˜ ์ด๋ฆ„
    • ๋ฉ”์‹œ์ง€
    • ์•ก์„ธ์Šค ํ† ํฐ

    ๋‹ค์Œ ์ƒ˜ํ”Œ์€ curl์„ ์‚ฌ์šฉํ•˜๋Š” POST ์š”์ฒญ๊ณผ hl7v2-sample1.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-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 ์ €์žฅ์†Œ์˜ ์ด๋ฆ„
    • ๋ฉ”์‹œ์ง€
    • ์•ก์„ธ์Šค ํ† ํฐ

    ๋‹ค์Œ ์ƒ˜ํ”Œ์€ curl์„ ์‚ฌ์šฉํ•˜๋Š” POST ์š”์ฒญ๊ณผ hl7v2-sample2.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-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 ์š”์ฒญ๊ณผ hl7v2-sample2.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-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 ๊ฐ’๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

Google Kubernetes Engine์— MLLP ์–ด๋Œ‘ํ„ฐ ๋ฐฐํฌ

๊ด€๋ฆฌ ์„ผํ„ฐ์—์„œ MLLP๋ฅผ ํ†ตํ•ด HL7v2 ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•  ๋•Œ Google Cloud์— ๋ฐฐํฌ๋œ ์–ด๋Œ‘ํ„ฐ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜์—ฌ Cloud Healthcare API๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

MLLP ์–ด๋Œ‘ํ„ฐ๋Š” GKE ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์Šคํ…Œ์ดํŠธ๋ฆฌ์Šค(Stateless) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. GKE ํด๋Ÿฌ์Šคํ„ฐ๋Š” ์ปจํ…Œ์ด๋„ˆ์‹ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๊ด€๋ฆฌํ˜• VM ์ธ์Šคํ„ด์Šค ๊ทธ๋ฃน์ž…๋‹ˆ๋‹ค. ์Šคํ…Œ์ดํŠธ๋ฆฌ์Šค(Stateless) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ฐ์ดํ„ฐ ๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ ๋˜๋Š” ์˜๊ตฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜์ง€ ์•Š๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค. ๋Œ€์‹  ๋ฐ์ดํ„ฐ ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์— ์œ ์ง€๋˜๋ฏ€๋กœ, ์Šคํ…Œ์ดํŠธ๋ฆฌ์Šค(Stateless) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํ™•์žฅ์„ฑ์ด ๋” ๋›ฐ์–ด๋‚ฉ๋‹ˆ๋‹ค.

GKE๋Š” ๋ฐฐํฌ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํ…Œ์ดํŠธ๋ฆฌ์Šค(Stateless) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹จ์ผ์˜ ๋น„๊ณ ์œ  ํฌ๋“œ๋กœ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐํฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•  ํฌ๋“œ ์ˆ˜, ์‹คํ–‰ํ•  ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋ฒ„์ „, ๋ผ๋ฒจ์„ ์ง€์ •ํ•  ํฌ๋“œ ๋“ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์›ํ•˜๋Š” ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐํฌ์˜ ํฌ๋“œ ์‚ฌ์–‘์„ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ์›ํ•˜๋Š” ์ƒํƒœ๋ฅผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋Œ‘ํ„ฐ๋ฅผ ๋ฐฐํฌํ•˜๋Š” ๋™์‹œ์— ๋‚ด๋ถ€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ Cloud Healthcare API์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋น„์Šค ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GKE๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ œํ’ˆ ์ž‘๋™ ๋ฐฉ์‹์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋Š” GKE ๋น ๋ฅธ ์‹œ์ž‘์„ ์™„๋ฃŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

GKE ์„œ๋น„์Šค ๊ณ„์ •์— Pub/Sub API ๊ถŒํ•œ ์ถ”๊ฐ€

์„œ๋น„์Šค ๊ณ„์ •์œผ๋กœ Cloud Platform์— ์ธ์ฆ์— ๋Œ€ํ•œ GKE ๋ฌธ์„œ์— ์„ค๋ช…๋œ ๋Œ€๋กœ ์ปจํ…Œ์ด๋„ˆ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๊ฐ ๋…ธ๋“œ๋Š” Compute Engine ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ MLLP ์–ด๋Œ‘ํ„ฐ๋Š” ์ปจํ…Œ์ด๋„ˆ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์‹คํ–‰๋˜๋ฉด ๋ฐฐํฌ๋œ Compute Engine ์ธ์Šคํ„ด์Šค์˜ ๋ฒ”์œ„๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์†ํ•ฉ๋‹ˆ๋‹ค.

Google Cloud๋Š” 'Compute Engine ๊ธฐ๋ณธ ์„œ๋น„์Šค ๊ณ„์ •'์ด๋ผ๋Š” ์„œ๋น„์Šค ๊ณ„์ •์„ ์ž๋™์œผ๋กœ ๋งŒ๋“ค๊ณ  ์ด ์„œ๋น„์Šค ๊ณ„์ •์„ GKE๊ฐ€ ๋งŒ๋“  ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ๊ธฐ๋ณธ ์„œ๋น„์Šค ๊ณ„์ •์— ๋‹ค๋ฅธ Cloud Platform API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์ด ํฌํ•จ๋˜๊ฑฐ๋‚˜ ํฌํ•จ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. GKE๋Š” ๋˜ํ•œ ์ผ๋ถ€ ์ œํ•œ๋œ ์•ก์„ธ์Šค ๋ฒ”์œ„๋ฅผ Compute Engine ์ธ์Šคํ„ด์Šค์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

์ตœ์ƒ์˜ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ธฐ๋ณธ ์„œ๋น„์Šค ๊ณ„์ •์˜ ๊ถŒํ•œ์„ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ Compute Engine ์ธ์Šคํ„ด์Šค์— ์ถ”๊ฐ€ ์•ก์„ธ์Šค ๋ฒ”์œ„๋ฅผ ํ• ๋‹นํ•˜์—ฌ GKE์—์„œ ์‹คํ–‰๋˜๋Š” ํฌ๋“œ์—์„œ ๋‹ค๋ฅธ Google Cloud ์„œ๋น„์Šค(์˜ˆ: Pub/Sub)์— ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋งˆ์„ธ์š”. ๋Œ€์‹  ์ž์ฒด ์„œ๋น„์Šค ๊ณ„์ •์„ ๋งŒ๋“œ์„ธ์š”.

ํ•„์š”ํ•œ Pub/Sub ๊ถŒํ•œ์„ ์ปจํ…Œ์ด๋„ˆ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ถ€์—ฌํ•ด์•ผ ํ•˜์ง€๋งŒ Cloud Monitoring์— ์ธก์ •ํ•ญ๋ชฉ์„ ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ๋„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ํด๋Ÿฌ์Šคํ„ฐ์— ํ•„์š”ํ•œ ๋ฒ”์œ„๋งŒ ํฌํ•จํ•˜๋Š” ์ƒˆ ์„œ๋น„์Šค ๊ณ„์ •์„ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•˜์„ธ์š”.

์ฝ˜์†”

์„œ๋น„์Šค ๊ณ„์ •์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  1. Google Cloud ์ฝ˜์†”์—์„œ ์„œ๋น„์Šค ๊ณ„์ • ๋งŒ๋“ค๊ธฐ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    ์„œ๋น„์Šค ๊ณ„์ • ๋งŒ๋“ค๊ธฐ๋กœ ์ด๋™

  2. ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  3. ์„œ๋น„์Šค ๊ณ„์ • ์ด๋ฆ„ ํ•„๋“œ์— ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. Google Cloud ์ฝ˜์†”์€ ์ด ์ด๋ฆ„์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„œ๋น„์Šค ๊ณ„์ • ID ํ•„๋“œ๋ฅผ ์ฑ„์›๋‹ˆ๋‹ค.

    ์„ ํƒ์‚ฌํ•ญ: ์„œ๋น„์Šค ๊ณ„์ • ์„ค๋ช… ํ•„๋“œ์— ์„ค๋ช…์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  4. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  5. ์—ญํ•  ์„ ํƒ ํ•„๋“œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    ๋ชจ๋“  ์—ญํ• ์—์„œ Pub/Sub > Pub/Sub ๊ตฌ๋…์ž๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  6. ๋‹ค๋ฅธ ์—ญํ•  ์ถ”๊ฐ€๋ฅผ ํด๋ฆญํ•œ ๋‹ค์Œ ์—ญํ•  ์„ ํƒ ํ•„๋“œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    ๋ชจ๋“  ์—ญํ• ์—์„œ Cloud Healthcare > Healthcare HL7v2 ๋ฉ”์‹œ์ง€ ์ˆ˜์ง‘์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  7. ์„ ํƒ์‚ฌํ•ญ: ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์‚ฌ์šฉ ์„ค์ •ํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ์—ญํ•  ์ถ”๊ฐ€๋ฅผ ํด๋ฆญํ•œ ๋‹ค์Œ ์—ญํ•  ์„ ํƒ ํ•„๋“œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    ๋ชจ๋“  ์—ญํ• ์—์„œ ๋ชจ๋‹ˆํ„ฐ๋ง > ๋ชจ๋‹ˆํ„ฐ๋ง ์ธก์ •ํ•ญ๋ชฉ ์ž‘์„ฑ์ž๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  8. ๊ณ„์†์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  9. ์™„๋ฃŒ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์„œ๋น„์Šค ๊ณ„์ • ๋งŒ๋“ค๊ธฐ๋ฅผ ๋งˆ์นฉ๋‹ˆ๋‹ค.

    ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์„ ๋‹ซ์ง€ ๋งˆ์„ธ์š”. ๋‹ค์Œ ์ ˆ์ฐจ์—์„œ ์ด ์ฐฝ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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-a๋Š” us-west ๋ฆฌ์ „์— ์žˆ๋Š” ํ•œ ์˜์—ญ์ž…๋‹ˆ๋‹ค. gcloud config set compute/zone์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ ์˜์—ญ์„ ์„ค์ •ํ•œ ๊ฒฝ์šฐ ์ด ํ”Œ๋ž˜๊ทธ์˜ ๊ฐ’์ด ๊ธฐ๋ณธ๊ฐ’์„ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • CLIENT_EMAIL์€ ์‚ฌ์šฉํ•  ์„œ๋น„์Šค ๊ณ„์ •์˜ ์‹๋ณ„์ž์ž…๋‹ˆ๋‹ค. 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๋Š” 3๊ฐœ์˜ 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:๋Š” ๋ฐฐํฌ์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ณต์ œ๋œ ํฌ๋“œ ์ˆ˜์ž…๋‹ˆ๋‹ค.
  • spec: template: metadata: labels:๋Š” ๋ฐฐํฌ์—์„œ ํฌ๋“œ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฐ ํฌ๋“œ์— ์ง€์ •๋œ ๋ผ๋ฒจ์ž…๋‹ˆ๋‹ค.
  • spec: template: spec:์€ ๊ฐ ํฌ๋“œ์˜ ์‹คํ–‰ ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•˜๋Š” ํฌ๋“œ ์‚ฌ์–‘์ž…๋‹ˆ๋‹ค.
  • spec: containers์—๋Š” ๊ฐ ํฌ๋“œ์—์„œ ์‹คํ–‰ํ•  ์ปจํ…Œ์ด๋„ˆ์˜ ์ด๋ฆ„๊ณผ ์‹คํ–‰ํ•  ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ ์‚ฌ์–‘์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Deployment API ์ฐธ์กฐ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

์„œ๋น„์Šค ๊ตฌ์„ฑ

ํด๋Ÿฌ์Šคํ„ฐ ์™ธ๋ถ€์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์˜ˆ: ๊ด€๋ฆฌ ์„ผํ„ฐ)์—์„œ MLLP ์–ด๋Œ‘ํ„ฐ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด ๋‚ด๋ถ€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

VPN์„ ๊ตฌ์„ฑํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋™์ผํ•œ VPC ๋„คํŠธ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋™์ผํ•œ Google Cloud ๋ฆฌ์ „์— ์žˆ๋Š” ๊ฒฝ์šฐ ๋‚ด๋ถ€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ํ†ตํ•ด MLLP ์–ด๋Œ‘ํ„ฐ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋™์ผํ•œ ๋ฆฌ์ „ ๋ฐ ๋™์ผํ•œ VPC ๋„คํŠธ์›Œํฌ์˜ Compute Engine VM ์ธ์Šคํ„ด์Šค์—์„œ ์–ด๋Œ‘ํ„ฐ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ํด๋Ÿฌ์Šคํ„ฐ์˜ ์„œ๋น„์Šค ๋ฆฌ์†Œ์Šค์— ๋‚ด๋ถ€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฐํฌ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์„ ๋งŒ๋“  ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ ์ฝ˜ํ…์ธ ๊ฐ€ ํฌํ•จ๋œ 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:๋Š” ์„œ๋น„์Šค๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฐ ํฌ๋“œ์˜ ํฌํŠธ๋ฅผ ์ง€์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • spec: selector: app:๋Š” ์„œ๋น„์Šค๊ฐ€ ํƒ€๊ฒŸํŒ…ํ•˜๋Š” ํฌ๋“œ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

clusterIP ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ์˜ IP ์ฃผ์†Œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ์ž์ฒด IP ์ฃผ์†Œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์ด ํŠœํ† ๋ฆฌ์–ผ์˜ ๋’ท๋ถ€๋ถ„์—์„œ ์‚ฌ์šฉํ•˜๋Š” IP ์ฃผ์†Œ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๋ถ€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ GKE ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์„œ๋น„์Šค ์‚ฌ์–‘์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์„œ๋น„์Šค API ์ฐธ์กฐ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

๋ฐฐํฌ ์ค€๋น„

GKE ํด๋Ÿฌ์Šคํ„ฐ์— ์–ด๋Œ‘ํ„ฐ๋ฅผ ๋ฐฐํฌํ•˜๋ ค๋ฉด mllp_adapter.yaml ๋ฐฐํฌ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์ด ํฌํ•จ๋œ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

kubectl apply -f mllp_adapter.yaml

์ด ๋ช…๋ น์–ด๋Š” ๋‹ค์Œ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

deployment.extensions "mllp-adapter-deployment" created

๋ฐฐํฌ ๊ฒ€์‚ฌ

๋ฐฐํฌ๋ฅผ ๋งŒ๋“  ํ›„ kubectl ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐํฌ๋ฅผ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฐํฌ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

kubectl describe deployment mllp-adapter

๋ฐฐํฌ์—์„œ ๋งŒ๋“  ํฌ๋“œ๋ฅผ ๋‚˜์—ดํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

kubectl get pods -l app=mllp-adapter

์ƒ์„ฑ๋œ ํฌ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด ๋‹ค์Œ ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

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 ์ฃผ์†Œ๊ฐ€ ์ฑ„์›Œ์ง€๋Š” ๋ฐ ์ตœ๋Œ€ 1๋ถ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ ์ด IP ์ฃผ์†Œ์™€ 2575 ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋Ÿฌ์Šคํ„ฐ ์™ธ๋ถ€์—์„œ ์„œ๋น„์Šค์— ์•ก์„ธ์Šคํ•ฉ๋‹ˆ๋‹ค.

Compute Engine VM ๋งŒ๋“ค๊ธฐ ๋ฐ ๋ฉ”์‹œ์ง€ ์ „์†ก

์ด ํŠœํ† ๋ฆฌ์–ผ ์•ž๋ถ€๋ถ„์—์„œ MLLP ์–ด๋Œ‘ํ„ฐ๋ฅผ ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธํ•˜๊ณ  HL7v2 ๋ฉ”์‹œ์ง€๋ฅผ HL7v2 ์ €์žฅ์†Œ๋กœ ๋ณด๋ƒˆ์ง€๋งŒ ์ด์ œ Compute Engine VM์—์„œ GKE์—์„œ ์‹คํ–‰๋˜๋Š” MLLP ์–ด๋Œ‘ํ„ฐ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฉ”์‹œ์ง€๊ฐ€ HL7v2 ์ €์žฅ์†Œ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

์ƒˆ ์ธ์Šคํ„ด์Šค์—์„œ GKE ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋ ค๋ฉด ์ธ์Šคํ„ด์Šค์™€ ๊ธฐ์กด ์ธ์Šคํ„ด์Šค๊ฐ€ ๋™์ผํ•œ ๋ฆฌ์ „์— ์žˆ๊ณ  ๋™์ผํ•œ VPC ๋„คํŠธ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ์„น์…˜ ๋์—์„œ๋Š” Pub/Sub ์ฃผ์ œ์— ๊ฒŒ์‹œ๋œ ์•Œ๋ฆผ๊ณผ HL7v2 ์ €์žฅ์†Œ์˜ HL7v2 ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜์—ด๋ฉ๋‹ˆ๋‹ค. Compute Engine VM ์ธ์Šคํ„ด์Šค์—๋Š” ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์ด ๋ถ€์—ฌ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์ „์— ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•˜์—ฌ ํ•„์š”ํ•œ ๊ถŒํ•œ์œผ๋กœ ์ƒˆ ์„œ๋น„์Šค ๊ณ„์ •์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ฝ˜์†”

์„œ๋น„์Šค ๊ณ„์ •์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  1. Google Cloud ์ฝ˜์†”์—์„œ ์„œ๋น„์Šค ๊ณ„์ • ๋งŒ๋“ค๊ธฐ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    ์„œ๋น„์Šค ๊ณ„์ • ๋งŒ๋“ค๊ธฐ๋กœ ์ด๋™

  2. ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  3. ์„œ๋น„์Šค ๊ณ„์ • ์ด๋ฆ„ ํ•„๋“œ์— ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. Google Cloud ์ฝ˜์†”์€ ์ด ์ด๋ฆ„์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„œ๋น„์Šค ๊ณ„์ • ID ํ•„๋“œ๋ฅผ ์ฑ„์›๋‹ˆ๋‹ค.

    ์„ ํƒ์‚ฌํ•ญ: ์„œ๋น„์Šค ๊ณ„์ • ์„ค๋ช… ํ•„๋“œ์— ์„ค๋ช…์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  4. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  5. ์—ญํ•  ์„ ํƒ ํ•„๋“œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    ๋ชจ๋“  ์—ญํ• ์—์„œ Pub/Sub > Pub/Sub ๊ตฌ๋…์ž๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  6. ๋‹ค๋ฅธ ์—ญํ•  ์ถ”๊ฐ€๋ฅผ ํด๋ฆญํ•œ ๋‹ค์Œ ์—ญํ•  ์„ ํƒ ํ•„๋“œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    ๋ชจ๋“  ์—ญํ• ์—์„œ Cloud Healthcare > Healthcare HL7v2 ๋ฉ”์‹œ์ง€ ์†Œ๋น„์ž๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  7. ๊ณ„์†์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  8. ์™„๋ฃŒ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์„œ๋น„์Šค ๊ณ„์ • ๋งŒ๋“ค๊ธฐ๋ฅผ ๋งˆ์นฉ๋‹ˆ๋‹ค.

    ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์„ ๋‹ซ์ง€ ๋งˆ์„ธ์š”. ๋‹ค์Œ ์ ˆ์ฐจ์—์„œ ์ด ์ฐฝ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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 Console์—์„œ VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™

  2. ์ธ์Šคํ„ด์Šค ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  3. ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋งŒ๋“ค ๋•Œ ์„ ํƒํ•œ ์˜์—ญ๊ณผ ์ผ์น˜ํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ ๋ฆฌ์ „ ๋ฐ ์˜์—ญ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋งŒ๋“ค ๋•Œ COMPUTE_ZONE์— us-central1-a๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ํ™”๋ฉด์—์„œ ๋ฆฌ์ „์€ us-central1 (Iowa)๋ฅผ, ์˜์—ญ์€ us-central1-a๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  4. ๋ถ€ํŒ… ๋””์Šคํฌ ์„น์…˜์—์„œ ๋ณ€๊ฒฝ์„ ํด๋ฆญํ•˜์—ฌ ๋ถ€ํŒ… ๋””์Šคํฌ ๊ตฌ์„ฑ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  5. ๊ณต๊ฐœ ์ด๋ฏธ์ง€ ํƒญ์—์„œ Debian ์šด์˜์ฒด์ œ ๋ฒ„์ „ 9๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  6. ์„ ํƒ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  7. ID ๋ฐ API ์•ก์„ธ์Šค ์„น์…˜์—์„œ ์ƒ์„ฑ๋œ ์„œ๋น„์Šค ๊ณ„์ •์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  8. ๋ฐฉํ™”๋ฒฝ ์„น์…˜์—์„œ HTTP ํŠธ๋ž˜ํ”ฝ ํ—ˆ์šฉ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  9. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

gcloud

Compute ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์„œ gcloud compute instances create ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

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 Console์—์„œ VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™

  2. ๊ฐ€์ƒ ๋จธ์‹  ์ธ์Šคํ„ด์Šค ๋ชฉ๋ก์˜ ๋ฐ”๋กœ ์ „์— ๋งŒ๋“  ์ธ์Šคํ„ด์Šค ํ–‰์—์„œ 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 Virtual Private 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

์ปค์Šคํ…€ VPC ๋„คํŠธ์›Œํฌ ๋ฐ ์„œ๋ธŒ๋„ท ๋งŒ๋“ค๊ธฐ

Cloud VPN ๊ตฌ์„ฑ์˜ ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” VPC ๋„คํŠธ์›Œํฌ 2๊ฐœ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. on-prem-vpn-network๋ผ๋Š” ํ•œ ๋„คํŠธ์›Œํฌ๋Š” '์˜จํ”„๋ ˆ๋ฏธ์Šค' ํ™˜๊ฒฝ์— ๊ตฌ์„ฑ๋˜๊ณ , on-prem-instance๋ผ๋Š” Compute Engine VM ์ธ์Šคํ„ด์Šค์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. cloud-vpn-network๋ผ๋Š” ๋‹ค๋ฅธ ๋„คํŠธ์›Œํฌ๋Š” MLLP ์–ด๋Œ‘ํ„ฐ๋ฅผ ์‹คํ–‰ํ•˜๋Š” GKE ํด๋Ÿฌ์Šคํ„ฐ์— ์‚ฌ์šฉ๋˜๋Š” ๋„คํŠธ์›Œํฌ์ž…๋‹ˆ๋‹ค. on-prem-instance VM์— ์—ฐ๊ฒฐํ•˜๊ณ  HL7v2 ๋ฉ”์‹œ์ง€๋ฅผ MLLP ์–ด๋Œ‘ํ„ฐ์˜ ๋‚ด๋ถ€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ํ†ตํ•ด cloud-vpn-network ๋„คํŠธ์›Œํฌ์—์„œ ์‹คํ–‰๋˜๋Š” MLLP ์–ด๋Œ‘ํ„ฐ๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•˜์—ฌ ์ปค์Šคํ…€ VPC ๋„คํŠธ์›Œํฌ ๋‘ ๊ฐœ์™€ ํ•ด๋‹น ์„œ๋ธŒ๋„ท์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  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 VPC ๋„คํŠธ์›Œํฌ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    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. ๋‹ค์Œ ์„น์…˜์—์„œ VPN ๊ฒŒ์ดํŠธ์›จ์ด ๊ตฌ์„ฑ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์™ธ๋ถ€ IP ์ฃผ์†Œ๋ฅผ ๊ธฐ๋กํ•ด ๋‘ก๋‹ˆ๋‹ค. ์™ธ๋ถ€ 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. 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. 3๊ฐœ์˜ ์ „๋‹ฌ ๊ทœ์น™์„ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ณ  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. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํฌํŠธ 22์—์„œ VM ์ธ์Šคํ„ด์Šค์— SSH๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉํ™”๋ฒฝ ๊ทœ์น™์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    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 ์—ฐ๊ฒฐ์„ ํ†ตํ•ด MLLP ์–ด๋Œ‘ํ„ฐ์— HL7v2 ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜์ง€๋งŒ ์ด์ œ Cloud VPN์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณด์•ˆ ์—ฐ๊ฒฐ์„ ํ†ตํ•ด Compute Engine VM์—์„œ GKE์—์„œ ์‹คํ–‰๋˜๋Š” MLLP ์–ด๋Œ‘ํ„ฐ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฉ”์‹œ์ง€๊ฐ€ HL7v2 ์ €์žฅ์†Œ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ ๋‹ค์‹œ ๋งŒ๋“ค๊ธฐ

๋จผ์ € Cloud VPN ๊ตฌ์„ฑ์—์„œ ๊ตฌ์„ฑํ•œ ์„ค์ •์ด ํด๋Ÿฌ์Šคํ„ฐ์— ์‚ฌ์šฉ๋˜๋„๋ก GKE์—์„œ ๋ฐฐํฌ๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  1. ์ƒ์„ฑ๋œ mllp-adapter ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•ด gcloud container clusters delete ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ ์‚ฌ์šฉ๋œ COMPUTE_ZONE ๊ฐ’์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    gcloud container clusters delete mllp-adapter --zone=COMPUTE_ZONE
  2. Kubernetes Engine์— MLLP ์–ด๋Œ‘ํ„ฐ ๋ฐฐํฌ์˜ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด๋˜ 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์„ ๊ตฌ์„ฑํ•  ๋•Œ๋Š” us-central1์„ ์‚ฌ์šฉํ•˜๋„๋ก 'Google Cloud ์ธก' ๋„คํŠธ์›Œํฌ๋ฅผ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด 'Google Cloud ์ธก' ๋„คํŠธ์›Œํฌ๋Š” GKE ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋„คํŠธ์›Œํฌ์ž…๋‹ˆ๋‹ค. us-central1์—์„œ us-central1-c, us-central1-a, us-central1-f, us-central1-b ์ค‘ ์•„๋ฌด ์˜์—ญ์ด๋‚˜ ์‚ฌ์šฉํ•˜์„ธ์š”.

    • CLIENT_EMAIL์€ ์‚ฌ์šฉํ•  ์„œ๋น„์Šค ๊ณ„์ •์˜ ์‹๋ณ„์ž์ž…๋‹ˆ๋‹ค. 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 Console์—์„œ VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™

  2. ์ธ์Šคํ„ด์Šค ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  3. '์˜จํ”„๋ ˆ๋ฏธ์Šค' ๋„คํŠธ์›Œํฌ ์„ค์ •๊ณผ ์ผ์น˜ํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ ๋ฆฌ์ „ ๋ฐ ์˜์—ญ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์ „์˜ ๊ฒฝ์šฐ europe-west1 (Belgium), ์˜์—ญ์˜ ๊ฒฝ์šฐ europe-west1-b์ž…๋‹ˆ๋‹ค.

  4. ๋ถ€ํŒ… ๋””์Šคํฌ ์„น์…˜์—์„œ ๋ณ€๊ฒฝ์„ ํด๋ฆญํ•˜์—ฌ ๋ถ€ํŒ… ๋””์Šคํฌ ๊ตฌ์„ฑ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  5. ๊ณต๊ฐœ ์ด๋ฏธ์ง€ ํƒญ์—์„œ Debian ์šด์˜์ฒด์ œ ๋ฒ„์ „ 9๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  6. ์„ ํƒ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  7. ID ๋ฐ API ์•ก์„ธ์Šค ์„น์…˜์—์„œ ์ƒ์„ฑ๋œ ์„œ๋น„์Šค ๊ณ„์ •์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  8. ๋ฐฉํ™”๋ฒฝ ์„น์…˜์—์„œ HTTP ํŠธ๋ž˜ํ”ฝ ํ—ˆ์šฉ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  9. ๊ด€๋ฆฌ, ๋ณด์•ˆ, ๋””์Šคํฌ, ๋„คํŠธ์›Œํ‚น, ๋‹จ๋… ํ…Œ๋„ŒํŠธ ์„น์…˜์„ ํŽผ์นฉ๋‹ˆ๋‹ค.

  10. ๋„คํŠธ์›Œํ‚น ํƒญ์˜ ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ '์˜จํ”„๋ ˆ๋ฏธ์Šค' ๋„คํŠธ์›Œํฌ ์„ค์ •์˜ ๋„คํŠธ์›Œํฌ ์„ธ๋ถ€์ •๋ณด๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

    1. ๋„คํŠธ์›Œํฌ ํ•„๋“œ์—์„œ on-prem-vpn-network๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    2. ์„œ๋ธŒ๋„คํŠธ์›Œํฌ ํ•„๋“œ์—์„œ subnet-europe-west-10-0-2(10.0.2.0/24)๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  11. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ธ์Šคํ„ด์Šค๊ฐ€ ์‹œ์ž‘๋  ๋•Œ๊นŒ์ง€ ์ž ์‹œ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ค€๋น„๊ฐ€ ๋˜๋ฉด VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€์— ๋…น์ƒ‰ ์ƒํƒœ ์•„์ด์ฝ˜์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

gcloud

Compute ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์„œ gcloud compute instances create ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • '์˜จํ”„๋ ˆ๋ฏธ์Šค' ๋„คํŠธ์›Œํฌ ์„ค์ •๊ณผ ์ผ์น˜ํ•˜๋Š” ZONE: ์˜์—ญ์˜ ๊ฒฝ์šฐ europe-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 Console์—์„œ VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    VM ์ธ์Šคํ„ด์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™

  2. ๊ฐ€์ƒ ๋จธ์‹  ์ธ์Šคํ„ด์Šค ๋ชฉ๋ก์˜ ๋ฐ”๋กœ ์ „์— ๋งŒ๋“  ์ธ์Šคํ„ด์Šค ํ–‰์—์„œ 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 ์‚ฌ์šฉ์ž์—๊ฒŒ์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. --network=host ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  -p 2575:2575๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ --receiver_ip=127.0.0.0์„ ์„ค์ •ํ•˜๋Š” ๋Œ€์‹  --receiver_ip=0.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 \
...