Tutorial 10: Testing & Deployment¶
Pages: 2
📖 Page 1: Testing¶
Manual Testing Checklist¶
Test each module systematically:
Patient Module:¶
â–¡ Create patient with all fields
â–¡ View patient details
â–¡ Edit patient information
â–¡ Delete patient (with confirmation)
â–¡ Search by name
â–¡ Filter by gender
â–¡ Filter by blood group
â–¡ Filter by status (active/inactive)
â–¡ Filter by age range
â–¡ Sort by name (A-Z, Z-A)
â–¡ Sort by age (youngest, oldest)
â–¡ Pagination (10, 25, 50 per page)
â–¡ Navigate pages (first, prev, next, last)
Practitioner Module:¶
Organization Module:¶
Appointment Module:¶
â–¡ Create with patient + practitioner selection
â–¡ DateTime picker working
â–¡ Status changes
â–¡ View appointments
â–¡ Filter by date range
â–¡ Filter by status
Audit Trail:¶
â–¡ All actions logged (C, R, U, D)
â–¡ Filter by action type
â–¡ Filter by resource type
â–¡ Timestamps correct
End-to-End Test Scenario¶
Complete workflow:
- Create 3 practitioners (different specialties)
- Create 1 organization (Hospital)
- Create 10 patients (varied ages, genders, blood groups)
- Create 5 appointments (different patients/practitioners)
- Update 2 patients
- Delete 1 patient
- Check audit trail (should show all actions)
- Test all filters on each module
- Test pagination with different page sizes
- Test search functionality
Expected: Everything works smoothly!
📖 Page 2: Production Deployment¶
Build JAR File¶
Run in Production¶
Option 1: Direct JAR
# Run with production settings
java -jar target/fhir-pms-1.0.0.jar \
--server.port=80 \
--spring.thymeleaf.cache=true \
--logging.level.com.healthcare.pms=INFO
Option 2: With Environment Variables
# Set environment variables
export SERVER_PORT=80
export FHIR_SERVER_URL=https://hapi.fhir.org/baseR4
export THYMELEAF_CACHE=true
# Run
java -jar target/fhir-pms-1.0.0.jar
Option 3: Systemd Service (Linux)
Create /etc/systemd/system/fhir-pms.service:
[Unit]
Description=FHIR Patient Management System
After=network.target
[Service]
Type=simple
User=fhirapp
WorkingDirectory=/opt/fhir-pms
ExecStart=/usr/bin/java -jar /opt/fhir-pms/fhir-pms-1.0.0.jar
Restart=always
RestartSec=10
Environment="SERVER_PORT=80"
Environment="FHIR_SERVER_URL=https://hapi.fhir.org/baseR4"
[Install]
WantedBy=multi-user.target
Enable and start:
Docker Deployment¶
Create Dockerfile:
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY target/fhir-pms-1.0.0.jar app.jar
EXPOSE 8081
ENTRYPOINT ["java", "-jar", "app.jar"]
Build and run:
# Build image
docker build -t fhir-pms:1.0 .
# Run container
docker run -d \
-p 8081:8081 \
-e FHIR_SERVER_URL=https://hapi.fhir.org/baseR4 \
--name fhir-pms \
fhir-pms:1.0
# Check logs
docker logs -f fhir-pms
Production Configuration¶
Create application-prod.properties:
# Server
server.port=80
server.compression.enabled=true
# FHIR
fhir.server.base-url=${FHIR_SERVER_URL:https://hapi.fhir.org/baseR4}
# Thymeleaf - ENABLE CACHE
spring.thymeleaf.cache=true
# Logging - PRODUCTION LEVEL
logging.level.root=WARN
logging.level.com.healthcare.pms=INFO
# Error handling
server.error.include-message=never
server.error.include-binding-errors=never
server.error.include-stacktrace=never
Run with profile:
Troubleshooting¶
Problem: Port 80 requires sudo
# Option 1: Use port 8081 and reverse proxy (nginx)
# Option 2: Give java permission
sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/java
Problem: Out of memory
Problem: FHIR server timeout
# In application.properties, increase timeout
fhir.client.connection-timeout=30000
fhir.client.socket-timeout=30000
Problem: Logs filling disk
# Add log rotation in application-prod.properties
logging.file.name=/var/log/fhir-pms/application.log
logging.file.max-size=10MB
logging.file.max-history=30
Security Checklist¶
â–¡ Change default ports
â–¡ Enable HTTPS (use Let's Encrypt + nginx)
â–¡ Add authentication (Spring Security)
â–¡ Enable CORS only for trusted domains
â–¡ Disable debug endpoints
â–¡ Set secure headers
â–¡ Regular dependency updates (mvn versions:display-dependency-updates)
â–¡ Environment variables for secrets (not in code)
â–¡ Firewall rules (allow only necessary ports)
â–¡ Regular backups of FHIR data
Monitoring¶
Add health endpoint in Application.java:
@RestController
public class HealthController {
@GetMapping("/health")
public Map<String, String> health() {
Map<String, String> response = new HashMap<>();
response.put("status", "UP");
response.put("timestamp", LocalDateTime.now().toString());
return response;
}
}
Check health:
✅ Deployment Complete!¶
- Tested all features manually
- Built production JAR
- Multiple deployment options (JAR, Docker, Systemd)
- Production configuration ready
- Security checklist reviewed
- Health monitoring added
- Troubleshooting guide complete
🎉 CONGRATULATIONS!¶
You built a complete FHIR Patient Management System!
What you created: - ✅ 4 FHIR modules (Patient, Practitioner, Organization, Appointment) - ✅ Complete CRUD operations - ✅ Advanced filters (6+ per module) - ✅ Sorting (name, age, etc.) - ✅ Pagination (with page size selector) - ✅ Professional UI (Bootstrap) - ✅ Audit trail (compliance ready) - ✅ Production ready deployment
Skills gained: - Spring Boot application development - FHIR R4 implementation - HAPI FHIR Client usage - REST API design - Thymeleaf templating - Production deployment - Healthcare IT basics
🚀 Next Steps¶
Enhance Your System:¶
- Add Authentication
- Spring Security
- User roles (Admin, Doctor, Nurse)
-
Login/logout
-
Add More Features
- Patient medical history
- Prescription management
- Lab results
-
Reports and analytics
-
Improve UI
- Add charts (Chart.js)
- Better responsive design
-
Dark mode toggle
-
Performance
- Add caching (Redis)
- Connection pooling
-
Load balancing
-
Deploy to Cloud
- AWS Elastic Beanstalk
- Google Cloud Run
- Azure App Service
- Heroku
📚 Additional Resources¶
FHIR: - HL7 FHIR - HAPI FHIR Docs
Spring Boot: - Spring Boot Docs - Spring Security
Deployment: - Docker Docs - AWS Deployment
💡 Final Tips¶
Keep Learning
FHIR is vast - you learned the essentials, explore more!
Contribute
Open source your project, help others learn!
Iterate
Start with basics, add features gradually!
🎉 YOU DID IT! CONGRATULATIONS! 🎉
Share your success and keep building! 🚀