ID: S202606091028
Status: imported
Tags: avans 2-4 LU1
OpenMRS Plugin (Windows) - Setup Guide
Overview
IMPORTANT
This document was converted from thelinux setup guide using AI (look at my reasoning for using Linux to understand why I daily drive Linux) so commands it says might not be 100% accurate or fully functional.
The bahmni.appointment.forwarder plugin is an OpenMRS OMOD that intercepts Bahmni appointment events and forwards them to a central RabbitMQ broker. This guide covers setup on Windows using PowerShell and Docker Desktop.
All commands in this guide use PowerShell. Do not use Command Prompt (cmd.exe) as it does not support the syntax used here.
Prerequisites
Required software
| Software | Download | Purpose |
|---|---|---|
| Java JDK 21 | adoptium.net | Running OpenMRS and building the plugin |
| Maven 3.x | maven.apache.org | Building the plugin |
| Git | git-scm.com | Cloning repositories |
| Docker Desktop | docker.com | Running OpenMRS locally |
| Python 3 | python.org | Reading RabbitMQ messages during testing |
Verify installations
Open PowerShell and run:
java -version
mvn -version
git --version
docker --version
docker compose version
python --versionAll commands should return version information without errors.
Set JAVA_HOME
Maven requires JAVA_HOME to be set. In PowerShell:
[System.Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\Program Files\Eclipse Adoptium\jdk-21.0.0.37-hotspot", "Machine")Replace the path with your actual JDK installation path. Restart PowerShell after setting this.
Building the Dependencies
The plugin requires two OpenMRS modules to be built locally before the plugin itself can be built.
Build the event module
cd C:\Users\YourName\Repositories
git clone https://github.com/openmrs/openmrs-module-event.git
cd openmrs-module-event
mvn clean install -DskipTestsBuild the appointments module
cd C:\Users\YourName\Repositories
git clone https://github.com/Bahmni/openmrs-module-appointments.git openmrs-module-appointments-2.1
cd openmrs-module-appointments-2.1
git checkout 2.1.0
mvn clean install -DskipTestsBoth builds should end with BUILD SUCCESS.
Building the Plugin
cd AvansModuleOpenMRS\bahmni.appointment.forwarder
mvn clean install -DskipTestsThe OMOD file is generated at:
omod\target\bahmni.appointment.forwarder-1.0.0-SNAPSHOT.omod
Deploying to OpenMRS
Step 1, Clone the OpenMRS distribution
cd C:\Users\YourName\Desktop
git clone https://github.com/openmrs/openmrs-distro-referenceapplication.git OpenMRSLocally
cd OpenMRSLocallyStep 2, Set up the modules folder
New-Item -ItemType Directory -Path modules -Force
Copy-Item "C:\Users\YourName\Repositories\AvansModuleOpenMRS\bahmni.appointment.forwarder\omod\target\bahmni.appointment.forwarder-1.0.0-SNAPSHOT.omod" -Destination "modules\"Step 3, Update docker-compose.yml
Open docker-compose.yml in a text editor and find the volumes block under the backend service. Add the bind mount line:
volumes:
- openmrs-data:/openmrs/data
- ./modules/bahmni.appointment.forwarder-1.0.0-SNAPSHOT.omod:/openmrs/distribution/openmrs_modules/bahmni.appointment.forwarder-1.0.0-SNAPSHOT.omodThe bind mount uses forward slashes even on Windows. Docker Desktop handles the path conversion automatically.
Do not copy the OMOD directly into /openmrs/data/modules/ as it will be wiped on every restart.
Step 4, Start OpenMRS
docker compose up -dWait approximately 3 minutes for OpenMRS to fully start. Monitor startup with:
docker logs -f (docker ps --filter name=backend -q) 2>$nullOr filter for relevant lines:
docker logs (docker ps --filter name=backend -q) 2>$null | Select-String "done refreshing|forwarder|started"Once you see the following lines the plugin is loaded:
=== BAHMNI APPOINTMENT FORWARDER CONTEXT REFRESHED ===
=== BAHMNI APPOINTMENT FORWARDER STARTED ===
Configuring Global Properties
The plugin reads all its configuration from OpenMRS global properties. Set them directly in the database after the first startup.
First get the database container name:
docker ps --format "{{.Names}}"Look for the container with db in its name, for example openmrs-distro-referenceapplication-main-db-1. Then run:
docker exec openmrs-distro-referenceapplication-main-db-1 `
mysql -u openmrs -popenmrs openmrs -e "
INSERT INTO global_property (property, property_value, description, uuid) VALUES
('communicatie.tenantId', 'your-tenant-id', 'Tenant identifier', UUID()),
('communicatie.rabbitmq.host', 'your-host', 'RabbitMQ host', UUID()),
('communicatie.rabbitmq.port', '5672', 'RabbitMQ port', UUID()),
('communicatie.rabbitmq.username','your-username', 'RabbitMQ username', UUID()),
('communicatie.rabbitmq.password','your-password', 'RabbitMQ password', UUID())
ON DUPLICATE KEY UPDATE property_value=VALUES(property_value);" 2>$nullReplace the container name and placeholder values:
| Property | Example | Description |
|---|---|---|
communicatie.tenantId | hospital-amsterdam | Unique ID for this OpenMRS instance |
communicatie.rabbitmq.host | 86.48.5.113 | IP or hostname of the RabbitMQ server |
communicatie.rabbitmq.port | 5672 | AMQP port |
communicatie.rabbitmq.username | communicatie | RabbitMQ username |
communicatie.rabbitmq.password | yourpassword | RabbitMQ password |
Verify the properties were saved:
docker exec openmrs-distro-referenceapplication-main-db-1 `
mysql -u openmrs -popenmrs openmrs `
-e "SELECT property, property_value FROM global_property WHERE property LIKE 'communicatie%';" 2>$nullStep 5, Restart to apply properties
docker compose restart backendWait for OpenMRS to start again. You should now see the RabbitMQ connection confirmed:
=== BAHMNI APPOINTMENT FORWARDER STARTED ===
=== CONNECTED TO RABBITMQ AT your-host:5672 ===
Verifying the Setup
Check the exchange exists
curl -s -u 'username:password' `
'http://your-rabbitmq-host:15672/api/exchanges/%2F/appointment.exchange'A JSON response confirms the plugin connected. A 404 means the plugin has not connected yet.
Create a test queue binding
curl -s -u 'username:password' `
-X PUT 'http://your-rabbitmq-host:15672/api/queues/%2F/debug.queue' `
-H 'Content-Type: application/json' `
-d '{"durable":true,"auto_delete":false}'
curl -s -u 'username:password' `
-X POST 'http://your-rabbitmq-host:15672/api/bindings/%2F/e/appointment.exchange/q/debug.queue' `
-H 'Content-Type: application/json' `
-d '{"routing_key":"appointment.#"}'Create a test appointment
curl -s -u admin:Admin123 -X POST `
'http://localhost/openmrs/ws/rest/v1/appointment' `
-H 'Content-Type: application/json' `
-d '{
"patientUuid": "YOUR_PATIENT_UUID",
"serviceUuid": "YOUR_SERVICE_UUID",
"startDateTime": "2026-06-01T10:00:00.000Z",
"endDateTime": "2026-06-01T10:30:00.000Z",
"appointmentKind": "Scheduled",
"status": "Scheduled"
}'Read the message from the queue
$response = curl -s -u 'username:password' `
-X POST 'http://your-rabbitmq-host:15672/api/queues/%2F/debug.queue/get' `
-H 'Content-Type: application/json' `
-d '{"count":1,"ackmode":"ack_requeue_true","encoding":"auto"}'
$data = $response | ConvertFrom-Json
if ($data -is [array] -and $data.Count -gt 0) {
$data[0].payload | ConvertFrom-Json | ConvertTo-Json -Depth 10
}Redeploying After Code Changes
After rebuilding the plugin, run these commands to deploy the new OMOD:
# Copy new OMOD to modules folder
Copy-Item "C:\Users\YourName\Repositories\AvansModuleOpenMRS\bahmni.appointment.forwarder\omod\target\bahmni.appointment.forwarder-1.0.0-SNAPSHOT.omod" `
-Destination "modules\" -Force
# Clear the OpenMRS lib cache for the plugin
$volumePath = docker inspect openmrs-distro-referenceapplication-main-backend-1 `
--format='{{range .Mounts}}{{if eq .Destination "/openmrs/data"}}{{.Source}}{{end}}{{end}}'
Remove-Item -Recurse -Force "$volumePath\.openmrs-lib-cache\bahmni.appointment.forwarder" -ErrorAction SilentlyContinue
# Restart the backend
docker restart openmrs-distro-referenceapplication-main-backend-1If the volume path command does not work, find the volume mount path manually in Docker Desktop under Volumes, or use docker inspect and look for the Mounts section.
Message Format
Every appointment create or reschedule publishes the following JSON payload to appointment.exchange:
{
"tenantId": "hospital-amsterdam",
"eventType": "BAHMNI_APPOINTMENT_CREATED",
"timestamp": "2026-05-20T13:28:00Z",
"appointmentUuid": "ad37be8a-227d-4486-8862-513dafb9fe77",
"appointmentNumber": "0000",
"appointmentKind": "Scheduled",
"patientUuid": "c35a048b-c311-4f5d-8a21-322f469d16e3",
"patientName": "Richard Nelson",
"patientIdentifier": "10001LL",
"phoneNumber": "+31612345678",
"emailAddress": "richard.nelson@test.com",
"startDateTime": "2026-05-31T10:00:00Z",
"endDateTime": "2026-05-31T10:30:00Z",
"serviceName": "General Medicine",
"serviceUuid": "3bd2766b-538d-11f1-a6ad-a2e877b8b22b",
"status": "Scheduled",
"comments": null,
"voided": false
}Routing key format: appointment.{tenantId}.{eventType}
Event types:
BAHMNI_APPOINTMENT_CREATED, fired whenvalidateAndSaveis calledBAHMNI_APPOINTMENT_UPDATED, fired whenrescheduleAppointmentis called
Troubleshooting
Docker Desktop not starting containers
Make sure WSL 2 is enabled. In PowerShell as Administrator:
wsl --install
wsl --set-default-version 2Restart Docker Desktop after enabling WSL 2.
Port 80 already in use
If another application is using port 80, stop it before starting OpenMRS. To find what is using port 80:
netstat -ano | findstr ":80 "Then stop the process with its PID:
Stop-Process -Id YOUR_PID -ForcePlugin not appearing in the module list
Check that the OMOD file is in the distribution folder inside the container:
docker exec openmrs-distro-referenceapplication-main-backend-1 `
ls /openmrs/distribution/openmrs_modules/ | findstr forwarderIf it is missing, the bind mount is not working. In Docker Desktop, go to Settings and make sure your drive is shared under Resources and File Sharing.
Plugin appears but does not start
Check the logs:
docker logs openmrs-distro-referenceapplication-main-backend-1 2>$null `
| Select-String "forwarder|bahmni.appointment.forwarder" `
| Select-Object -Last 20RabbitMQ not connecting
Verify the global properties are set:
docker exec openmrs-distro-referenceapplication-main-db-1 `
mysql -u openmrs -popenmrs openmrs `
-e "SELECT property, property_value FROM global_property WHERE property LIKE 'communicatie%';" 2>$nullOld OMOD cached after redeployment
Find the Docker volume data path in Docker Desktop under Volumes, then delete the cache folder for the plugin. Alternatively use Docker Desktop’s terminal to run:
docker exec openmrs-distro-referenceapplication-main-backend-1 `
rm -rf /openmrs/data/.openmrs-lib-cache/bahmni.appointment.forwarder
docker restart openmrs-distro-referenceapplication-main-backend-1mvn command not found
Maven needs to be on your system PATH. After installing Maven, add it manually:
$mavenPath = "C:\Program Files\Apache\maven-3.9.0\bin"
[System.Environment]::SetEnvironmentVariable("PATH", $env:PATH + ";$mavenPath", "Machine")Replace the path with your actual Maven installation. Restart PowerShell after making this change.
git clone uses SSH but SSH key is not set up
Use HTTPS instead of SSH when cloning:
git clone https://github.com/openmrs/openmrs-module-event.git
git clone https://github.com/Bahmni/openmrs-module-appointments.git openmrs-module-appointments-2.1
git clone https://github.com/ChrisHorler/AvansModuleOpenMRS.git