Cloud Storage๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ๋‚ด๋ณด๋‚ด๊ธฐ

์ด ํŽ˜์ด์ง€์—์„œ๋Š” DICOM ์ธ์Šคํ„ด์Šค๋ฅผ Cloud Storage๋กœ ๋‚ด๋ณด๋‚ด๊ณ  DICOM ๊ฐ์ฒด๋ฅผ Cloud Storage์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. DICOM ์ธ์Šคํ„ด์Šค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ด๋ฏธ์ง€์ด์ง€๋งŒ ๊ตฌ์กฐํ™”๋œ ๋ณด๊ณ ์„œ์™€ ๊ฐ™์ด ๋‹ค๋ฅธ ์œ ํ˜•์˜ ์˜๊ตฌ์ ์ธ ๋ฐ์ดํ„ฐ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Cloud Storage์˜ DICOM ๊ฐ์ฒด๋Š” Cloud Storage์— ์žˆ๋Š” DICOM ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud Storage๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

Cloud Storage ๊ถŒํ•œ ์„ค์ •

DICOM ๋ฐ์ดํ„ฐ๋ฅผ Cloud Storage๋กœ ๋‚ด๋ณด๋‚ด๊ณ  ๊ฐ€์ ธ์˜ค๊ธฐ ์ „์— Cloud Healthcare ์„œ๋น„์Šค ์—์ด์ „ํŠธ ์„œ๋น„์Šค ๊ณ„์ •์— ์ถ”๊ฐ€ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ DICOM ์ €์žฅ์†Œ Cloud Storage ๊ถŒํ•œ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

DICOM ๊ฐ์ฒด ๊ฐ€์ ธ์˜ค๊ธฐ

์—ฌ๋Ÿฌ DICOM ์ธ์Šคํ„ด์Šค ํŒŒ์ผ์„ DICOM ์ €์žฅ์†Œ๋กœ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด ๋‹ค์Œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์ƒ˜ํ”Œ์€ Cloud Storage ๋ฒ„ํ‚ท์—์„œ DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ฝ˜์†”

Cloud Storage ๋ฒ„ํ‚ท์—์„œ DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•˜์„ธ์š”.

  1. Google Cloud ์ฝ˜์†”์—์„œ ๋ฐ์ดํ„ฐ ์„ธํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
    ๋ฐ์ดํ„ฐ ์„ธํŠธ๋กœ ์ด๋™
  2. DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ DICOM ์ €์žฅ์†Œ๊ฐ€ ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ ๋ชฉ๋ก์—์„œ DICOM ์ €์žฅ์†Œ์˜ ์ž‘์—… ๋ชฉ๋ก์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    DICOM ์ €์žฅ์†Œ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
  4. ํ”„๋กœ์ ํŠธ ๋ชฉ๋ก์—์„œ Cloud Storage ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  5. ์œ„์น˜ ๋ชฉ๋ก์—์„œ Cloud Storage ๋ฒ„ํ‚ท์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  6. ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ฌ ํŠน์ • ์œ„์น˜๋ฅผ ์„ค์ •ํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    1. ๊ณ ๊ธ‰ ์˜ต์…˜์„ ํŽผ์นฉ๋‹ˆ๋‹ค.
    2. Cloud Storage ๊ฒฝ๋กœ ์žฌ์ •์˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    3. ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ฌ ํŠน์ • ์†Œ์Šค๋ฅผ ์„ค์ •ํ•˜๋ ค๋ฉด ์œ„์น˜ ํ…์ŠคํŠธ ์ƒ์ž์— ๋‹ค์Œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฝ๋กœ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
      • * - ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๊ฐ€ ์•„๋‹Œ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
      • ** - ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค(๊ตฌ๋ถ„ ๊ธฐํ˜ธ ํฌํ•จ). ํŒŒ์ผ ์ด๋ฆ„ ํ™•์žฅ์ž์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ์œ ํ˜•์˜ ํŒŒ์ผ์„ ๋ชจ๋‘ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • ? - ์ผ์น˜ํ•˜๋Š” 1๊ฐœ ๋ฌธ์ž๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
  7. ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์ •์˜๋œ ์†Œ์Šค์—์„œ DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  8. ์ž‘์—… ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋ ค๋ฉด ์ž‘์—… ํƒญ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ‘œ์‹œ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
    • ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—… ์ƒํƒœ ์„น์…˜์˜ ํ™•์ธ ์ œ๋ชฉ ์•„๋ž˜์— ๋…น์ƒ‰ ์ฒดํฌํ‘œ์‹œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ฐœ์š” ์„น์…˜์— ์ž‘์—… ID์™€ ๊ฐ™์€ ํ–‰์— ๋…น์ƒ‰ ์ฒดํฌํ‘œ์‹œ์™€ ํ™•์ธ ํ‘œ์‹œ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ž‘์—…์„ ํด๋ฆญํ•œ ๋‹ค์Œ Cloud Logging์—์„œ ์„ธ๋ถ€์ •๋ณด ๋ณด๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

gcloud

Cloud Storage ๋ฒ„ํ‚ท์—์„œ DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด gcloud healthcare dicom-stores import gcs ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ์ด๋ฆ„, DICOM ์ €์žฅ์†Œ์˜ ์ด๋ฆ„, Cloud Storage ๋ฒ„ํ‚ท์˜ ๊ฐ์ฒด ์œ„์น˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฒ„ํ‚ท ๋‚ด์˜ ํŒŒ์ผ ์œ„์น˜๋Š” ์ž„์˜์ ์ด๋ฉฐ ๋‹ค์Œ ์ƒ˜ํ”Œ์— ์ง€์ •๋œ ํ˜•์‹์„ ์ •ํ™•ํ•˜๊ฒŒ ์ค€์ˆ˜ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • Cloud Storage์—์„œ DICOM์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•  ๋•Œ๋Š” ์™€์ผ๋“œ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ๋Š” ์—ฌ๋Ÿฌ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ์ง€์›๋ฉ๋‹ˆ๋‹ค.
    • ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๊ฐ€ ์•„๋‹Œ 0์ž ์ด์ƒ์˜ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž๋ฅผ ์ฐพ์œผ๋ ค๋ฉด *๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด gs://BUCKET/DIRECTORY/Example*.dcm์„ ์‚ฌ์šฉํ•˜๋ฉด DIRECTORY์— ์žˆ๋Š” Example.dcm ๋ฐ Example22.dcm์ด ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค.
    • 0์ž ์ด์ƒ์˜ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž(๊ตฌ๋ถ„ ๊ธฐํ˜ธ ํฌํ•จ)๋ฅผ ์ฐพ์œผ๋ ค๋ฉด **๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฒฝ๋กœ์˜ ๋์— ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ ๊ฒฝ๋กœ์— ๋‹ค๋ฅธ ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ง€์ •๋œ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฐ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ํŒŒ์ผ ์ด๋ฆ„ ํ™•์žฅ์ž๊ฐ€ ์žˆ๋Š” ๋ชจ๋“  ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๋Š” ํŒŒ์ผ ์ด๋ฆ„ ํ™•์žฅ์ž (์˜ˆ : .dcm)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด gs://BUCKET/DIRECTORY/**.dcm๋Š” DIRECTORY ๋ฐ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ํŒŒ์ผ๋ช… ํ™•์žฅ์ž๊ฐ€ .dcm์ธ ํŒŒ์ผ์„ ๋ชจ๋‘ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    • ์ผ์น˜ํ•˜๋Š” 1๊ฐœ ๋ฌธ์ž๋ฅผ ์ฐพ์œผ๋ ค๋ฉด ?๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด gs://BUCKET/DIRECTORY/Example?.dcm์„ ์‚ฌ์šฉํ•˜๋ฉด Example1.dcm์ด ๊ฒ€์ƒ‰๋˜์ง€๋งŒ Example.dcm ๋˜๋Š” Example01.dcm์€ ๊ฒ€์ƒ‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์ƒ˜ํ”Œ์€ Cloud Storage ๋ฒ„ํ‚ท์—์„œ DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

gcloud healthcare dicom-stores import gcs DICOM_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --gcs-uri=gs://BUCKET/DIRECTORY/DICOM_INSTANCE.dcm

๋ช…๋ น์ค„์— ์ž‘์—… ID๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID

์ž‘์—… ์ƒํƒœ๋ฅผ ๋ณด๋ ค๋ฉด gcloud healthcare operations describe ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‘๋‹ต์—์„œ OPERATION_ID๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

gcloud healthcare operations describe OPERATION_ID \
  --location=LOCATION \
  --dataset=DATASET_ID

๋ช…๋ น์–ด๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์‘๋‹ต์— done: true๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

done: true
metadata:
'@type': type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata
apiMethodName: google.cloud.healthcare.v1.dicom.DicomService.ImportDicomData
counter:
  success: SUCCESSFUL_INSTANCES
  failure: FAILED_INSTANCES
createTime: "CREATE_TIME"
endTime: "END_TIME"
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID
response:
'@type': "..."

API

Cloud Storage ๋ฒ„ํ‚ท์—์„œ DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด projects.locations.datasets.dicomStores.import ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฒ„ํ‚ท ๋‚ด์˜ ํŒŒ์ผ ์œ„์น˜๋Š” ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‹ค์Œ ์ƒ˜ํ”Œ์— ์ง€์ •๋œ ํ˜•์‹๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.
  • Cloud Storage์—์„œ DICOM์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•  ๋•Œ๋Š” ์™€์ผ๋“œ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ๋Š” ์—ฌ๋Ÿฌ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋‹ค์Œ ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ์ง€์›๋ฉ๋‹ˆ๋‹ค.
    • ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๊ฐ€ ์•„๋‹Œ 0์ž ์ด์ƒ์˜ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž๋ฅผ ์ฐพ์œผ๋ ค๋ฉด *๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด gs://BUCKET/DIRECTORY/Example*.dcm์„ ์‚ฌ์šฉํ•˜๋ฉด DIRECTORY์— ์žˆ๋Š” Example.dcm ๋ฐ Example22.dcm์ด ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค.
    • 0์ž ์ด์ƒ์˜ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž(๊ตฌ๋ถ„ ๊ธฐํ˜ธ ํฌํ•จ)๋ฅผ ์ฐพ์œผ๋ ค๋ฉด **๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฒฝ๋กœ์˜ ๋์— ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ ๊ฒฝ๋กœ์— ๋‹ค๋ฅธ ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ง€์ •๋œ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฐ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ํŒŒ์ผ ์ด๋ฆ„ ํ™•์žฅ์ž๊ฐ€ ์žˆ๋Š” ๋ชจ๋“  ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๋Š” ํŒŒ์ผ ์ด๋ฆ„ ํ™•์žฅ์ž (์˜ˆ : .dcm)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด gs://BUCKET/DIRECTORY/**.dcm๋Š” DIRECTORY ๋ฐ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ํŒŒ์ผ๋ช… ํ™•์žฅ์ž๊ฐ€ .dcm์ธ ํŒŒ์ผ์„ ๋ชจ๋‘ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    • ์ผ์น˜ํ•˜๋Š” 1๊ฐœ ๋ฌธ์ž๋ฅผ ์ฐพ์œผ๋ ค๋ฉด ?๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด gs://BUCKET/DIRECTORY/Example?.dcm์„ ์‚ฌ์šฉํ•˜๋ฉด Example1.dcm์ด ๊ฒ€์ƒ‰๋˜์ง€๋งŒ Example.dcm ๋˜๋Š” Example01.dcm์€ ๊ฒ€์ƒ‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

REST

  1. DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

    ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: Google Cloud ํ”„๋กœ์ ํŠธ ID
    • LOCATION: ๋ฐ์ดํ„ฐ ์„ธํŠธ ์œ„์น˜
    • DATASET_ID: DICOM ์ €์žฅ์†Œ์˜ ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ
    • DICOM_STORE_ID: DICOM ์ €์žฅ์†Œ ID
    • BUCKET/PATH/TO/FILE: Cloud Storage์˜ DICOM ๊ฐ์ฒด ๊ฒฝ๋กœ

    JSON ์š”์ฒญ ๋ณธ๋ฌธ:

    {
      "gcsSource": {
        "uri": "gs://BUCKET/PATH/TO/FILE.dcm"
      }
    }
    

    ์š”์ฒญ์„ ๋ณด๋‚ด๋ ค๋ฉด ๋‹ค์Œ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    curl

    ์š”์ฒญ ๋ณธ๋ฌธ์„ request.json ํŒŒ์ผ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ด ํŒŒ์ผ์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ฎ์–ด์”๋‹ˆ๋‹ค.

    cat > request.json << 'EOF'
    {
      "gcsSource": {
        "uri": "gs://BUCKET/PATH/TO/FILE.dcm"
      }
    }
    EOF

    ๊ทธ๋Ÿฐ ํ›„ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ REST ์š”์ฒญ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -d @request.json \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:import"

    PowerShell

    ์š”์ฒญ ๋ณธ๋ฌธ์„ request.json ํŒŒ์ผ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ด ํŒŒ์ผ์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ฎ์–ด์”๋‹ˆ๋‹ค.

    @'
    {
      "gcsSource": {
        "uri": "gs://BUCKET/PATH/TO/FILE.dcm"
      }
    }
    '@  | Out-File -FilePath request.json -Encoding utf8

    ๊ทธ๋Ÿฐ ํ›„ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ REST ์š”์ฒญ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

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

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json" `
    -InFile request.json `
    -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:import" | Select-Object -Expand Content
    ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์‘๋‹ต์—๋Š” ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์˜ ์‹๋ณ„์ž๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ์™„๋ฃŒํ•˜๋Š” ๋ฐ ์ƒ๋‹นํ•œ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋Š” ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. OPERATION_ID์˜ ๊ฐ’์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ ์ด ๊ฐ’์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  2. ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—… ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

    ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: Google Cloud ํ”„๋กœ์ ํŠธ ID
    • LOCATION: ๋ฐ์ดํ„ฐ ์„ธํŠธ ์œ„์น˜
    • DATASET_ID: DICOM ์ €์žฅ์†Œ์˜ ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ
    • OPERATION_ID: ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์—์„œ ๋ฐ˜ํ™˜๋œ ID

    ์š”์ฒญ์„ ๋ณด๋‚ด๋ ค๋ฉด ๋‹ค์Œ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    curl

    ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    curl -X GET \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

    PowerShell

    ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

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

    Invoke-WebRequest `
    -Method GET `
    -Headers $headers `
    -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" | Select-Object -Expand Content
    ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์ด ์•„์ง ์‹คํ–‰ ์ค‘์ด๋ฉด ์„œ๋ฒ„๋Š” ๊ฐ€์ ธ์˜ค๊ธฐ ๋Œ€๊ธฐ ์ค‘์ธ DICOM ์ธ์Šคํ„ด์Šค ์ˆ˜๊ฐ€ ํฌํ•จ๋œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. LRO๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์„œ๋ฒ„๊ฐ€ JSON ํ˜•์‹์˜ ์ž‘์—… ์ƒํƒœ๊ฐ€ ํฌํ•จ๋œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Go

import (
	"context"
	"fmt"
	"io"

	healthcare "google.golang.org/api/healthcare/v1"
)

// importDICOMInstance imports DICOM objects from GCS.
func importDICOMInstance(w io.Writer, projectID, location, datasetID, dicomStoreID, contentURI string) error {
	ctx := context.Background()

	healthcareService, err := healthcare.NewService(ctx)
	if err != nil {
		return fmt.Errorf("healthcare.NewService: %w", err)
	}

	storesService := healthcareService.Projects.Locations.Datasets.DicomStores

	req := &healthcare.ImportDicomDataRequest{
		GcsSource: &healthcare.GoogleCloudHealthcareV1DicomGcsSource{
			Uri: contentURI,
		},
	}
	name := fmt.Sprintf("projects/%s/locations/%s/datasets/%s/dicomStores/%s", projectID, location, datasetID, dicomStoreID)

	lro, err := storesService.Import(name, req).Do()
	if err != nil {
		return fmt.Errorf("Import: %w", err)
	}

	fmt.Fprintf(w, "Import to DICOM store started. Operation: %q\n", lro.Name)
	return nil
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets.DicomStores;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.GoogleCloudHealthcareV1DicomGcsSource;
import com.google.api.services.healthcare.v1.model.ImportDicomDataRequest;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class DicomStoreImport {
  private static final String DICOM_NAME = "projects/%s/locations/%s/datasets/%s/dicomStores/%s";
  private static final JsonFactory JSON_FACTORY = new GsonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void dicomStoreImport(String dicomStoreName, String gcsUri) throws IOException {
    // String dicomStoreName =
    //    String.format(
    //        DICOM_NAME, "your-project-id", "your-region-id", "your-dataset-id", "your-dicom-id");
    // String gcsUri = "gs://your-bucket-id/path/to/destination/dir"

    // Initialize the client, which will be used to interact with the service.
    CloudHealthcare client = createClient();

    // Configure where the store should be imported from.
    GoogleCloudHealthcareV1DicomGcsSource gcsSource =
        new GoogleCloudHealthcareV1DicomGcsSource().setUri(gcsUri);
    ImportDicomDataRequest importRequest = new ImportDicomDataRequest().setGcsSource(gcsSource);

    // Create request and configure any parameters.
    DicomStores.CloudHealthcareImport request =
        client
            .projects()
            .locations()
            .datasets()
            .dicomStores()
            .healthcareImport(dicomStoreName, importRequest);

    // Execute the request, wait for the operation to complete, and process the results.
    try {
      Operation operation = request.execute();
      while (operation.getDone() == null || !operation.getDone()) {
        // Update the status of the operation with another request.
        Thread.sleep(500); // Pause for 500ms between requests.
        operation =
            client
                .projects()
                .locations()
                .datasets()
                .operations()
                .get(operation.getName())
                .execute();
      }
      System.out.println("DICOM store import complete." + operation.getResponse());
    } catch (Exception ex) {
      System.out.printf("Error during request execution: %s", ex.toString());
      ex.printStackTrace(System.out);
    }
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };

    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }
}

Node.js

const google = require('@googleapis/healthcare');
const healthcare = google.healthcare({
  version: 'v1',
  auth: new google.auth.GoogleAuth({
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
  }),
});
const sleep = ms => {
  return new Promise(resolve => setTimeout(resolve, ms));
};

const importDicomInstance = async () => {
  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const dicomStoreId = 'my-dicom-store';
  // const gcsUri = 'my-bucket/my-directory/*.dcm'
  const name = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/dicomStores/${dicomStoreId}`;
  const request = {
    name,
    resource: {
      // The location of the DICOM instances in Cloud Storage
      gcsSource: {
        uri: `gs://${gcsUri}`,
      },
    },
  };

  const operation =
    await healthcare.projects.locations.datasets.dicomStores.import(request);
  const operationName = operation.data.name;

  const operationRequest = {name: operationName};

  // Wait fifteen seconds for the LRO to finish.
  await sleep(15000);

  // Check the LRO's status
  const operationStatus =
    await healthcare.projects.locations.datasets.operations.get(
      operationRequest
    );

  const {data} = operationStatus;

  if (data.error === undefined) {
    console.log('Successfully imported DICOM instances');
  } else {
    console.log('Encountered errors. Sample error:');
    console.log(
      'Resource on which error occured:',
      data.error.details[0]['sampleErrors'][0]['resource']
    );
    console.log(
      'Error code:',
      data.error.details[0]['sampleErrors'][0]['error']['code']
    );
    console.log(
      'Error message:',
      data.error.details[0]['sampleErrors'][0]['error']['message']
    );
  }
};

importDicomInstance();

Python

def import_dicom_instance(
    project_id, location, dataset_id, dicom_store_id, content_uri
):
    """Imports data into the DICOM store by copying it from the specified
    source.

    See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom
    before running the sample."""
    # Imports the Google API Discovery Service.
    from googleapiclient import discovery

    api_version = "v1"
    service_name = "healthcare"
    # Returns an authorized API client by discovering the Healthcare API
    # and using GOOGLE_APPLICATION_CREDENTIALS environment variable.
    client = discovery.build(service_name, api_version)

    # TODO(developer): Uncomment these lines and replace with your values.
    # project_id = 'my-project'  # replace with your GCP project ID
    # location = 'us-central1'  # replace with the parent dataset's location
    # dataset_id = 'my-dataset'  # replace with the DICOM store's parent dataset ID
    # dicom_store_id = 'my-dicom-store'  # replace with the DICOM store's ID
    # content_uri = 'my-bucket/*.dcm'  # replace with a Cloud Storage bucket and DCM files
    dicom_store_parent = "projects/{}/locations/{}/datasets/{}".format(
        project_id, location, dataset_id
    )
    dicom_store_name = f"{dicom_store_parent}/dicomStores/{dicom_store_id}"

    body = {"gcsSource": {"uri": f"gs://{content_uri}"}}

    # Escape "import()" method keyword because "import"
    # is a reserved keyword in Python
    request = (
        client.projects()
        .locations()
        .datasets()
        .dicomStores()
        .import_(name=dicom_store_name, body=body)
    )

    response = request.execute()
    print(f"Imported DICOM instance: {content_uri}")

    return response

DICOM ์ €์žฅ์†Œ์—์„œ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค ๋˜๋Š” ์—ฐ๊ตฌ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ ค๋ฉด Cloud Healthcare API์— ๊ตฌํ˜„๋œ ๊ฑฐ๋ž˜ ๊ฒ€์ƒ‰ RESTful ์›น ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค ์ง€์ •(๋ฏธ๋ฆฌ๋ณด๊ธฐ)

๊ธฐ๋ณธ์ ์œผ๋กœ projects.locations.datasets.dicomStores.import ๋ฉ”์„œ๋“œ๋Š” Standard Storage ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๊ฐ์ฒด๋ฅผ DICOM ์ €์žฅ์†Œ๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. Cloud Storage์—์„œ DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ DICOM ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค ๋ณ€๊ฒฝ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๋‹ค์Œ ์ƒ˜ํ”Œ์€ Cloud Storage์—์„œ DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

REST

projects.locations.datasets.dicomStores.import ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  1. DICOM ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

    ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: Google Cloud ํ”„๋กœ์ ํŠธ ID
    • LOCATION: ๋ฐ์ดํ„ฐ ์„ธํŠธ ์œ„์น˜
    • DATASET_ID: DICOM ์ €์žฅ์†Œ์˜ ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ
    • DICOM_STORE_ID: DICOM ์ €์žฅ์†Œ ID
    • BUCKET/PATH/TO/FILE: Cloud Storage์˜ DICOM ๊ฐ์ฒด ๊ฒฝ๋กœ
    • STORAGE_CLASS: STANDARD, NEARLINE, COLDLINE, ARCHIVE์˜ DICOM ์Šคํ† ์–ด์— ์žˆ๋Š” DICOM ๊ฐ์ฒด์˜ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค

    JSON ์š”์ฒญ ๋ณธ๋ฌธ:

    {
      "gcsSource": {
        "uri": "gs://BUCKET/PATH/TO/FILE.dcm"
      },
      "blob_storage_settings": {
        "blob_storage_class": "STORAGE_CLASS"
      }
    }
    

    ์š”์ฒญ์„ ๋ณด๋‚ด๋ ค๋ฉด ๋‹ค์Œ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    curl

    ์š”์ฒญ ๋ณธ๋ฌธ์„ request.json ํŒŒ์ผ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ด ํŒŒ์ผ์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ฎ์–ด์”๋‹ˆ๋‹ค.

    cat > request.json << 'EOF'
    {
      "gcsSource": {
        "uri": "gs://BUCKET/PATH/TO/FILE.dcm"
      },
      "blob_storage_settings": {
        "blob_storage_class": "STORAGE_CLASS"
      }
    }
    EOF

    ๊ทธ๋Ÿฐ ํ›„ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ REST ์š”์ฒญ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -d @request.json \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:import"

    PowerShell

    ์š”์ฒญ ๋ณธ๋ฌธ์„ request.json ํŒŒ์ผ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ด ํŒŒ์ผ์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ฎ์–ด์”๋‹ˆ๋‹ค.

    @'
    {
      "gcsSource": {
        "uri": "gs://BUCKET/PATH/TO/FILE.dcm"
      },
      "blob_storage_settings": {
        "blob_storage_class": "STORAGE_CLASS"
      }
    }
    '@  | Out-File -FilePath request.json -Encoding utf8

    ๊ทธ๋Ÿฐ ํ›„ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ REST ์š”์ฒญ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

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

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json" `
    -InFile request.json `
    -Uri "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:import" | Select-Object -Expand Content
    ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์‘๋‹ต์—๋Š” ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์˜ ์‹๋ณ„์ž๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ์™„๋ฃŒํ•˜๋Š” ๋ฐ ์ƒ๋‹นํ•œ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋Š” ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. OPERATION_ID์˜ ๊ฐ’์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ ์ด ๊ฐ’์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  2. ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—… ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

    ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: Google Cloud ํ”„๋กœ์ ํŠธ ID
    • LOCATION: ๋ฐ์ดํ„ฐ ์„ธํŠธ ์œ„์น˜
    • DATASET_ID: DICOM ์ €์žฅ์†Œ์˜ ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ
    • OPERATION_ID: ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์—์„œ ๋ฐ˜ํ™˜๋œ ID

    ์š”์ฒญ์„ ๋ณด๋‚ด๋ ค๋ฉด ๋‹ค์Œ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    curl

    ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    curl -X GET \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

    PowerShell

    ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

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

    Invoke-WebRequest `
    -Method GET `
    -Headers $headers `
    -Uri "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" | Select-Object -Expand Content
    ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์ด ์•„์ง ์‹คํ–‰ ์ค‘์ด๋ฉด ์„œ๋ฒ„๋Š” ๊ฐ€์ ธ์˜ค๊ธฐ ๋Œ€๊ธฐ ์ค‘์ธ DICOM ์ธ์Šคํ„ด์Šค ์ˆ˜๊ฐ€ ํฌํ•จ๋œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. LRO๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์„œ๋ฒ„๊ฐ€ JSON ํ˜•์‹์˜ ์ž‘์—… ์ƒํƒœ๊ฐ€ ํฌํ•จ๋œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

DICOM ๊ฐ€์ ธ์˜ค๊ธฐ ์š”์ฒญ ๋ฌธ์ œ ํ•ด๊ฒฐ

DICOM ๊ฐ€์ ธ์˜ค๊ธฐ ์š”์ฒญ ์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ Cloud Logging์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud Logging์—์„œ ์˜ค๋ฅ˜ ๋กœ๊ทธ ๋ณด๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

DICOM ์ธ์Šคํ„ด์Šค ๋‚ด๋ณด๋‚ด๊ธฐ

๋‹ค์Œ ์ƒ˜ํ”Œ์€ DICOM ์ธ์Šคํ„ด์Šค๋ฅผ Cloud Storage ๋ฒ„ํ‚ท์œผ๋กœ ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. DICOM ์ €์žฅ์†Œ์—์„œ DICOM ์ธ์Šคํ„ด์Šค๋ฅผ ๋‚ด๋ณด๋‚ผ ๋•Œ๋Š” ์ €์žฅ์†Œ์— ์žˆ๋Š” ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋ฅผ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.

์ฝ˜์†”

DICOM ์ธ์Šคํ„ด์Šค๋ฅผ Cloud Storage๋กœ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

  1. Google Cloud ์ฝ˜์†”์—์„œ ๋ฐ์ดํ„ฐ ์„ธํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
    ๋ฐ์ดํ„ฐ ์„ธํŠธ๋กœ ์ด๋™
  2. DICOM ์ธ์Šคํ„ด์Šค๋ฅผ ๋‚ด๋ณด๋‚ผ DICOM ์ €์žฅ์†Œ๊ฐ€ ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ ๋ชฉ๋ก์— ์žˆ๋Š” DICOM ์ €์žฅ์†Œ์˜ ์ž‘์—… ๋ชฉ๋ก์—์„œ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  4. ํ‘œ์‹œ๋˜๋Š” DICOM ์ €์žฅ์†Œ ๋‚ด๋ณด๋‚ด๊ธฐ ํŽ˜์ด์ง€์—์„œ Google Cloud Storage ๋ฒ„ํ‚ท์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  5. ํ”„๋กœ์ ํŠธ ๋ชฉ๋ก์—์„œ Cloud Storage ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  6. ์œ„์น˜ ๋ชฉ๋ก์—์„œ Cloud Storage ๋ฒ„ํ‚ท์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  7. DICOM ๋‚ด๋ณด๋‚ด๊ธฐ ์„ค์ •์—์„œ DICOM ์ธ์Šคํ„ด์Šค๋ฅผ ๋‚ด๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํŒŒ์ผ ํ˜•์‹์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ํ˜•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • DICOM ํŒŒ์ผ(.dcm)
    • octet ์ŠคํŠธ๋ฆผ
    • ์ด๋ฏธ์ง€(.jpg,.png)
  8. ์ถ”๊ฐ€ ์ „์†ก ๋ฌธ๋ฒ•์„ ์ •์˜ํ•˜๋ ค๋ฉด ์ „์†ก ๋ฌธ๋ฒ• ๋ชฉ๋ก์—์„œ ๋ฌธ๋ฒ•์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  9. ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ํด๋ฆญํ•˜์—ฌ DICOM ์ธ์Šคํ„ด์Šค๋ฅผ Cloud Storage์˜ ์ •์˜๋œ ์œ„์น˜๋กœ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.
  10. ์ž‘์—… ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋ ค๋ฉด ์ž‘์—… ํƒญ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ‘œ์‹œ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
    • ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—… ์ƒํƒœ ์„น์…˜์˜ ํ™•์ธ ์ œ๋ชฉ ์•„๋ž˜์— ๋…น์ƒ‰ ์ฒดํฌํ‘œ์‹œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ฐœ์š” ์„น์…˜์— ์ž‘์—… ID์™€ ๊ฐ™์€ ํ–‰์— ๋…น์ƒ‰ ์ฒดํฌํ‘œ์‹œ์™€ ํ™•์ธ ํ‘œ์‹œ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ž‘์—…์„ ํด๋ฆญํ•œ ๋‹ค์Œ Cloud Logging์—์„œ ์„ธ๋ถ€์ •๋ณด ๋ณด๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

gcloud

DICOM ์ธ์Šคํ„ด์Šค๋ฅผ Cloud Storage ๋ฒ„ํ‚ท์œผ๋กœ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด gcloud healthcare dicom-stores export gcs ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ์ด๋ฆ„, DICOM ์ €์žฅ์†Œ์˜ ์ด๋ฆ„, ๋Œ€์ƒ Cloud Storage ๋ฒ„ํ‚ท์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • Cloud Healthcare API๊ฐ€ ๊ฐ ๊ฐ์ฒด์— ๋Œ€ํ•ด .dcm ํŒŒ์ผ์„ ํ•˜๋‚˜ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด ๋Œ€์‹  Cloud Storage ๋ฒ„ํ‚ท ๋˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
  • ๋ช…๋ น์–ด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ง€์ •ํ•˜๋ฉด ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์ƒ˜ํ”Œ์€ gcloud healthcare dicom-stores export gcs ๋ช…๋ น์–ด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

gcloud healthcare dicom-stores export gcs DICOM_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --gcs-uri-prefix=gs://BUCKET/DIRECTORY

๋ช…๋ น์ค„์— ์ž‘์—… ID๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID

์ž‘์—… ์ƒํƒœ๋ฅผ ๋ณด๋ ค๋ฉด gcloud healthcare operations describe ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‘๋‹ต์—์„œ OPERATION_ID๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

gcloud healthcare operations describe OPERATION_ID \
  --location=LOCATION \
  --dataset=DATASET_ID

๋ช…๋ น์–ด๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์‘๋‹ต์— done: true๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

done: true
metadata:
'@type': type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata
apiMethodName: google.cloud.healthcare.v1.dicom.DicomService.ExportDicomData
counter:
  success: SUCCESSFUL_INSTANCES
  failure: FAILED_INSTANCES
createTime: "CREATE_TIME"
endTime: "END_TIME"
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID
response:
'@type': "..."

API

DICOM ์ธ์Šคํ„ด์Šค๋ฅผ Cloud Storage ๋ฒ„ํ‚ท์œผ๋กœ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด projects.locations.datasets.dicomStores.export ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • Cloud Healthcare API๊ฐ€ ๊ฐ DICOM ๊ฐ์ฒด์— ๋Œ€ํ•ด .dcm ํŒŒ์ผ์„ ํ•˜๋‚˜ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด ๋Œ€์‹  Cloud Storage ๋ฒ„ํ‚ท ๋˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
  • ๋ช…๋ น์–ด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ง€์ •ํ•˜๋ฉด ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

curl

DICOM ์ธ์Šคํ„ด์Šค๋ฅผ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด POST ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋‹ค์Œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜์„ธ์š”.

  • ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ์ด๋ฆ„ ๋ฐ ์œ„์น˜
  • DICOM ์ €์žฅ์†Œ์˜ ์ด๋ฆ„
  • ๋Œ€์ƒ Cloud Storage ๋ฒ„ํ‚ท์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ ์ƒ˜ํ”Œ์€ curl์„ ์‚ฌ์šฉํ•˜๋Š” POST ์š”์ฒญ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    --data "{
      'gcsDestination': {
        'uriPrefix': 'gs://BUCKET/DIRECTORY'
      }
    }" "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:export"

์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ JSON ํ˜•์‹์œผ๋กœ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

์‘๋‹ต์— ์ž‘์—… ์ด๋ฆ„์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ž‘์—… ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋ ค๋ฉด ์ž‘์—… get ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๋Š” JSON ํ˜•์‹์˜ ์ž‘์—… ์ƒํƒœ๊ฐ€ ํฌํ•จ๋œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.dicom.DicomService.ExportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/query/CLOUD_LOGGING_URL",
    "counter":{
       "success": SUCCESSFUL_INSTANCES
       "failure": FAILED_INSTANCES
    }
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

PowerShell

DICOM ์ธ์Šคํ„ด์Šค๋ฅผ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด POST ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋‹ค์Œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜์„ธ์š”.

  • ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ์ด๋ฆ„ ๋ฐ ์œ„์น˜
  • DICOM ์ €์žฅ์†Œ์˜ ์ด๋ฆ„
  • ๋Œ€์ƒ Cloud Storage ๋ฒ„ํ‚ท์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ ์ƒ˜ํ”Œ์€ Windows PowerShell์„ ์‚ฌ์šฉํ•œ POST ์š”์ฒญ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

$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 "{
    'gcsDestination': {
      'uriPrefix': 'gs://BUCKET/DIRECTORY'
    }
  }" `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:export" | Select-Object -Expand Content

์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ JSON ํ˜•์‹์œผ๋กœ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

์‘๋‹ต์— ์ž‘์—… ์ด๋ฆ„์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ž‘์—… ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋ ค๋ฉด ์ž‘์—… get ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

Invoke-WebRequest `
  -Method Get `
  -Headers $headers `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" | Select-Object -Expand Content

์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๋Š” JSON ํ˜•์‹์˜ ์ž‘์—… ์ƒํƒœ๊ฐ€ ํฌํ•จ๋œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.dicom.DicomService.ExportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/query/CLOUD_LOGGING_URL",
    "counter":{
       "success": SUCCESSFUL_INSTANCES
       "failure": FAILED_INSTANCES
    },
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	healthcare "google.golang.org/api/healthcare/v1"
)

// exportDICOMInstance exports DICOM objects to GCS.
func exportDICOMInstance(w io.Writer, projectID, location, datasetID, dicomStoreID, destination string) error {
	ctx := context.Background()

	healthcareService, err := healthcare.NewService(ctx)
	if err != nil {
		return fmt.Errorf("healthcare.NewService: %w", err)
	}

	storesService := healthcareService.Projects.Locations.Datasets.DicomStores

	req := &healthcare.ExportDicomDataRequest{
		GcsDestination: &healthcare.GoogleCloudHealthcareV1DicomGcsDestination{
			UriPrefix: destination, // "gs://my-bucket/path/to/prefix/"
		},
	}
	name := fmt.Sprintf("projects/%s/locations/%s/datasets/%s/dicomStores/%s", projectID, location, datasetID, dicomStoreID)

	lro, err := storesService.Export(name, req).Do()
	if err != nil {
		return fmt.Errorf("Export: %w", err)
	}

	fmt.Fprintf(w, "Export to DICOM store started. Operation: %q\n", lro.Name)
	return nil
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets.DicomStores;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.ExportDicomDataRequest;
import com.google.api.services.healthcare.v1.model.GoogleCloudHealthcareV1DicomGcsDestination;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class DicomStoreExport {
  private static final String DICOM_NAME = "projects/%s/locations/%s/datasets/%s/dicomStores/%s";
  private static final JsonFactory JSON_FACTORY = new GsonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void dicomStoreExport(String dicomStoreName, String gcsUri) throws IOException {
    // String dicomStoreName =
    //    String.format(
    //        DICOM_NAME, "your-project-id", "your-region-id", "your-dataset-id", "your-dicom-id");
    // String gcsUri = "gs://your-bucket-id/path/to/destination/dir"

    // Initialize the client, which will be used to interact with the service.
    CloudHealthcare client = createClient();

    // Configure where the store will be exported too.
    GoogleCloudHealthcareV1DicomGcsDestination gcsDestination =
        new GoogleCloudHealthcareV1DicomGcsDestination().setUriPrefix(gcsUri);
    ExportDicomDataRequest exportRequest =
        new ExportDicomDataRequest().setGcsDestination(gcsDestination);

    // Create request and configure any parameters.
    DicomStores.Export request =
        client
            .projects()
            .locations()
            .datasets()
            .dicomStores()
            .export(dicomStoreName, exportRequest);

    // Execute the request, wait for the operation to complete, and process the results.
    try {
      Operation operation = request.execute();
      while (operation.getDone() == null || !operation.getDone()) {
        // Update the status of the operation with another request.
        Thread.sleep(500); // Pause for 500ms between requests.
        operation =
            client
                .projects()
                .locations()
                .datasets()
                .operations()
                .get(operation.getName())
                .execute();
      }
      System.out.println("DICOM store export complete." + operation.getResponse());
    } catch (Exception ex) {
      System.out.printf("Error during request execution: %s", ex.toString());
      ex.printStackTrace(System.out);
    }
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };

    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }
}

Node.js

const google = require('@googleapis/healthcare');
const healthcare = google.healthcare({
  version: 'v1',
  auth: new google.auth.GoogleAuth({
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
  }),
});

const exportDicomInstanceGcs = async () => {
  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const dicomStoreId = 'my-dicom-store';
  // const gcsUri = 'my-bucket/my-directory'
  const name = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/dicomStores/${dicomStoreId}`;
  const request = {
    name,
    resource: {
      gcsDestination: {
        // The destination location of the DICOM instances in Cloud Storage
        uriPrefix: `gs://${gcsUri}`,
        // The format to use for the output files, per the MIME types supported in the DICOM spec
        mimeType: 'application/dicom',
      },
    },
  };

  await healthcare.projects.locations.datasets.dicomStores.export(request);
  console.log(`Exported DICOM instances to ${gcsUri}`);
};

exportDicomInstanceGcs();

Python

def export_dicom_instance(project_id, location, dataset_id, dicom_store_id, uri_prefix):
    """Export data to a Google Cloud Storage bucket by copying
    it from the DICOM store.

    See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom
    before running the sample."""
    # Imports the Google API Discovery Service.
    from googleapiclient import discovery

    api_version = "v1"
    service_name = "healthcare"
    # Returns an authorized API client by discovering the Healthcare API
    # and using GOOGLE_APPLICATION_CREDENTIALS environment variable.
    client = discovery.build(service_name, api_version)

    # TODO(developer): Uncomment these lines and replace with your values.
    # project_id = 'my-project'  # replace with your GCP project ID
    # location = 'us-central1'  # replace with the parent dataset's location
    # dataset_id = 'my-dataset'  # replace with the DICOM store's parent dataset ID
    # dicom_store_id = 'my-dicom-store'  # replace with the DICOM store's ID
    # uri_prefix = 'my-bucket'  # replace with a Cloud Storage bucket
    dicom_store_parent = "projects/{}/locations/{}/datasets/{}".format(
        project_id, location, dataset_id
    )
    dicom_store_name = f"{dicom_store_parent}/dicomStores/{dicom_store_id}"

    body = {"gcsDestination": {"uriPrefix": f"gs://{uri_prefix}"}}

    request = (
        client.projects()
        .locations()
        .datasets()
        .dicomStores()
        .export(name=dicom_store_name, body=body)
    )

    response = request.execute()
    print(f"Exported DICOM instances to bucket: gs://{uri_prefix}")

    return response

ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DICOM ์ธ์Šคํ„ด์Šค ๋‚ด๋ณด๋‚ด๊ธฐ

๊ธฐ๋ณธ์ ์œผ๋กœ DICOM ํŒŒ์ผ์„ Cloud Storage๋กœ ๋‚ด๋ณด๋‚ด๋ฉด DICOM ์ €์žฅ์†Œ์˜ ๋ชจ๋“  DICOM ํŒŒ์ผ์ด ๋‚ด๋ณด๋‚ด์ง‘๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ DICOM ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ BigQuery๋กœ ๋‚ด๋ณด๋‚ด๋ฉด DICOM ์ €์žฅ์†Œ์˜ ๋ชจ๋“  DICOM ๋ฐ์ดํ„ฐ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ๋‚ด๋ณด๋‚ด์ง‘๋‹ˆ๋‹ค.

ํ•„ํ„ฐ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๋ฐ์ดํ„ฐ ๋˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„ํ„ฐ ํŒŒ์ผ ๊ตฌ์„ฑ

  • ํ•„ํ„ฐ ํŒŒ์ผ์˜ ๊ฐ ์ค„์€ ์—ฐ๊ตฌ, ์‹œ๋ฆฌ์ฆˆ ๋˜๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ •์˜ํ•˜๊ณ  /studies/STUDY_INSTANCE_UID/series/SERIES_INSTANCE_UID/instances/INSTANCE_UID ํ˜•์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์„ ์„ ์ž˜๋ผ ํ•„ํ„ฐ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ์ˆ˜์ค€์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด /studies/STUDY_INSTANCE_UID๋ฅผ ์ง€์ •ํ•˜์—ฌ ์ „์ฒด ์—ฐ๊ตฌ๋ฅผ ์„ ํƒํ•˜๊ฑฐ๋‚˜ /studies/STUDY_INSTANCE_UID/series/SERIES_INSTANCE_UID๋ฅผ ์ง€์ •ํ•˜์—ฌ ์ „์ฒด ์‹œ๋ฆฌ์ฆˆ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ํ•„ํ„ฐ ํŒŒ์ผ์„ ์˜ˆ๋กœ ๋“ค์–ด ๋ด…์‹œ๋‹ค.

/studies/1.123.456.789
/studies/1.666.333.111/series/123.456
/studies/1.666.333.111/series/567.890
/studies/1.888.999.222/series/123.456/instances/111
/studies/1.888.999.222/series/123.456/instances/222
/studies/1.888.999.222/series/123.456/instances/333

์ด ์˜ˆ์‹œ ํ•„ํ„ฐ ํŒŒ์ผ์€ ๋‹ค์Œ์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • ํ•™์Šต ์ธ์Šคํ„ด์Šค UID๊ฐ€ 1.123.456.789์ธ ์ „์ฒด ํ•™์Šต
  • ํ•™์Šต 1.666.333.111์—์„œ ์‹œ๋ฆฌ์ฆˆ ์ธ์Šคํ„ด์Šค UID๊ฐ€ 123.456 ๋ฐ 567.890์ธ ๊ฐœ๋ณ„ ์‹œ๋ฆฌ์ฆˆ 2๊ฐœ
  • ํ•™์Šต 1.888.999.222 ๋ฐ ์‹œ๋ฆฌ์ฆˆ 123.456์—์„œ ์ธ์Šคํ„ด์Šค ID๊ฐ€ 111, 222, 333์ธ ๊ฐœ๋ณ„ ์ธ์Šคํ„ด์Šค 3๊ฐœ

BigQuery๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„ํ„ฐ ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ

BigQuery๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„ํ„ฐ ํŒŒ์ผ์„ ๋งŒ๋“ค๋ ค๋ฉด ๋จผ์ € DICOM ์Šคํ† ์–ด์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ BigQuery๋กœ ๋‚ด๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ณด๋‚ธ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์—๋Š” DICOM ์Šคํ† ์–ด์— ์žˆ๋Š” DICOM ๋ฐ์ดํ„ฐ์˜ ํ•™์Šต, ์‹œ๋ฆฌ์ฆˆ, ์ธ์Šคํ„ด์Šค UID๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ธ ํ›„ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

  1. ํ•„ํ„ฐ ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•  ์—ฐ๊ตฌ, ์‹œ๋ฆฌ์ฆˆ, ์ธ์Šคํ„ด์Šค์˜ UID๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์ฟผ๋ฆฌ๋Š” ํ•„ํ„ฐ ํŒŒ์ผ ํ˜•์‹ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๊ฒŒ ์—ฐ๊ตฌ, ์‹œ๋ฆฌ์ฆˆ, ์ธ์Šคํ„ด์Šค UID๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

    SELECT CONCAT
        ('/studies/', StudyInstanceUID, '/series/', SeriesInstanceUID, '/instances/', SOPInstanceUID)
    FROM
        [PROJECT_ID:BIGQUERY_DATASET.BIGQUERY_TABLE]
  2. ์„ ํƒ์‚ฌํ•ญ: ์ฟผ๋ฆฌ๊ฐ€ ์ตœ๋Œ€ ์‘๋‹ต ํฌ๊ธฐ๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ํฐ ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ BigQuery์˜ ์ƒˆ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

  3. ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํŒŒ์ผ์— ์ €์žฅํ•˜๊ณ  Cloud Storage๋กœ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค. 2๋‹จ๊ณ„์—์„œ ์ƒˆ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•œ ๊ฒฝ์šฐ ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ํ…Œ์ด๋ธ” ์ฝ˜ํ…์ธ ๋ฅผ Cloud Storage๋กœ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.

  4. ๋‚ด๋ณด๋‚ธ ํŒŒ์ผ์„ ํ•„์š”์— ๋”ฐ๋ผ ์ˆ˜์ •ํ•œ ํ›„ ์š”์ฒญ์— ํฌํ•จํ•˜์—ฌ ์—ฌ๋Ÿฌ DICOM ๊ฐ์ฒด์˜ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜๋™์œผ๋กœ ํ•„ํ„ฐ ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ

ํ•„ํ„ฐ ํŒŒ์ผ์„ ์ˆ˜๋™์œผ๋กœ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

  1. ํ•„ํ„ฐ๋งํ•  DICOM ๊ฐ์ฒด๊ฐ€ ํฌํ•จ๋œ ํ•„ํ„ฐ ํŒŒ์ผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  2. ํ•„ํ„ฐ ํŒŒ์ผ์„ Cloud Storage์— ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์•ˆ๋‚ด๋Š” ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ ๊ฐ์ฒด ์—…๋กœ๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

ํ•„ํ„ฐ ํŒŒ์ผ ์ „๋‹ฌ

ํ•„ํ„ฐ ํŒŒ์ผ์„ ๋งŒ๋“  ํ›„ DICOM ๋‚ด๋ณด๋‚ด๊ธฐ ์ž‘์—…์„ ํ˜ธ์ถœํ•˜๊ณ  REST API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„ํ„ฐ ํŒŒ์ผ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ƒ˜ํ”Œ์€ ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

gcloud

ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ Cloud Storage๋กœ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด gcloud beta healthcare dicom-stores export gcs ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

gcloud beta healthcare dicom-stores export gcs DICOM_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --gcs-uri-prefix=gs://DESTINATION_BUCKET/DIRECTORY \
  --filter-config-gcs-uri=gs://BUCKET/DIRECTORY/FILTER_FILE

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • DICOM_STORE_ID: DICOM ์ €์žฅ์†Œ์˜ ์‹๋ณ„์ž์ž…๋‹ˆ๋‹ค.
  • DATASET_ID: DICOM ์ €์žฅ์†Œ์˜ ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • LOCATION: DICOM ์ €์žฅ์†Œ์˜ ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ ์œ„์น˜์ž…๋‹ˆ๋‹ค.
  • DESTINATION_BUCKET/DIRECTORY: ๋Œ€์ƒ Cloud Storage ๋ฒ„ํ‚ท์ž…๋‹ˆ๋‹ค.
  • BUCKET/DIRECTORY/FILTER_FILE: Cloud Storage ๋ฒ„ํ‚ท์—์„œ ํ•„ํ„ฐ ํŒŒ์ผ์˜ ์œ„์น˜์ž…๋‹ˆ๋‹ค.

์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Request issued for: [DICOM_STORE_ID]
Waiting for operation [projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID] to complete...done.
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID

์ž‘์—… ์ƒํƒœ๋ฅผ ๋ณด๋ ค๋ฉด gcloud healthcare operations describe ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‘๋‹ต์—์„œ OPERATION_ID๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

gcloud healthcare operations describe OPERATION_ID \
  --location=LOCATION \
  --dataset=DATASET_ID

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • OPERATION_ID: ์ด์ „ ์‘๋‹ต์—์„œ ๋ฐ˜ํ™˜๋œ ID ๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค.
  • DATASET_ID: DICOM ์ €์žฅ์†Œ์˜ ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • LOCATION: DICOM ์ €์žฅ์†Œ์˜ ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ ์œ„์น˜์ž…๋‹ˆ๋‹ค.

์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

done: true
metadata:
'@type': type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata
apiMethodName: google.cloud.healthcare.v1beta1.dicom.DicomService.ExportDicomData
counter:
  success: SUCCESSFUL_INSTANCES
  failure: FAILED_INSTANCES
createTime: 'CREATE_TIME'
endTime: 'END_TIME'
logsUrl: 'https://console.cloud.google.com/logs/query/CLOUD_LOGGING_URL'
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID
response:
'@type': '...'

API

ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด projects.locations.datasets.dicomStores.export ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

curl

ํ•„ํ„ฐ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด POST ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋‹ค์Œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ์ด๋ฆ„ ๋ฐ ์œ„์น˜
  • DICOM ์ €์žฅ์†Œ์˜ ์ด๋ฆ„
  • ๋Œ€์ƒ Cloud Storage ๋ฒ„ํ‚ท์ž…๋‹ˆ๋‹ค.
  • Cloud Storage ๋ฒ„ํ‚ท์—์„œ ํ•„ํ„ฐ ํŒŒ์ผ ์œ„์น˜

๋‹ค์Œ ์ƒ˜ํ”Œ์€ curl์„ ์‚ฌ์šฉํ•˜๋Š” POST ์š”์ฒญ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    --data "{
      'gcsDestination': {
        'uriPrefix': 'gs://BUCKET/DIRECTORY'
      },
      'filterConfig': {
        'resourcePathsGcsUri': 'gs://BUCKET/DIRECTORY/FILTER_FILE'
      }
    }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:export"

์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ JSON ํ˜•์‹์˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_ID"
}

์‘๋‹ต์— ์ž‘์—… ์ด๋ฆ„์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ž‘์—… get ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—… ์ƒํƒœ๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_NAME"

์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ JSON ํ˜•์‹์˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1beta1.dicom.DicomService.ExportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME"
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

PowerShell

ํ•„ํ„ฐ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ DICOM ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ด๋ ค๋ฉด POST ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋‹ค์Œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒ์œ„ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ์ด๋ฆ„ ๋ฐ ์œ„์น˜
  • DICOM ์ €์žฅ์†Œ์˜ ์ด๋ฆ„
  • ๋Œ€์ƒ Cloud Storage ๋ฒ„ํ‚ท์ž…๋‹ˆ๋‹ค.
  • Cloud Storage ๋ฒ„ํ‚ท์—์„œ ํ•„ํ„ฐ ํŒŒ์ผ ์œ„์น˜

๋‹ค์Œ ์ƒ˜ํ”Œ์€ Windows PowerShell์„ ์‚ฌ์šฉํ•œ POST ์š”์ฒญ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

$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 "{
    'gcsDestination': {
      'uriPrefix': 'gs://BUCKET/DIRECTORY'
    },
    'filterConfig': {
      'resourcePathsGcsUri': 'gs://BUCKET/DIRECTORY/FILTER_FILE'
  }" `
  -Uri "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:export" | Select-Object -Expand Content

์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ JSON ํ˜•์‹์˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_ID"
}

์‘๋‹ต์— ์ž‘์—… ์ด๋ฆ„์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ž‘์—… get ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—… ์ƒํƒœ๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.

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

Invoke-WebRequest `
  -Method Get `
  -Headers $headers `
  -Uri "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_NAME" | Select-Object -Expand Content

์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๋Š” JSON ํ˜•์‹์˜ ์ž‘์—… ์ƒํƒœ๊ฐ€ ํฌํ•จ๋œ ๋‹ค์Œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1beta1.dicom.DicomService.ExportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME"
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

DICOM ๋‚ด๋ณด๋‚ด๊ธฐ ์š”์ฒญ ๋ฌธ์ œ ํ•ด๊ฒฐ

DICOM ๋‚ด๋ณด๋‚ด๊ธฐ ์š”์ฒญ ์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ Cloud Logging์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud Logging์—์„œ ์˜ค๋ฅ˜ ๋กœ๊ทธ ๋ณด๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ „์ฒด ์ž‘์—…์ด ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—… ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”.