diff --git a/.github/workflows/swagger-json.yml b/.github/workflows/swagger-json.yml
new file mode 100644
index 0000000..b9d58e6
--- /dev/null
+++ b/.github/workflows/swagger-json.yml
@@ -0,0 +1,100 @@
+name: Sync Swagger to AMRIT-Docs
+
+on:
+ push:
+ branches: [ main ]
+ workflow_dispatch:
+
+jobs:
+ swagger-sync:
+ runs-on: ubuntu-latest
+
+ 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 clean package -DENV_VAR=swagger -DskipTests -Dcheckstyle.skip=true
+
+ - name: Install jq
+ run: sudo apt-get update && sudo apt-get install -y jq
+
+ - name: Run API in swagger profile
+ run: |
+ mvn spring-boot:run \
+ -DENV_VAR=swagger \
+ -Dspring-boot.run.profiles=swagger \
+ -Dcheckstyle.skip=true \
+ -Dmaven.test.skip=true \
+ -Dspring-boot.run.arguments="--server.port=9090" \
+ > app.log 2>&1 &
+ echo $! > api_pid.txt
+
+ - name: Wait for API & fetch Swagger
+ run: |
+ for i in {1..30}; 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
+ if jq . swagger_raw.json > helpline104-api.json; then
+ echo "Swagger generated successfully"
+ exit 0
+ else
+ echo "Failed to parse swagger_raw.json with jq"
+ exit 1
+ fi
+ fi
+ echo "Waiting for API... ($i)"
+ sleep 5
+ 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
+
+ - name: Copy Swagger JSON
+ run: |
+ mkdir -p amrit-docs/docs/swagger
+ cp helpline104-api.json amrit-docs/docs/swagger/helpline104-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-helpline104-api
+ base: main
+ commit-message: Auto-update Helpline104-API swagger
+ title: Auto-update Helpline104-API swagger
+ delete-branch: true
+ body: |
+ This PR automatically updates the Helpline104-API Swagger JSON
+ from the latest main branch build.
diff --git a/pom.xml b/pom.xml
index ac49436..4349c78 100644
--- a/pom.xml
+++ b/pom.xml
@@ -249,6 +249,11 @@
0.12.6
runtime
+
+ com.h2database
+ h2
+ runtime
+
diff --git a/src/main/java/com/iemr/helpline104/App.java b/src/main/java/com/iemr/helpline104/App.java
index 4dd7bfd..01cbfda 100644
--- a/src/main/java/com/iemr/helpline104/App.java
+++ b/src/main/java/com/iemr/helpline104/App.java
@@ -26,6 +26,7 @@
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
@@ -60,6 +61,7 @@ public static void main(String[] args) {
}
@Bean
+ @Profile("!swagger")
public IEMRApplBeans instantiateBeans() {
return new IEMRApplBeans();
}
@@ -83,6 +85,7 @@ public String hello(@PathVariable String name) {
}
@Bean
+ @Profile("!swagger")
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(factory);
diff --git a/src/main/java/com/iemr/helpline104/config/InterceptorConfig.java b/src/main/java/com/iemr/helpline104/config/InterceptorConfig.java
index 5a2df6e..746c8db 100644
--- a/src/main/java/com/iemr/helpline104/config/InterceptorConfig.java
+++ b/src/main/java/com/iemr/helpline104/config/InterceptorConfig.java
@@ -29,7 +29,10 @@
import com.iemr.helpline104.utils.http.HTTPRequestInterceptor;
+import org.springframework.context.annotation.Profile;
+
@Configuration
+@Profile("!swagger")
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
diff --git a/src/main/java/com/iemr/helpline104/config/RedisConfig.java b/src/main/java/com/iemr/helpline104/config/RedisConfig.java
index 755b966..5c15ba0 100644
--- a/src/main/java/com/iemr/helpline104/config/RedisConfig.java
+++ b/src/main/java/com/iemr/helpline104/config/RedisConfig.java
@@ -7,12 +7,14 @@
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.context.annotation.Profile;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import com.iemr.helpline104.data.users.M_User;
@Configuration
@EnableCaching
+@Profile("!swagger")
public class RedisConfig {
@Bean
diff --git a/src/main/java/com/iemr/helpline104/config/SwaggerConfig.java b/src/main/java/com/iemr/helpline104/config/SwaggerConfig.java
index e8a09c0..62e2f73 100644
--- a/src/main/java/com/iemr/helpline104/config/SwaggerConfig.java
+++ b/src/main/java/com/iemr/helpline104/config/SwaggerConfig.java
@@ -2,6 +2,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
@@ -11,14 +12,23 @@
@Configuration
public class SwaggerConfig {
-
- @Bean
- public OpenAPI customOpenAPI() {
- return new OpenAPI().info(new
- Info().title("Helpline 104 API").version("version").description("A microservice for the creation and management of beneficiaries."))
- .addSecurityItem(new SecurityRequirement().addList("my security"))
- .components(new Components().addSecuritySchemes("my security",
- new SecurityScheme().name("my security").type(SecurityScheme.Type.HTTP).scheme("bearer")));
+ private static final String DEFAULT_SERVER_URL = "http://localhost:8091";
+
+ @Bean
+ public OpenAPI customOpenAPI(Environment env) {
+ String devUrl = env.getProperty("api.dev.url", DEFAULT_SERVER_URL);
+ String uatUrl = env.getProperty("api.uat.url", DEFAULT_SERVER_URL);
+ String demoUrl = env.getProperty("api.demo.url", DEFAULT_SERVER_URL);
+ return new OpenAPI()
+ .info(new Info().title("Helpline 104 API").version("1.0.0").description("Helpline 104 API for health advisory, disease surveillance, and medical information services."))
+ .addSecurityItem(new SecurityRequirement().addList("my security"))
+ .components(new Components().addSecuritySchemes("my security",
+ new SecurityScheme().name("my security").type(SecurityScheme.Type.HTTP).scheme("bearer")))
+ .servers(java.util.Arrays.asList(
+ new io.swagger.v3.oas.models.servers.Server().url(devUrl).description("Dev"),
+ new io.swagger.v3.oas.models.servers.Server().url(uatUrl).description("UAT"),
+ new io.swagger.v3.oas.models.servers.Server().url(demoUrl).description("Demo")
+ ));
}
}
diff --git a/src/main/java/com/iemr/helpline104/utils/FilterConfig.java b/src/main/java/com/iemr/helpline104/utils/FilterConfig.java
index 065954b..8f425a8 100644
--- a/src/main/java/com/iemr/helpline104/utils/FilterConfig.java
+++ b/src/main/java/com/iemr/helpline104/utils/FilterConfig.java
@@ -3,10 +3,12 @@
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
import org.springframework.core.Ordered;
import org.springframework.beans.factory.annotation.Value;
@Configuration
+@Profile("!swagger")
public class FilterConfig {
@Value("${cors.allowed-origins}")
diff --git a/src/main/java/com/iemr/helpline104/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/helpline104/utils/JwtAuthenticationUtil.java
index cdba5a8..f15f081 100644
--- a/src/main/java/com/iemr/helpline104/utils/JwtAuthenticationUtil.java
+++ b/src/main/java/com/iemr/helpline104/utils/JwtAuthenticationUtil.java
@@ -6,6 +6,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -19,6 +20,7 @@
import jakarta.servlet.http.HttpServletRequest;
@Component
+@Profile("!swagger")
public class JwtAuthenticationUtil {
@Autowired
diff --git a/src/main/java/com/iemr/helpline104/utils/JwtUtil.java b/src/main/java/com/iemr/helpline104/utils/JwtUtil.java
index bc4c659..5317636 100644
--- a/src/main/java/com/iemr/helpline104/utils/JwtUtil.java
+++ b/src/main/java/com/iemr/helpline104/utils/JwtUtil.java
@@ -5,6 +5,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.Claims;
@@ -12,6 +13,7 @@
import io.jsonwebtoken.security.Keys;
@Component
+@Profile("!swagger")
public class JwtUtil {
@Value("${jwt.secret}")
diff --git a/src/main/java/com/iemr/helpline104/utils/TokenDenylist.java b/src/main/java/com/iemr/helpline104/utils/TokenDenylist.java
index fb53ef5..bfb22dd 100644
--- a/src/main/java/com/iemr/helpline104/utils/TokenDenylist.java
+++ b/src/main/java/com/iemr/helpline104/utils/TokenDenylist.java
@@ -4,17 +4,21 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
+@Profile("!swagger")
public class TokenDenylist {
private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
private static final String PREFIX = "denied_";
@Autowired
+ @Qualifier("genericRedisTemplate")
private RedisTemplate redisTemplate;
private String getKey(String jti) {
diff --git a/src/main/java/com/iemr/helpline104/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/helpline104/utils/http/HTTPRequestInterceptor.java
index 693170a..7036833 100644
--- a/src/main/java/com/iemr/helpline104/utils/http/HTTPRequestInterceptor.java
+++ b/src/main/java/com/iemr/helpline104/utils/http/HTTPRequestInterceptor.java
@@ -40,8 +40,10 @@
import jakarta.ws.rs.core.MediaType;
import com.iemr.helpline104.utils.validator.Validator;
+import org.springframework.context.annotation.Profile;
@Component
+@Profile("!swagger")
public class HTTPRequestInterceptor implements HandlerInterceptor {
private final Validator validator;
diff --git a/src/main/java/com/iemr/helpline104/utils/redis/RedisStorage.java b/src/main/java/com/iemr/helpline104/utils/redis/RedisStorage.java
index 69fb95e..e5595c1 100644
--- a/src/main/java/com/iemr/helpline104/utils/redis/RedisStorage.java
+++ b/src/main/java/com/iemr/helpline104/utils/redis/RedisStorage.java
@@ -28,9 +28,11 @@
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.types.Expiration;
+import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
+@Profile("!swagger")
public class RedisStorage {
// @Autowired
// private RedisConnection redisConnection;// = new RedisConnection();
diff --git a/src/main/java/com/iemr/helpline104/utils/sessionobject/SessionObject.java b/src/main/java/com/iemr/helpline104/utils/sessionobject/SessionObject.java
index 3f54972..7f6c0f2 100644
--- a/src/main/java/com/iemr/helpline104/utils/sessionobject/SessionObject.java
+++ b/src/main/java/com/iemr/helpline104/utils/sessionobject/SessionObject.java
@@ -22,6 +22,7 @@
package com.iemr.helpline104.utils.sessionobject;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
@@ -32,6 +33,7 @@
import com.iemr.helpline104.utils.redis.RedisStorage;
@Component
+@Profile("!swagger")
public class SessionObject
{
diff --git a/src/main/java/com/iemr/helpline104/utils/validator/Validator.java b/src/main/java/com/iemr/helpline104/utils/validator/Validator.java
index 6d41a79..a953085 100644
--- a/src/main/java/com/iemr/helpline104/utils/validator/Validator.java
+++ b/src/main/java/com/iemr/helpline104/utils/validator/Validator.java
@@ -26,7 +26,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-
+import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import com.iemr.helpline104.utils.config.ConfigProperties;
@@ -36,6 +36,7 @@
@Service
+@Profile("!swagger")
public class Validator
{
// private static SessionObject session;
diff --git a/src/main/resources/104_swagger.properties b/src/main/resources/104_swagger.properties
new file mode 100644
index 0000000..da9d6d9
--- /dev/null
+++ b/src/main/resources/104_swagger.properties
@@ -0,0 +1,23 @@
+server.port=8091
+# Primary DB – H2 in-memory (MySQL compatibility mode)
+spring.datasource.url=jdbc:h2:mem:swaggerdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false
+spring.datasource.username=SA
+spring.datasource.password=
+spring.datasource.driver-class-name=org.h2.Driver
+# Secondary (Reporting) DB – H2 in-memory
+secondary.datasource.url=jdbc:h2:mem:reportingdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false
+secondary.datasource.username=SA
+secondary.datasource.password=
+secondary.datasource.driver-class-name=org.h2.Driver
+# Common URLs (safe defaults)
+common-url=http://localhost:8080
+sendSMSUrl=http://localhost:8080/sms/sendSMS
+sendEmailGeneralUrl=http://localhost:8080/emailController/sendEmailGeneral
+# Redis
+spring.redis.host=localhost
+# JWT
+jwt.secret=${JWT_SECRET_KEY:#{T(java.util.UUID).randomUUID().toString()}}
+# CORS
+cors.allowed-origins=http://localhost:8091,http://127.0.0.1:9000
+# Logging
+logging.file.name=logs/helpline104-api.log