diff --git a/src/main/java/com/iemr/common/controller/health/HealthController.java b/src/main/java/com/iemr/common/controller/health/HealthController.java new file mode 100644 index 00000000..e340b905 --- /dev/null +++ b/src/main/java/com/iemr/common/controller/health/HealthController.java @@ -0,0 +1,119 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + +package com.iemr.common.controller.health; + +import java.sql.Connection; +import java.util.HashMap; +import java.util.Map; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Health check controller for Common-API. + * Verifies application liveness and dependency health (DB, Redis). + * + * @author vaishnavbhosale + */ +@RestController +public class HealthController { + + private static final Logger logger = + LoggerFactory.getLogger(HealthController.class); + + private static final String COMPONENT_DATABASE = "database"; + private static final String COMPONENT_REDIS = "redis"; + + private final DataSource dataSource; + private final RedisConnectionFactory redisConnectionFactory; + + public HealthController( + DataSource dataSource, + RedisConnectionFactory redisConnectionFactory) { + this.dataSource = dataSource; + this.redisConnectionFactory = redisConnectionFactory; + } + + @GetMapping("/health") + public ResponseEntity> health() { + + Map response = new HashMap<>(); + Map components = new HashMap<>(); + + boolean dbUp = checkDatabase(components); + boolean redisUp = checkRedis(components); + + boolean overallUp = dbUp && redisUp; + + response.put("status", overallUp ? "UP" : "DOWN"); + response.put("components", components); + + return overallUp + ? ResponseEntity.ok(response) + : ResponseEntity.status(503).body(response); + } + + private boolean checkDatabase(Map components) { + if (dataSource == null) { + components.put(COMPONENT_DATABASE, "NOT_CONFIGURED"); + return true; + } + + try (Connection connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + + statement.execute("SELECT 1"); + components.put(COMPONENT_DATABASE, "UP"); + return true; + + } catch (Exception e) { + logger.error("Database health check failed", e); + components.put(COMPONENT_DATABASE, "DOWN"); + return false; + } + } + + private boolean checkRedis(Map components) { + if (redisConnectionFactory == null) { + components.put(COMPONENT_REDIS, "NOT_CONFIGURED"); + return true; + } + + try (RedisConnection connection = redisConnectionFactory.getConnection()) { + connection.ping(); + components.put(COMPONENT_REDIS, "UP"); + return true; + + } catch (Exception e) { + logger.error("Redis health check failed", e); + components.put(COMPONENT_REDIS, "DOWN"); + return false; + } + } +} + diff --git a/src/main/java/com/iemr/common/controller/version/VersionController.java b/src/main/java/com/iemr/common/controller/version/VersionController.java index 705fccdc..10645866 100644 --- a/src/main/java/com/iemr/common/controller/version/VersionController.java +++ b/src/main/java/com/iemr/common/controller/version/VersionController.java @@ -1,30 +1,37 @@ /* -* AMRIT – Accessible Medical Records via Integrated Technology -* Integrated EHR (Electronic Health Records) Solution -* -* Copyright (C) "Piramal Swasthya Management and Research Institute" -* -* This file is part of AMRIT. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see https://www.gnu.org/licenses/. -*/ + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +/** + * REST controller exposing application version and build metadata. + *

+ * Provides the /version endpoint which returns the + * Git commit hash and build timestamp in a standardized JSON format. + *

+ * + * @author Vaishnav Bhosale + */ package com.iemr.common.controller.version; -import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; +import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,46 +39,35 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -import com.iemr.common.utils.response.OutputResponse; - import io.swagger.v3.oas.annotations.Operation; - @RestController public class VersionController { - private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); + private final Logger logger = + LoggerFactory.getLogger(this.getClass().getSimpleName()); @Operation(summary = "Get version") @RequestMapping(value = "/version", method = { RequestMethod.GET }) - public String versionInformation() { - OutputResponse output = new OutputResponse(); - try { - logger.info("version Controller Start"); - output.setResponse(readGitProperties()); - } catch (Exception e) { - output.setError(e); - } - - logger.info("version Controller End"); - return output.toString(); - } + public VersionInfo versionInformation() { - private String readGitProperties() throws Exception { - ClassLoader classLoader = getClass().getClassLoader(); - InputStream inputStream = classLoader.getResourceAsStream("git.properties"); + Properties properties = new Properties(); - return readFromInputStream(inputStream); - } + try (InputStream is = getClass() + .getClassLoader() + .getResourceAsStream("git.properties")) { - private String readFromInputStream(InputStream inputStream) throws IOException { - StringBuilder resultStringBuilder = new StringBuilder(); - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String line; - while ((line = br.readLine()) != null) { - resultStringBuilder.append(line).append("\n"); + if (is != null) { + properties.load(is); } + + } catch (Exception e) { + logger.error("Error reading git.properties", e); } - return resultStringBuilder.toString(); + + return new VersionInfo( + properties.getProperty("git.commit.id.abbrev", "unknown"), + properties.getProperty("git.build.time", "unknown") + ); } } diff --git a/src/main/java/com/iemr/common/controller/version/VersionInfo.java b/src/main/java/com/iemr/common/controller/version/VersionInfo.java new file mode 100644 index 00000000..20f560a1 --- /dev/null +++ b/src/main/java/com/iemr/common/controller/version/VersionInfo.java @@ -0,0 +1,46 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +/** + * DTO for exposing build and version metadata. + * + * @author vaishnavbhosale + */ +package com.iemr.common.controller.version; + +public class VersionInfo { + + private String commitHash; + private String buildTime; + + public VersionInfo(String commitHash, String buildTime) { + this.commitHash = commitHash; + this.buildTime = buildTime; + } + + public String getCommitHash() { + return commitHash; + } + + public String getBuildTime() { + return buildTime; + } +}