Files
go-ohif-proxy/README.md

12 KiB

GO-OHIF-Proxy

1. Gambaran Umum

Tujuan

App ini dibuat untuk menyalurkan dicomWeb request dari OHIF ke Google Healthcare. Proxy berperan hanya sebagai authenticator ke Google dengan service-account.json, tanpa merubah / menambah request

Berikut adalah cara clone project ini:

2. Alur Kerja Aplikasi

+----------------+      +----------------+      +----------------------+
|                |      |                |      |                      |
|  OHIF Viewer   |----->| GO-OHIF-Proxy |----->| Google Healthcare    |
|  (Web Client)  |<-----|                |<-----| DICOM API            |
|                |      |                |      |                      |
+----------------+      +----------------+      +----------------------+
  1. Permintaan Klien: OHIF Viewer mengirimkan permintaan DICOMweb (misalnya, untuk mengambil studi).
  2. Pemrosesan Proxy:
    • Proxy mencegat permintaan.
    • Menambahkan header autentikasi yang sesuai.
    • Meneruskan permintaan ke Google Cloud Healthcare API.
  3. Pemrosesan Google Cloud: Healthcare API memproses permintaan DICOM.
  4. Penanganan Respons: Proxy meneruskan respons kembali ke klien.

2b. Arsitektur

go-ohif-proxy/
│
├── cmd/
│   └── server/           # Application entry point
│       └── main.go       # Main server initialization
│
├── config/               # Configuration management
│   ├── config.go         # Configuration loader
│   └── config.yaml       # Application configuration
│
├── credentials/          # Authentication credentials
│   └── service-account.json  # Google Cloud service account
│
├── internal/
│   ├── api/              # API endpoints
│   │   ├── handler.go    # HTTP request handlers
│   │   ├── middleware.go # Request middleware
│   │   └── routes.go     # API route definitions
│   │
│   ├── auth/             # Authentication services
│   │   └── google.go     # Google Cloud authentication
│   │
│   ├── proxy/            # Proxy service
│   │   └── dicomweb.go   # DICOMweb request handling
│   │
│   └── utils/            # Utility functions
│       ├── http.go       # HTTP utilities
│       └── logger.go     # Logging functionality
│
├── test/                 # Testing resources
│   └── http/             # HTTP test requests
│
├── Dockerfile            # Container definition
├── docker-compose.yml    # Multi-container orchestration
├── go.mod                # Go module definition
├── go.sum                # Module dependency checksums
└── README.md             # Project documentation

2c. Alur Kerja Kode

Secara umum kode di repo ini kurang lebih memiliki alur:

Routes --> Handlers --> Service --> Repository

3. Instalasi dan Penggunaan

Prasyarat

  • Go versi 1.19 atau lebih tinggi.
  • Akun Google Cloud dengan Healthcare API diaktifkan.
  • Kredensial akun layanan dengan akses ke DICOM store.

Clone dan Setup

# Clone repositori
git clone https://devone.aplikasi.web.id/gitea/mario/go-ohif-proxy.git
cd go-ohif-proxy

# Install dependencies
go mod download

Konfigurasi

  1. Salin file konfigurasi contoh:

    cp config/config.yaml.example config/config.yaml
    
  2. Edit config/config.yaml sesuai kebutuhan:

    server:
      port: 5555
      read_timeout_seconds: 30
      write_timeout_seconds: 30
      idle_timeout_seconds: 60
    
    log_level: "info"  # debug, info, warn, error
    
    google:
      project_id: "id-proyek-gcp-anda"
      location: "lokasi-anda"
      dataset: "nama-dataset-anda"
      dicom_store: "nama-dicom-store-anda"
      credentials_path: "./credentials/service-account.json"
    
    allowed_origins:
      - "http://localhost:3000"  # URL OHIF Viewer
    
  3. Letakkan kredensial akun layanan Google Cloud Anda di credentials/service-account.json.

Menjalankan Aplikasi

Build dan Jalankan Secara Langsung

# Build aplikasi
go build -o ohif-proxy ./cmd/server

# Jalankan aplikasi
./ohif-proxy

Menggunakan Docker

# Build image Docker
docker build -t go-ohif-proxy .

# Jalankan dengan Docker
docker run -p 5555:5555 -v $(pwd)/config:/app/config -v $(pwd)/credentials:/app/credentials go-ohif-proxy

Menggunakan Docker Compose

docker-compose up

Run Aplikasi Tanpa Build

  1. Transfer ./ohif-proxy ke server tujuan. Contoh:
    scp ohif-proxy pacs@152.42.173.210:/home/pacs/google-ohif-proxy
    
  2. Pastikan server tujuan terinstall go versi >1.19. Cek dengan:
  3. Buat direktori:
    mkdir -p ~/google-ohif-proxy
    mkdir -p ~/google-ohif-proxy/config
    mkdir -p ~/google-ohif-proxy/credentials
    
  4. Tambahkan config.go dan config.yaml.
    scp -r config/* pacs@152.42.173.210:/home/pacs/google-ohif-proxy/config/
    
  5. Tambahkan credential /credentials/service-account.json
    nano credentials/service-account.json
    # atau
    # scp dari local
    

Pengujian

Aplikasi ini menyertakan permintaan HTTP uji di direktori test/http yang dapat digunakan dengan klien REST seperti ekstensi REST Client di VSCode.

# Jalankan pengujian yang disertakan
make test

Untuk informasi lebih lanjut tentang OHIF: https://ohif.org/ Untuk informasi lebih lanjut tentang Google Cloud Healthcare API: https://cloud.google.com/healthcare

GO-OHIF-Proxy Architecture

Project Structure

go-ohif-proxy/
├── cmd/
│   └── server/              # Application entry point
│       └── main.go          # Main function and application start
│
├── config/                  # Configuration 
│   ├── config.go            # Config structure definitions
│   └── config.yaml          # YAML configuration file
│
├── credentials/             # Authentication credentials
│   └── service-account.json # Google service account credentials
│
├── internal/                # Internal packages (not importable)
│   ├── api/                 # API implementation
│   │   ├── handlers/        # HTTP request handlers
│   │   │   ├── auth.go      # Authentication handlers
│   │   │   ├── dicom.go     # DICOM request handlers
│   │   │   └── healthcheck.go # Health check endpoint
│   │   │
│   │   ├── middleware/      # HTTP middleware
│   │   │   ├── auth.go      # Authentication middleware
│   │   │   └── logging.go   # Request logging middleware
│   │   │
│   │   ├── models/          # Data models
│   │   │   └── user.go      # User and authentication models
│   │   │
│   │   ├── repository/      # Data access layer
│   │   │   ├── interfaces.go # Repository interfaces
│   │   │   └── mysql_repository.go # MySQL implementation
│   │   │
│   │   ├── service/         # Business logic 
│   │   │   ├── auth_service.go # Authentication service
│   │   │   └── db_repository.go # Legacy repository code (to be removed)
│   │   │
│   │   └── routes.go        # API route definitions
│   │
│   ├── auth/                # Authentication utilities
│   │   ├── google.go        # Google authentication client
│   │   └── jwt.go           # JWT generation and validation
│   │
│   ├── logger/              # Logging utilities
│   │   └── logger.go        # Logger configuration
│   │
│   └── proxy/               # DICOM web proxy functionality
│       └── client.go        # Google Healthcare API client
│
├── pkg/                     # Public packages (importable)
│
├── test/                    # Test files
│   └── http/                # HTTP test requests
│       ├── ohif-flow.http   # OHIF workflow tests
│       └── test.http        # General API tests
│
├── docker-compose.yaml      # Docker Compose configuration
├── Dockerfile               # Docker build instructions
├── go.mod                   # Go module definition
├── go.sum                   # Go module checksums
├── Makefile                 # Build automation
└── README.md                # Project documentation

Architecture Diagram

graph TD
    subgraph Client
        OHIF[OHIF Viewer]
    end

    subgraph API_Gateway
        Router[Chi Router]
        Auth_MW[Auth Middleware]
        Logging_MW[Logging Middleware]
        CORS_MW[CORS Middleware]
        PatientView_MW[Patient View Restriction]
    end

    subgraph Services
        AuthService[Auth Service]
        DicomService[DICOM Service]
    end

    subgraph Repositories
        UserRepo[User Repository]
        TokenRepo[Token Repository]
        PatientRepo[Patient Repository]
        DoctorRepo[Doctor Repository]
    end

    subgraph External
        GoogleHealthcare[Google Healthcare API]
        MySQL[MySQL Database]
    end

    subgraph Utilities
        JWTManager[JWT Manager]
        GoogleAuth[Google Auth Client]
        Logger[Logger]
    end

    OHIF -->|HTTP Requests| Router
    Router --> Auth_MW
    Auth_MW --> Logging_MW
    Logging_MW --> CORS_MW
    CORS_MW --> PatientView_MW
    PatientView_MW --> DicomService

    Router -->|Auth Routes| AuthService
    AuthService -->|Uses| JWTManager
    AuthService -->|Uses| UserRepo
    AuthService -->|Uses| TokenRepo

    DicomService -->|Uses| GoogleHealthcare
    DicomService -->|Uses| PatientRepo

    UserRepo -->|Implements| MySQL
    TokenRepo -->|Implements| MySQL
    PatientRepo -->|Implements| MySQL
    DoctorRepo -->|Implements| MySQL

    DicomService -->|Uses| GoogleAuth
    GoogleAuth -->|Authenticates| GoogleHealthcare

Authentication Flow

sequenceDiagram
    participant Client
    participant API as API Gateway
    participant AuthService
    participant Repo as Repository
    participant JWT as JWT Manager
    participant DB as Database

    Client->>API: POST /auth/login
    API->>AuthService: Login(email, password)
    
    alt Database Auth Enabled
        AuthService->>Repo: GetUserByEmail(email)
        Repo->>DB: SELECT * FROM users
        DB->>Repo: User Data
        Repo->>AuthService: User Object
        AuthService->>JWT: Generate Tokens
        JWT->>AuthService: Access + Refresh Tokens
        AuthService->>Repo: StoreRefreshToken()
        Repo->>DB: INSERT INTO refresh_tokens
    else Hardcoded Auth
        AuthService->>JWT: Generate Tokens
        JWT->>AuthService: Access + Refresh Tokens
    end
    
    AuthService->>API: Tokens + User Info
    API->>Client: Auth Response
    
    Note over Client,API: Later - Protected Request
    
    Client->>API: GET /dicomWeb/* with Bearer Token
    API->>AuthService: ValidateToken()
    AuthService->>JWT: ParseToken()
    JWT->>AuthService: Claim Data
    AuthService->>API: User Context
    API->>Client: Protected Resource

DICOM Request Flow

sequenceDiagram
    participant Client
    participant API as API Gateway
    participant Auth as Auth Middleware
    participant PatientMW as Patient Restriction MW
    participant DicomHandler
    participant GCP as Google Healthcare API

    Client->>API: GET /dicomWeb/studies/{studyUID}
    
    alt Whitelisted Path
        API->>DicomHandler: Forward Request (Skip Auth)
    else Protected Path
        API->>Auth: Check Authentication
        Auth->>API: User Context
        API->>PatientMW: Check Access Rights
        
        alt Patient Role
            PatientMW->>Repo: IsStudyAssignedToPatient()
            Repo->>PatientMW: Access Result
            alt Study Assigned
                PatientMW->>DicomHandler: Forward Request
            else Study Not Assigned
                PatientMW->>Client: 403 Forbidden
            end
        else Doctor Role
            PatientMW->>DicomHandler: Forward Request
        end
    end
    
    DicomHandler->>GCP: Forward Request to DICOM Store
    GCP->>DicomHandler: DICOM Data
    DicomHandler->>Client: DICOM Response