From f2ea8494eaa24110f0c35fe4044c7f9f4871eab5 Mon Sep 17 00:00:00 2001
From: KOPPIREDDY DURGA PRASAD
<144464542+DurgaPrasad-54@users.noreply.github.com>
Date: Thu, 12 Mar 2026 16:51:38 +0530
Subject: [PATCH 1/4] Feat/health version (#3)
* feat(health,version): add health and version endpoints
* fix(jwt): fix the jwtvalidation issues
* refactor(health): simplify MySQL health check and remove sensitive details
* fix(health): harden advanced MySQL checks and throttle execution
* fix(health): scope PROCESSLIST lock-wait check to application DB user
* fix(health): cancel timed-out advanced MySQL checks to avoid orphaned tasks
* fix(health): avoid sharing JDBC connections across threads in advanced MySQL checks
* refactor(health): extract MySQL basic health query into helper method
* fix(health): avoid blocking DB I/O under write lock and restore interrupt flag
---
.github/workflows/swagger-json.yml | 107 ++++
README.md | 2 +
pom.xml | 31 +
.../controller/health/HealthController.java | 62 ++
.../controller/version/VersionController.java | 79 +++
.../fhir/service/health/HealthService.java | 573 ++++++++++++++++++
.../fhir/utils/JwtUserIdValidationFilter.java | 4 +-
.../resources/application-swagger.properties | 133 ++++
8 files changed, 990 insertions(+), 1 deletion(-)
create mode 100644 .github/workflows/swagger-json.yml
create mode 100644 src/main/java/com/wipro/fhir/controller/health/HealthController.java
create mode 100644 src/main/java/com/wipro/fhir/controller/version/VersionController.java
create mode 100644 src/main/java/com/wipro/fhir/service/health/HealthService.java
create mode 100644 src/main/resources/application-swagger.properties
diff --git a/.github/workflows/swagger-json.yml b/.github/workflows/swagger-json.yml
new file mode 100644
index 0000000..d140252
--- /dev/null
+++ b/.github/workflows/swagger-json.yml
@@ -0,0 +1,107 @@
+name: Sync Swagger to AMRIT-Docs
+
+on:
+ push:
+ branches: [ main ]
+ workflow_dispatch:
+
+jobs:
+ swagger-sync:
+ runs-on: ubuntu-latest
+ timeout-minutes: 20
+
+ steps:
+ - name: Checkout API repo
+ uses: actions/checkout@v4
+
+ - name: Set up Java 17
+ uses: actions/setup-java@v4
+ with:
+ distribution: temurin
+ java-version: 17
+ cache: maven
+
+ - name: Build API (skip tests)
+ run: mvn -B clean package -DskipTests
+
+ - name: Install jq
+ run: sudo apt-get update && sudo apt-get install -y jq
+
+ - name: Run API in swagger profile
+ run: |
+ nohup java -jar target/fhir-api-*.war \
+ --spring.profiles.active=swagger \
+ --server.port=9090 \
+ > app.log 2>&1 &
+ echo $! > api_pid.txt
+
+ - name: Wait for API & fetch Swagger
+ run: |
+ for i in {1..40}; do
+ CODE=$(curl --connect-timeout 2 --max-time 5 -s -o swagger_raw.json -w "%{http_code}" http://localhost:9090/v3/api-docs || true)
+
+ if [ "$CODE" = "200" ]; then
+ jq . swagger_raw.json > fhir-api.json || {
+ echo "Swagger JSON invalid"
+ cat swagger_raw.json
+ exit 1
+ }
+
+ if [ "$(jq '.paths | length' fhir-api.json)" -eq 0 ]; then
+ echo "Swagger paths empty – failing"
+ exit 1
+ fi
+
+ echo "Swagger generated successfully"
+ exit 0
+ fi
+
+ echo "Waiting for API... ($i)"
+ sleep 4
+ done
+
+ echo "Swagger not generated"
+ cat app.log || true
+ exit 1
+
+ - name: Stop API
+ if: always()
+ run: |
+ # Graceful shutdown of the process group
+ sleep 5
+ # Force kill the process group if still running
+ if [ -f api_pid.txt ]; then
+ PID=$(cat api_pid.txt)
+ kill -TERM -- -"$PID" 2>/dev/null || true
+ sleep 2
+ kill -9 -- -"$PID" 2>/dev/null || true
+ fi
+ # Fallback: kill any remaining java process on port 9090
+ fuser -k 9090/tcp 2>/dev/null || true
+
+ - name: Checkout AMRIT-Docs
+ uses: actions/checkout@v4
+ with:
+ repository: PSMRI/AMRIT-Docs
+ token: ${{ secrets.DOCS_REPO_TOKEN }}
+ path: amrit-docs
+ fetch-depth: 0
+
+ - name: Copy Swagger JSON
+ run: |
+ mkdir -p amrit-docs/docs/swagger
+ cp fhir-api.json amrit-docs/docs/swagger/fhir-api.json
+
+ - name: Create Pull Request
+ uses: peter-evans/create-pull-request@v8
+ with:
+ token: ${{ secrets.DOCS_REPO_TOKEN }}
+ path: amrit-docs
+ branch: auto/swagger-update-${{ github.run_id }}-${{ github.run_attempt }}
+ base: main
+ commit-message: "chore(docs): auto-update FHIR-API swagger"
+ title: "chore(docs): auto-update FHIR-API swagger"
+ delete-branch: true
+ body: |
+ This PR automatically updates FHIR-API Swagger JSON
+ from the latest main branch build.
diff --git a/README.md b/README.md
index a6836c0..a52fdd3 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# AMRIT - FHIR Service
[](https://www.gnu.org/licenses/gpl-3.0) 
+[](https://deepwiki.com/PSMRI/FHIR-API)
+
FHIR (Fast Healthcare Interoperability Resources) standard defines how healthcare information can be exchanged between different computer systems regardless of how it is stored in those systems. FHIR provides a means for representing and sharing information among clinicians and organizations in a standard way regardless of the ways local EHRs represent or store the data. FHIR combines the best features of previous standards into a common specification, while being flexible enough to meet needs of a wide variety of use cases within the healthcare ecosystem. Resources are the basis for all exchangeable FHIR content. Each resource includes a standard definition and human-readable descriptions about how to use the resource. Each resource also has a set of common and resource-specific metadata (attributes) to allow its use clearly and unambiguously. FHIR Resources can store and/or exchange many types of clinical and administrative data.
diff --git a/pom.xml b/pom.xml
index 0a5c084..99c38e7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -327,6 +327,11 @@
0.12.6
runtime
+
+ com.h2database
+ h2
+ runtime
+
@@ -511,6 +516,32 @@
+
+ io.github.git-commit-id
+ git-commit-id-maven-plugin
+ 7.0.0
+
+
+ get-the-git-infos
+
+ revision
+
+ initialize
+
+
+
+ true
+ ${project.build.outputDirectory}/git.properties
+
+ ^git.branch$
+ ^git.commit.id.abbrev$
+ ^git.build.version$
+ ^git.build.time$
+
+ false
+ false
+
+
org.springframework.boot
spring-boot-maven-plugin
diff --git a/src/main/java/com/wipro/fhir/controller/health/HealthController.java b/src/main/java/com/wipro/fhir/controller/health/HealthController.java
new file mode 100644
index 0000000..b0aaf77
--- /dev/null
+++ b/src/main/java/com/wipro/fhir/controller/health/HealthController.java
@@ -0,0 +1,62 @@
+package com.wipro.fhir.controller.health;
+
+import java.time.Instant;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.wipro.fhir.service.health.HealthService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+@RestController
+@RequestMapping("/health")
+@Tag(name = "Health Check", description = "APIs for checking infrastructure health status")
+public class HealthController {
+
+ private static final Logger logger = LoggerFactory.getLogger(HealthController.class);
+
+ private final HealthService healthService;
+
+ public HealthController(HealthService healthService) {
+ this.healthService = healthService;
+ }
+
+ @GetMapping
+ @Operation(summary = "Check infrastructure health",
+ description = "Returns the health status of MySQL, Redis, and other configured services")
+ @ApiResponses({
+ @ApiResponse(responseCode = "200", description = "Services are UP or DEGRADED (operational with warnings)"),
+ @ApiResponse(responseCode = "503", description = "One or more critical services are DOWN")
+ })
+ public ResponseEntity