# hl7gateway

This is the samedi HL7 interface application.

[![pipeline status](https://git.samedi.cc/dev/hl7gateway/badges/main/pipeline.svg)](https://git.samedi.cc/dev/hl7gateway/commits/main)
[![coverage report](https://git.samedi.cc/dev/hl7gateway/badges/main/coverage.svg)](https://git.samedi.cc/dev/hl7gateway/commits/main)

It is an application that is installed on premises. It sends and receives HL7 messages. It implements small parts of HL7 2.8 (Scheduling and Patient Synchronisation) A copy of the standard can be found [here](https://git.samedi.cc/levin.alexander/hl7-standards/tree/master/2.8.2).

## Installing and testing hl7gateway on Windows

To get the latest version, visit https://hl7gateway.samedi.de/hl7gateway/. For older versions, download a given package from https://git.samedi.cc/dev/hl7gateway/-/pipelines?page=1&scope=tags.

Uninstall the old version first and then install the desired version.

To test samedi hl7gateway do the following:

- Install the program with the msi installer.
- This creates a batch file `start-hl7gateway.bat` in `"%ProgramData%\samedi HL7Gateway"` when you first run this file it creates an example configuration `hl7gateway.toml`.
- Edit this configuration file with a text editor to add your samedi username and password.
- Start `hl7listener.exe` from `"%PROGRAMFILES(X86)%\samedi HL7Gateway\utils"` to show received messages on your console.
- Run `start-hl7gateway.bat` again. You should now see all changes in your configured samedi account in the hl7listener output.

## User-facing documentation

- There is a support-website, https://hl7gateway.samedi.de for user-facing documentation. This is built from the `website` directory. It is built in CI using hugo. Run `make website` to rebuild.
- See the hl7gateway [README](cmd/hl7gateway/README.md) for User-facing application documentation.
- See [CHANGELOG](CHANGELOG.md) for user-facing changes by released version.

## Developing hl7gateway

Most code here is written in [Go](https://golang.org). Minimal supported version is v1.17. Production builds on CI are done using v1.17. ((this is set in `.gitlab-ci.yaml`)

Go can be installed from your package manager or [golang.org/doc/install](https://golang.org/doc/install) in case your operating system doesn't ship with a recent enough version.

This uses Go Modules. The GOPATH environment variable must not be set. Package dependencies should be vendored with `go mod vendor`

Tests are run with `make test`.

To update go modules, you need to configure `go get` to be able to use git.samedi.cc.

```sh
git config --global url."[git@git.samedi.cc:22277]:".insteadOf "https://git.samedi.cc"
```

You might also need to disable module verification:

```sh
export GONOSUMDB="git.samedi.cc"
export GOPRIVATE="git.samedi.cc
```

If you see errors related to host hey mismatch, ensure that `ssh` trusts the gitlab server, run `ssh -p 22277 git.samedi.cc` to add the host keys to `~/.ssh/known_hosts`

### Releasing a new version

To release a new Version of `hl7gateway`:

- On any branch, ensure CHANGELOG is up-to-date.
- In case changes need to be made, create a new branch and get it reviewed and merged.
- Then, create a new tag (`git tag v1.2.3`) and push it (`git push --tags`) (or [create a tag in GitLab](https://git.samedi.cc/dev/hl7gateway/tags))
- CI will build the new version in the `package` step (like [here](https://git.samedi.cc/dev/hl7gateway/-/jobs/1703828)), after that:
  - the windows installer will be uploaded to `https://hl7gateway.samedi.de/dist/hl7gateway-x.y.x.msi`
  - a macOS build will be uploaded to `https://hl7gateway.samedi.de/dist/samedi-hl7gateway-darwin_all-x.y.x.tgz`
- Communicate release of the new version to users.

### Run hl7gateway locally in developer mode

By default the hl7gateway.dev.example.toml is using staging as an endpoint, remember to update it to use the locally running instance.

Before running the hl7gateway, make sure that admin-auto-otto on platform app does not have 2FA enabled, otherwise gateway cannot connect to the endpoint.
You can see it in Settings => Instutition => Account setup => Two factor authentication settings.
Make sure "Enable two factor authentication" is not ticked on.

#### Documentation

- The HL7 standard documents are at [levin.alexander/hl7](https://git.samedi.cc/levin.alexander/hl7-standards/tree/master/2.8.2/HL7%20Messaging%20Version%202.8.2/PDF) We're writing to the latest version but strive to maintain compatibility with [v2.5.1](https://git.samedi.cc/levin.alexander/hl7-standards/tree/master/2.5.1/HL7_Messaging_v251_PDF) because that version is used as the "Basisprofil" in Germany (http://wiki.hl7.de/index.php?title=Deutsche_Profilübersicht).

#### Run hl7gateway

There is a helper script `./script/server` which compiles and runs `hl7gateway` with the `hl7gateway.dev.toml` configuration file.

To run the `./script/server` use following command

```sh
./script/server run
```

#### Run hl7listener

There is a program, `hl7listener`, that listens on a TCP-port and prints and acknowledges all received HL7 messages.

```sh
go build ./cmd/hl7listener && ./hl7listener -address :2020
```

HL7Listener can simulate a master patient index and respond to PIX (Patient identifier cross reference) queries.
There is a command line option `--patientIdentifiers <filename>` which allows to reference a file. (e.g. `./hl7listener.exe --patientIdentifiers identifiers.txt`)

That file should contain, in each line a group of patient identifiers that belong to the same person.

Identifiers in each line are separated by spaces, each identifier consists of system and value separated by a comma:

```txt
urn:oid:1.3.6.1.4.1.9784.999200.2.1,12345 urn:oid:1.3.6.1.4.1.9784.999200.2.2,6789
urn:oid:1.3.6.1.4.1.9784.999200.1.4,abcd urn:oid:1.3.6.1.4.1.9784.999200.1.5,p123 urn:oid:1.3.6.1.4.1.9784.999200.23.1,q456
```

#### Sending a message to samedi

To send test messages to `hl7gateway` use `hl7send`. There are some example messages in the `hl7/testdata` directory.

```sh
go build ./cmd/hl7send && ./hl7send my-hl7-message.txt.hl7
```

#### TLS/mTLS

To generate the certificates needed to test TLS connections, use:

```sh
./script/make_test_certificates
```

`hl7send` and `hl7listener` take a `-tls` flag that enables TLS and uses these certificates automatically.

## High-Level Package Overview

This repository contains multiple packages:

- `api-adapter` — generate HL7 messages from samedi API objects and vice-versa
- `hl7` — parse and generate HL7 messages
- `samedi`
  - `samedi/accounts` — manage multiple simultaneous API connections to different accounts
  - `samedi/api` — main samedi HTTP API
- `util`
  - `util/rest` — JSON-over-HTTP utility package
  - `util/urlutil` — evaluate urltemplates

## Windows Installer

The GitLab CI build generates a signed MSI setup file using `script/generate-msi`.

## Testing iMedOne locally

In order to test iMedOne integration, you need three things:

- The iMedOne sandbox server (port `:9002`) which receives appointments from samedi platform
- Hl7gateway with imedOne configuration (it should be configured to listen for incoming requests on port `:8086`)
- To update appointments in platform, you can submit iMedOne webhooks

```sh
# start the sandbox server
# Note: listenAddr here refers the port in variable base_api_endpoint in imedone configuration, make sure they are the same
go run ./cmd/imedone_sandbox/main.go run --listenAddr :9002

# start hl7gateway
go run ./cmd/hl7gateway/main.go run --config imedone.dev.example.toml
```

The commands above is enough to sync Platform -> iMedOne direction.

But iMedOne can communicate back to platform via webhooks, to have that
direction (iMedOne -> Platform) we have extended our sandbox to simulate those
webhooks, you can check how to use with the examples below.

```sh
# create appointments in samedi platform
go run ./cmd/imedone_sandbox/main.go createAppointment --patientXref patient-xref --appointmentId 1 --appointmentType impf --appointmentTime 2021-07-14T12:00

# cancel appointments
go run ./cmd/imedone_sandbox/main.go cancelAppointment --appointmentId 124

# show help output for available subcommands and flags
go run ./cmd/imedone_sandbox/main.go --help
```

#### Run FHIR Subscription Test Tools

There are two testing tools available for FHIR subscriptions:

**fhir_webhook_listener** - A test tool that listens for FHIR webhook subscription notifications. It starts an HTTP server that can receive webhook notifications from a FHIR server.

```sh
go build ./cmd/fhir_webhook_listener && ./fhir_webhook_listener run --port 8080 --path /webhook
```

**fhir_websocket_listener** - A test tool that connects to a FHIR server's websocket endpoint to listen for subscription notifications. It establishes a WebSocket connection and binds to a specific subscription.

```sh
go build ./cmd/fhir_websocket_listener && ./fhir_websocket_listener run --endpoint ws://localhost:8081/websocket --subscription-id your-subscription-id --token your-bearer-token
```

These tools are useful for testing FHIR subscription functionality and debugging subscription notifications.
