From 4b286c6c74aaab8cab73a1c7cc717138d39a66d7 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 14 Jan 2026 00:37:59 +0530 Subject: [PATCH 1/5] feat: add detailed component health checks for MySQL, Redis, and MongoDB - Enhanced /health endpoint to show per-component status - Added type, host, port, database, version, and response time details - Returns error messages and types when components are down - Added MongoDB dependency and health check support --- pom.xml | 4 + .../admin/service/health/HealthService.java | 307 ++++++++++++++++-- src/main/resources/application.properties | 5 + 3 files changed, 290 insertions(+), 26 deletions(-) diff --git a/pom.xml b/pom.xml index 712140d..db644db 100644 --- a/pom.xml +++ b/pom.xml @@ -200,6 +200,10 @@ spring-session-data-redis + + org.springframework.boot + spring-boot-starter-data-mongodb + org.mockito mockito-core diff --git a/src/main/java/com/iemr/admin/service/health/HealthService.java b/src/main/java/com/iemr/admin/service/health/HealthService.java index ae41b8e..820cf29 100644 --- a/src/main/java/com/iemr/admin/service/health/HealthService.java +++ b/src/main/java/com/iemr/admin/service/health/HealthService.java @@ -24,14 +24,19 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.util.HashMap; +import java.time.Instant; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.Properties; import javax.sql.DataSource; +import org.bson.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @@ -41,6 +46,7 @@ public class HealthService { private static final Logger logger = LoggerFactory.getLogger(HealthService.class); private static final String DB_HEALTH_CHECK_QUERY = "SELECT 1 as health_check"; + private static final String DB_VERSION_QUERY = "SELECT VERSION()"; @Autowired private DataSource dataSource; @@ -48,72 +54,321 @@ public class HealthService { @Autowired(required = false) private RedisTemplate redisTemplate; + @Autowired(required = false) + private MongoTemplate mongoTemplate; + + @Value("${spring.datasource.url:unknown}") + private String dbUrl; + + @Value("${spring.redis.host:localhost}") + private String redisHost; + + @Value("${spring.redis.port:6379}") + private int redisPort; + + @Value("${spring.data.mongodb.host:localhost}") + private String mongoHost; + + @Value("${spring.data.mongodb.port:27017}") + private int mongoPort; + + @Value("${spring.data.mongodb.database:amrit}") + private String mongoDatabase; + public Map checkHealth() { - Map healthStatus = new HashMap<>(); + Map healthStatus = new LinkedHashMap<>(); + Map components = new LinkedHashMap<>(); boolean overallHealth = true; - // Check database connectivity (details logged internally, not exposed) - boolean dbHealthy = checkDatabaseHealthInternal(); - if (!dbHealthy) { + // Check MySQL connectivity + Map mysqlStatus = checkMySQLHealth(); + components.put("mysql", mysqlStatus); + if (!"UP".equals(mysqlStatus.get("status"))) { overallHealth = false; } - // Check Redis connectivity if configured (details logged internally) + // Check Redis connectivity if configured if (redisTemplate != null) { - boolean redisHealthy = checkRedisHealthInternal(); - if (!redisHealthy) { + Map redisStatus = checkRedisHealth(); + components.put("redis", redisStatus); + if (!"UP".equals(redisStatus.get("status"))) { + overallHealth = false; + } + } + + // Check MongoDB connectivity if configured + if (mongoTemplate != null) { + Map mongoStatus = checkMongoDBHealth(); + components.put("mongodb", mongoStatus); + if (!"UP".equals(mongoStatus.get("status"))) { overallHealth = false; } } healthStatus.put("status", overallHealth ? "UP" : "DOWN"); + healthStatus.put("timestamp", Instant.now().toString()); + healthStatus.put("components", components); logger.info("Health check completed - Overall status: {}", overallHealth ? "UP" : "DOWN"); return healthStatus; } - private boolean checkDatabaseHealthInternal() { + private Map checkMySQLHealth() { + Map status = new LinkedHashMap<>(); + Map details = new LinkedHashMap<>(); long startTime = System.currentTimeMillis(); - + + // Add connection details + details.put("type", "MySQL"); + details.put("host", extractHost(dbUrl)); + details.put("port", extractPort(dbUrl)); + details.put("database", extractDatabaseName(dbUrl)); + try (Connection connection = dataSource.getConnection()) { - boolean isConnectionValid = connection.isValid(2); // 2 second timeout per best practices - + // 2 second timeout per best practices + boolean isConnectionValid = connection.isValid(2); + if (isConnectionValid) { + // 3 second query timeout try (PreparedStatement stmt = connection.prepareStatement(DB_HEALTH_CHECK_QUERY)) { - stmt.setQueryTimeout(3); // 3 second query timeout + stmt.setQueryTimeout(3); try (ResultSet rs = stmt.executeQuery()) { if (rs.next() && rs.getInt(1) == 1) { long responseTime = System.currentTimeMillis() - startTime; - logger.debug("Database health check: UP ({}ms)", responseTime); - return true; + logger.debug("MySQL health check: UP ({}ms)", responseTime); + + status.put("status", "UP"); + details.put("responseTimeMs", responseTime); + + // Get database version + String version = getMySQLVersion(connection); + if (version != null) { + details.put("version", version); + } + + status.put("details", details); + return status; } } } } - logger.warn("Database health check: Connection not valid"); - return false; + logger.warn("MySQL health check: Connection not valid"); + status.put("status", "DOWN"); + details.put("error", "Connection validation failed"); + status.put("details", details); + return status; } catch (Exception e) { - logger.error("Database health check failed: {}", e.getMessage()); - return false; + logger.error("MySQL health check failed: {}", e.getMessage()); + status.put("status", "DOWN"); + details.put("error", e.getMessage()); + details.put("errorType", e.getClass().getSimpleName()); + status.put("details", details); + return status; } } - private boolean checkRedisHealthInternal() { + private Map checkRedisHealth() { + Map status = new LinkedHashMap<>(); + Map details = new LinkedHashMap<>(); long startTime = System.currentTimeMillis(); - + + // Add connection details + details.put("type", "Redis"); + details.put("host", redisHost); + details.put("port", redisPort); + try { - String pong = redisTemplate.execute((RedisCallback) connection -> connection.ping()); - + // Use ping() from RedisConnection directly + String pong = redisTemplate.execute((RedisCallback) connection -> + connection.ping() + ); + if ("PONG".equals(pong)) { long responseTime = System.currentTimeMillis() - startTime; logger.debug("Redis health check: UP ({}ms)", responseTime); - return true; + + status.put("status", "UP"); + details.put("responseTimeMs", responseTime); + + // Get Redis version + String version = getRedisVersion(); + if (version != null) { + details.put("version", version); + } + + status.put("details", details); + return status; } logger.warn("Redis health check: Ping returned unexpected response"); - return false; + status.put("status", "DOWN"); + details.put("error", "Ping returned unexpected response"); + status.put("details", details); + return status; } catch (Exception e) { logger.error("Redis health check failed: {}", e.getMessage()); - return false; + status.put("status", "DOWN"); + details.put("error", e.getMessage()); + details.put("errorType", e.getClass().getSimpleName()); + status.put("details", details); + return status; + } + } + + private Map checkMongoDBHealth() { + Map status = new LinkedHashMap<>(); + Map details = new LinkedHashMap<>(); + long startTime = System.currentTimeMillis(); + + // Add connection details + details.put("type", "MongoDB"); + details.put("host", mongoHost); + details.put("port", mongoPort); + details.put("database", mongoDatabase); + + try { + // Run ping command to check MongoDB connectivity + Document pingResult = mongoTemplate.getDb().runCommand(new Document("ping", 1)); + + if (pingResult != null && pingResult.getDouble("ok") == 1.0) { + long responseTime = System.currentTimeMillis() - startTime; + logger.debug("MongoDB health check: UP ({}ms)", responseTime); + + status.put("status", "UP"); + details.put("responseTimeMs", responseTime); + + // Get MongoDB version + String version = getMongoDBVersion(); + if (version != null) { + details.put("version", version); + } + + status.put("details", details); + return status; + } + logger.warn("MongoDB health check: Ping returned unexpected response"); + status.put("status", "DOWN"); + details.put("error", "Ping returned unexpected response"); + status.put("details", details); + return status; + } catch (Exception e) { + logger.error("MongoDB health check failed: {}", e.getMessage()); + status.put("status", "DOWN"); + details.put("error", e.getMessage()); + details.put("errorType", e.getClass().getSimpleName()); + status.put("details", details); + return status; + } + } + + private String getMySQLVersion(Connection connection) { + try (PreparedStatement stmt = connection.prepareStatement(DB_VERSION_QUERY); + ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + return rs.getString(1); + } + } catch (Exception e) { + logger.debug("Could not retrieve MySQL version: {}", e.getMessage()); + } + return null; + } + + private String getRedisVersion() { + try { + Properties info = redisTemplate.execute((RedisCallback) connection -> + connection.serverCommands().info("server") + ); + if (info != null && info.containsKey("redis_version")) { + return info.getProperty("redis_version"); + } + } catch (Exception e) { + logger.debug("Could not retrieve Redis version: {}", e.getMessage()); + } + return null; + } + + private String getMongoDBVersion() { + try { + Document buildInfo = mongoTemplate.getDb().runCommand(new Document("buildInfo", 1)); + if (buildInfo != null && buildInfo.containsKey("version")) { + return buildInfo.getString("version"); + } + } catch (Exception e) { + logger.debug("Could not retrieve MongoDB version: {}", e.getMessage()); + } + return null; + } + + /** + * Extracts host from JDBC URL. + * Example: jdbc:mysql://mysql-container:3306/db_iemr -> mysql-container + */ + private String extractHost(String jdbcUrl) { + if (jdbcUrl == null || "unknown".equals(jdbcUrl)) { + return "unknown"; + } + try { + // Remove jdbc:mysql:// prefix + String withoutPrefix = jdbcUrl.replaceFirst("jdbc:mysql://", ""); + // Get host:port part (before the first /) + int slashIndex = withoutPrefix.indexOf('/'); + String hostPort = slashIndex > 0 + ? withoutPrefix.substring(0, slashIndex) + : withoutPrefix; + // Get host (before the colon) + int colonIndex = hostPort.indexOf(':'); + return colonIndex > 0 ? hostPort.substring(0, colonIndex) : hostPort; + } catch (Exception e) { + logger.debug("Could not extract host from URL: {}", e.getMessage()); + } + return "unknown"; + } + + /** + * Extracts port from JDBC URL. + * Example: jdbc:mysql://mysql-container:3306/db_iemr -> 3306 + */ + private String extractPort(String jdbcUrl) { + if (jdbcUrl == null || "unknown".equals(jdbcUrl)) { + return "unknown"; + } + try { + // Remove jdbc:mysql:// prefix + String withoutPrefix = jdbcUrl.replaceFirst("jdbc:mysql://", ""); + // Get host:port part (before the first /) + int slashIndex = withoutPrefix.indexOf('/'); + String hostPort = slashIndex > 0 + ? withoutPrefix.substring(0, slashIndex) + : withoutPrefix; + // Get port (after the colon) + int colonIndex = hostPort.indexOf(':'); + return colonIndex > 0 ? hostPort.substring(colonIndex + 1) : "3306"; + } catch (Exception e) { + logger.debug("Could not extract port from URL: {}", e.getMessage()); + } + return "3306"; + } + + /** + * Extracts database name from JDBC URL. + * Example: jdbc:mysql://mysql-container:3306/db_iemr?params -> db_iemr + */ + private String extractDatabaseName(String jdbcUrl) { + if (jdbcUrl == null || "unknown".equals(jdbcUrl)) { + return "unknown"; + } + try { + int lastSlash = jdbcUrl.lastIndexOf('/'); + if (lastSlash >= 0 && lastSlash < jdbcUrl.length() - 1) { + String afterSlash = jdbcUrl.substring(lastSlash + 1); + int queryStart = afterSlash.indexOf('?'); + if (queryStart > 0) { + return afterSlash.substring(0, queryStart); + } + return afterSlash; + } + } catch (Exception e) { + logger.debug("Could not extract database name: {}", e.getMessage()); } + return "unknown"; } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e65d5b3..bbc7f9e 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -74,3 +74,8 @@ swymed-edituser-url=swymed-base-url/SwymedWebApi/api/Contact calibrationPageSize=5 biological-screening-device-url=http://localhost:8096/ezdx-hub-connect-srv + +## MongoDB Configuration +spring.data.mongodb.host=mongodb-container +spring.data.mongodb.port=27017 +spring.data.mongodb.database=amrit From d6a362cabdc9bf6822620a0066e2af045a94b409 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 14 Jan 2026 00:45:37 +0530 Subject: [PATCH 2/5] fix: fetch base branch in commitlint workflow --- .github/workflows/commit-lint.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index d6a5d36..eed2fc9 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -17,6 +17,9 @@ jobs: submodules: true fetch-depth: 0 + - name: Fetch base branch + run: git fetch origin ${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }} + - name: Setup Node.js uses: actions/setup-node@v4 with: From 98f92e18eb663de3553b3b4e50107d03a98ce49f Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 14 Jan 2026 01:05:33 +0530 Subject: [PATCH 3/5] refactor: eliminate code duplication in health checks --- .../admin/service/health/HealthService.java | 182 +++++++----------- 1 file changed, 67 insertions(+), 115 deletions(-) diff --git a/src/main/java/com/iemr/admin/service/health/HealthService.java b/src/main/java/com/iemr/admin/service/health/HealthService.java index 820cf29..c98c027 100644 --- a/src/main/java/com/iemr/admin/service/health/HealthService.java +++ b/src/main/java/com/iemr/admin/service/health/HealthService.java @@ -28,6 +28,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; +import java.util.function.Supplier; import javax.sql.DataSource; @@ -83,7 +84,7 @@ public Map checkHealth() { // Check MySQL connectivity Map mysqlStatus = checkMySQLHealth(); components.put("mysql", mysqlStatus); - if (!"UP".equals(mysqlStatus.get("status"))) { + if (!isHealthy(mysqlStatus)) { overallHealth = false; } @@ -91,7 +92,7 @@ public Map checkHealth() { if (redisTemplate != null) { Map redisStatus = checkRedisHealth(); components.put("redis", redisStatus); - if (!"UP".equals(redisStatus.get("status"))) { + if (!isHealthy(redisStatus)) { overallHealth = false; } } @@ -100,7 +101,7 @@ public Map checkHealth() { if (mongoTemplate != null) { Map mongoStatus = checkMongoDBHealth(); components.put("mongodb", mongoStatus); - if (!"UP".equals(mongoStatus.get("status"))) { + if (!isHealthy(mongoStatus)) { overallHealth = false; } } @@ -114,144 +115,94 @@ public Map checkHealth() { } private Map checkMySQLHealth() { - Map status = new LinkedHashMap<>(); Map details = new LinkedHashMap<>(); - long startTime = System.currentTimeMillis(); - - // Add connection details details.put("type", "MySQL"); details.put("host", extractHost(dbUrl)); details.put("port", extractPort(dbUrl)); details.put("database", extractDatabaseName(dbUrl)); - try (Connection connection = dataSource.getConnection()) { - // 2 second timeout per best practices - boolean isConnectionValid = connection.isValid(2); - - if (isConnectionValid) { - // 3 second query timeout - try (PreparedStatement stmt = connection.prepareStatement(DB_HEALTH_CHECK_QUERY)) { - stmt.setQueryTimeout(3); - try (ResultSet rs = stmt.executeQuery()) { - if (rs.next() && rs.getInt(1) == 1) { - long responseTime = System.currentTimeMillis() - startTime; - logger.debug("MySQL health check: UP ({}ms)", responseTime); - - status.put("status", "UP"); - details.put("responseTimeMs", responseTime); - - // Get database version - String version = getMySQLVersion(connection); - if (version != null) { - details.put("version", version); + return performHealthCheck("MySQL", details, () -> { + try (Connection connection = dataSource.getConnection()) { + if (connection.isValid(2)) { + try (PreparedStatement stmt = connection.prepareStatement(DB_HEALTH_CHECK_QUERY)) { + stmt.setQueryTimeout(3); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next() && rs.getInt(1) == 1) { + String version = getMySQLVersion(connection); + return new HealthCheckResult(true, version, null); } - - status.put("details", details); - return status; } } } + return new HealthCheckResult(false, null, "Connection validation failed"); } - logger.warn("MySQL health check: Connection not valid"); - status.put("status", "DOWN"); - details.put("error", "Connection validation failed"); - status.put("details", details); - return status; - } catch (Exception e) { - logger.error("MySQL health check failed: {}", e.getMessage()); - status.put("status", "DOWN"); - details.put("error", e.getMessage()); - details.put("errorType", e.getClass().getSimpleName()); - status.put("details", details); - return status; - } + }); } private Map checkRedisHealth() { - Map status = new LinkedHashMap<>(); Map details = new LinkedHashMap<>(); - long startTime = System.currentTimeMillis(); - - // Add connection details details.put("type", "Redis"); details.put("host", redisHost); details.put("port", redisPort); - try { - // Use ping() from RedisConnection directly + return performHealthCheck("Redis", details, () -> { String pong = redisTemplate.execute((RedisCallback) connection -> connection.ping() ); - if ("PONG".equals(pong)) { - long responseTime = System.currentTimeMillis() - startTime; - logger.debug("Redis health check: UP ({}ms)", responseTime); - - status.put("status", "UP"); - details.put("responseTimeMs", responseTime); - - // Get Redis version String version = getRedisVersion(); - if (version != null) { - details.put("version", version); - } - - status.put("details", details); - return status; + return new HealthCheckResult(true, version, null); } - logger.warn("Redis health check: Ping returned unexpected response"); - status.put("status", "DOWN"); - details.put("error", "Ping returned unexpected response"); - status.put("details", details); - return status; - } catch (Exception e) { - logger.error("Redis health check failed: {}", e.getMessage()); - status.put("status", "DOWN"); - details.put("error", e.getMessage()); - details.put("errorType", e.getClass().getSimpleName()); - status.put("details", details); - return status; - } + return new HealthCheckResult(false, null, "Ping returned unexpected response"); + }); } private Map checkMongoDBHealth() { - Map status = new LinkedHashMap<>(); Map details = new LinkedHashMap<>(); - long startTime = System.currentTimeMillis(); - - // Add connection details details.put("type", "MongoDB"); details.put("host", mongoHost); details.put("port", mongoPort); details.put("database", mongoDatabase); - try { - // Run ping command to check MongoDB connectivity + return performHealthCheck("MongoDB", details, () -> { Document pingResult = mongoTemplate.getDb().runCommand(new Document("ping", 1)); - if (pingResult != null && pingResult.getDouble("ok") == 1.0) { - long responseTime = System.currentTimeMillis() - startTime; - logger.debug("MongoDB health check: UP ({}ms)", responseTime); + String version = getMongoDBVersion(); + return new HealthCheckResult(true, version, null); + } + return new HealthCheckResult(false, null, "Ping returned unexpected response"); + }); + } + /** + * Common health check execution pattern to reduce code duplication. + */ + private Map performHealthCheck(String componentName, + Map details, + Supplier checker) { + Map status = new LinkedHashMap<>(); + long startTime = System.currentTimeMillis(); + + try { + HealthCheckResult result = checker.get(); + long responseTime = System.currentTimeMillis() - startTime; + + if (result.isHealthy) { + logger.debug("{} health check: UP ({}ms)", componentName, responseTime); status.put("status", "UP"); details.put("responseTimeMs", responseTime); - - // Get MongoDB version - String version = getMongoDBVersion(); - if (version != null) { - details.put("version", version); + if (result.version != null) { + details.put("version", result.version); } - - status.put("details", details); - return status; + } else { + logger.warn("{} health check: {}", componentName, result.error); + status.put("status", "DOWN"); + details.put("error", result.error); } - logger.warn("MongoDB health check: Ping returned unexpected response"); - status.put("status", "DOWN"); - details.put("error", "Ping returned unexpected response"); status.put("details", details); return status; } catch (Exception e) { - logger.error("MongoDB health check failed: {}", e.getMessage()); + logger.error("{} health check failed: {}", componentName, e.getMessage()); status.put("status", "DOWN"); details.put("error", e.getMessage()); details.put("errorType", e.getClass().getSimpleName()); @@ -260,6 +211,10 @@ private Map checkMongoDBHealth() { } } + private boolean isHealthy(Map componentStatus) { + return "UP".equals(componentStatus.get("status")); + } + private String getMySQLVersion(Connection connection) { try (PreparedStatement stmt = connection.prepareStatement(DB_VERSION_QUERY); ResultSet rs = stmt.executeQuery()) { @@ -298,23 +253,16 @@ private String getMongoDBVersion() { return null; } - /** - * Extracts host from JDBC URL. - * Example: jdbc:mysql://mysql-container:3306/db_iemr -> mysql-container - */ private String extractHost(String jdbcUrl) { if (jdbcUrl == null || "unknown".equals(jdbcUrl)) { return "unknown"; } try { - // Remove jdbc:mysql:// prefix String withoutPrefix = jdbcUrl.replaceFirst("jdbc:mysql://", ""); - // Get host:port part (before the first /) int slashIndex = withoutPrefix.indexOf('/'); String hostPort = slashIndex > 0 ? withoutPrefix.substring(0, slashIndex) : withoutPrefix; - // Get host (before the colon) int colonIndex = hostPort.indexOf(':'); return colonIndex > 0 ? hostPort.substring(0, colonIndex) : hostPort; } catch (Exception e) { @@ -323,23 +271,16 @@ private String extractHost(String jdbcUrl) { return "unknown"; } - /** - * Extracts port from JDBC URL. - * Example: jdbc:mysql://mysql-container:3306/db_iemr -> 3306 - */ private String extractPort(String jdbcUrl) { if (jdbcUrl == null || "unknown".equals(jdbcUrl)) { return "unknown"; } try { - // Remove jdbc:mysql:// prefix String withoutPrefix = jdbcUrl.replaceFirst("jdbc:mysql://", ""); - // Get host:port part (before the first /) int slashIndex = withoutPrefix.indexOf('/'); String hostPort = slashIndex > 0 ? withoutPrefix.substring(0, slashIndex) : withoutPrefix; - // Get port (after the colon) int colonIndex = hostPort.indexOf(':'); return colonIndex > 0 ? hostPort.substring(colonIndex + 1) : "3306"; } catch (Exception e) { @@ -348,10 +289,6 @@ private String extractPort(String jdbcUrl) { return "3306"; } - /** - * Extracts database name from JDBC URL. - * Example: jdbc:mysql://mysql-container:3306/db_iemr?params -> db_iemr - */ private String extractDatabaseName(String jdbcUrl) { if (jdbcUrl == null || "unknown".equals(jdbcUrl)) { return "unknown"; @@ -371,4 +308,19 @@ private String extractDatabaseName(String jdbcUrl) { } return "unknown"; } + + /** + * Internal class to hold health check results. + */ + private static class HealthCheckResult { + final boolean isHealthy; + final String version; + final String error; + + HealthCheckResult(boolean isHealthy, String version, String error) { + this.isHealthy = isHealthy; + this.version = version; + this.error = error; + } + } } From c3dc907117018817229db3e310c2e9dfbc78ca47 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 14 Jan 2026 01:23:18 +0530 Subject: [PATCH 4/5] refactor: reduce health check duplication and fix SQLException --- .../admin/service/health/HealthService.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/iemr/admin/service/health/HealthService.java b/src/main/java/com/iemr/admin/service/health/HealthService.java index c98c027..d657611 100644 --- a/src/main/java/com/iemr/admin/service/health/HealthService.java +++ b/src/main/java/com/iemr/admin/service/health/HealthService.java @@ -122,19 +122,23 @@ private Map checkMySQLHealth() { details.put("database", extractDatabaseName(dbUrl)); return performHealthCheck("MySQL", details, () -> { - try (Connection connection = dataSource.getConnection()) { - if (connection.isValid(2)) { - try (PreparedStatement stmt = connection.prepareStatement(DB_HEALTH_CHECK_QUERY)) { - stmt.setQueryTimeout(3); - try (ResultSet rs = stmt.executeQuery()) { - if (rs.next() && rs.getInt(1) == 1) { - String version = getMySQLVersion(connection); - return new HealthCheckResult(true, version, null); + try { + try (Connection connection = dataSource.getConnection()) { + if (connection.isValid(2)) { + try (PreparedStatement stmt = connection.prepareStatement(DB_HEALTH_CHECK_QUERY)) { + stmt.setQueryTimeout(3); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next() && rs.getInt(1) == 1) { + String version = getMySQLVersion(connection); + return new HealthCheckResult(true, version, null); + } } } } + return new HealthCheckResult(false, null, "Connection validation failed"); } - return new HealthCheckResult(false, null, "Connection validation failed"); + } catch (Exception e) { + throw new RuntimeException(e); } }); } From e3afa2e2a11197fcd2ce46dd1e12fa223d2c94f0 Mon Sep 17 00:00:00 2001 From: Suraj Date: Sat, 17 Jan 2026 17:23:47 +0530 Subject: [PATCH 5/5] refactor: remove MongoDB health check from Admin-API - Removed MongoDB dependency and configuration (Admin-API doesn't use MongoDB) - Removed MongoDB health check from HealthService - Removed unnecessary base branch fetch step from commit-lint workflow - MongoDB is only used by FHIR-API, not Admin-API --- .github/workflows/commit-lint.yml | 3 -- pom.xml | 4 -- .../admin/service/health/HealthService.java | 52 +------------------ src/main/resources/application.properties | 5 -- 4 files changed, 2 insertions(+), 62 deletions(-) diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index eed2fc9..d6a5d36 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -17,9 +17,6 @@ jobs: submodules: true fetch-depth: 0 - - name: Fetch base branch - run: git fetch origin ${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }} - - name: Setup Node.js uses: actions/setup-node@v4 with: diff --git a/pom.xml b/pom.xml index db644db..712140d 100644 --- a/pom.xml +++ b/pom.xml @@ -200,10 +200,6 @@ spring-session-data-redis - - org.springframework.boot - spring-boot-starter-data-mongodb - org.mockito mockito-core diff --git a/src/main/java/com/iemr/admin/service/health/HealthService.java b/src/main/java/com/iemr/admin/service/health/HealthService.java index d657611..ac16a9f 100644 --- a/src/main/java/com/iemr/admin/service/health/HealthService.java +++ b/src/main/java/com/iemr/admin/service/health/HealthService.java @@ -32,12 +32,10 @@ import javax.sql.DataSource; -import org.bson.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @@ -55,9 +53,6 @@ public class HealthService { @Autowired(required = false) private RedisTemplate redisTemplate; - @Autowired(required = false) - private MongoTemplate mongoTemplate; - @Value("${spring.datasource.url:unknown}") private String dbUrl; @@ -67,15 +62,6 @@ public class HealthService { @Value("${spring.redis.port:6379}") private int redisPort; - @Value("${spring.data.mongodb.host:localhost}") - private String mongoHost; - - @Value("${spring.data.mongodb.port:27017}") - private int mongoPort; - - @Value("${spring.data.mongodb.database:amrit}") - private String mongoDatabase; - public Map checkHealth() { Map healthStatus = new LinkedHashMap<>(); Map components = new LinkedHashMap<>(); @@ -97,15 +83,6 @@ public Map checkHealth() { } } - // Check MongoDB connectivity if configured - if (mongoTemplate != null) { - Map mongoStatus = checkMongoDBHealth(); - components.put("mongodb", mongoStatus); - if (!isHealthy(mongoStatus)) { - overallHealth = false; - } - } - healthStatus.put("status", overallHealth ? "UP" : "DOWN"); healthStatus.put("timestamp", Instant.now().toString()); healthStatus.put("components", components); @@ -161,22 +138,7 @@ private Map checkRedisHealth() { }); } - private Map checkMongoDBHealth() { - Map details = new LinkedHashMap<>(); - details.put("type", "MongoDB"); - details.put("host", mongoHost); - details.put("port", mongoPort); - details.put("database", mongoDatabase); - - return performHealthCheck("MongoDB", details, () -> { - Document pingResult = mongoTemplate.getDb().runCommand(new Document("ping", 1)); - if (pingResult != null && pingResult.getDouble("ok") == 1.0) { - String version = getMongoDBVersion(); - return new HealthCheckResult(true, version, null); - } - return new HealthCheckResult(false, null, "Ping returned unexpected response"); - }); - } + /** * Common health check execution pattern to reduce code duplication. @@ -245,17 +207,7 @@ private String getRedisVersion() { return null; } - private String getMongoDBVersion() { - try { - Document buildInfo = mongoTemplate.getDb().runCommand(new Document("buildInfo", 1)); - if (buildInfo != null && buildInfo.containsKey("version")) { - return buildInfo.getString("version"); - } - } catch (Exception e) { - logger.debug("Could not retrieve MongoDB version: {}", e.getMessage()); - } - return null; - } + private String extractHost(String jdbcUrl) { if (jdbcUrl == null || "unknown".equals(jdbcUrl)) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index bbc7f9e..e65d5b3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -74,8 +74,3 @@ swymed-edituser-url=swymed-base-url/SwymedWebApi/api/Contact calibrationPageSize=5 biological-screening-device-url=http://localhost:8096/ezdx-hub-connect-srv - -## MongoDB Configuration -spring.data.mongodb.host=mongodb-container -spring.data.mongodb.port=27017 -spring.data.mongodb.database=amrit