diff --git a/api-docs/api-docs.yaml b/api-docs/api-docs.yaml
new file mode 100644
index 0000000..427d6c3
--- /dev/null
+++ b/api-docs/api-docs.yaml
@@ -0,0 +1,381 @@
+openapi: 3.0.1
+info:
+ title: UCI Inbound
+ description: UCI Inbound Api Documentation
+ termsOfService: http://swagger.io/terms/
+ license:
+ name: Apache 2.0
+ url: http://springdoc.org
+ version: "1.0"
+servers:
+- url: http://localhost:8085
+ description: Generated server url
+paths:
+ /netcore/whatsApp:
+ post:
+ tags:
+ - Netcore Apis
+ summary: Send message to kafka topic via netcore whatsapp service
+ description: This API is used to get send message to inbound kafka topic received
+ from netcore whatsapp service.
+ operationId: netcoreWhatsApp
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/NetcoreMessageFormat'
+ examples:
+ Text Message:
+ description: Request body for text messages
+ value:
+ messages:
+ - message_id: ABEGkZlgQyWAAgo-sDVSUOa9jH0z
+ from: "919960432580"
+ received_at: "1567090835"
+ context:
+ ncmessage_id: null
+ message_id: null
+ message_type: TEXT
+ text_type:
+ text: Hi UCI
+ required: true
+ responses:
+ "200":
+ description: OK!
+ /gupshup/whatsApp:
+ post:
+ tags:
+ - Gupshup Apis
+ summary: Send message to kafka topic via gupshup whatsapp service
+ description: This API is used to get send message to inbound kafka topic received
+ from gupshup whatsapp service.
+ operationId: gupshupWhatsApp
+ requestBody:
+ content:
+ application/x-www-form-urlencoded:
+ schema:
+ $ref: '#/components/schemas/GSWhatsAppMessage'
+ responses:
+ "200":
+ description: OK!
+ /service/health/kafka:
+ get:
+ tags:
+ - Services Health Api
+ summary: Get Kafka Health
+ description: This API is used to get kafka health status
+ operationId: kafkaStatusCheck
+ responses:
+ "200":
+ description: OK!
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ComponentHealthApiExample'
+ /service/health/cassandra:
+ get:
+ tags:
+ - Services Health Api
+ summary: Get Cassandra Health
+ description: This API is used to get cassandra health status
+ operationId: cassandraStatusCheck
+ responses:
+ "200":
+ description: OK!
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ComponentHealthApiExample'
+ /service/health/campaign:
+ get:
+ tags:
+ - Services Health Api
+ summary: Get Campaign Health
+ description: This API is used to get campaign health status
+ operationId: campaignUrlStatusCheck
+ responses:
+ "200":
+ description: OK!
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ComponentHealthApiExample'
+ /health:
+ get:
+ tags:
+ - System Health Apis
+ summary: Get System Health
+ description: |-
+ This API is used to get system health. It included health of two components.
+ - Kafka
+ - Cassandra
+ operationId: statusCheck
+ responses:
+ "200":
+ description: OK!
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SystemHealthApiExample'
+ /campaign/start:
+ get:
+ tags:
+ - Campaign Apis
+ summary: Start Campaign
+ description: This API is used to start the campaign kafka topic.- The fields
+ marked with an asterisk (*) are mandatory. They cannot be null or empty.
+ operationId: startCampaign
+ parameters:
+ - name: campaignId
+ in: query
+ required: true
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ /campaign/resume:
+ get:
+ tags:
+ - Campaign Apis
+ summary: Resume Campaign
+ description: This API is used to start campaign kafka topic.
+ operationId: resumeCampaign
+ parameters:
+ - name: campaignId
+ in: query
+ required: true
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ /campaign/pause:
+ get:
+ tags:
+ - Campaign Apis
+ summary: Pause Campaign
+ description: This API is used to pause the campaign kafka topic.
+ operationId: pauseCampaign
+ parameters:
+ - name: campaignId
+ in: query
+ required: true
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+components:
+ schemas:
+ MessageContext:
+ type: object
+ properties:
+ ncmessage_id:
+ type: string
+ message_id:
+ type: string
+ NetcoreInboundFile:
+ type: object
+ properties:
+ mime_type:
+ type: string
+ signature:
+ type: string
+ url:
+ type: string
+ caption:
+ type: string
+ NetcoreMessageFormat:
+ type: object
+ properties:
+ messages:
+ type: array
+ items:
+ $ref: '#/components/schemas/NetcoreWhatsAppMessage'
+ NetcoreWhatsAppMessage:
+ type: object
+ properties:
+ waNumber:
+ type: string
+ mobile:
+ type: string
+ replyId:
+ type: string
+ messageId:
+ type: string
+ timestamp:
+ type: string
+ name:
+ type: string
+ version:
+ type: integer
+ format: int32
+ type:
+ type: string
+ text:
+ $ref: '#/components/schemas/TextType'
+ eventType:
+ type: string
+ context:
+ $ref: '#/components/schemas/MessageContext'
+ statusRemark:
+ type: string
+ source:
+ type: string
+ image:
+ $ref: '#/components/schemas/NetcoreInboundFile'
+ document:
+ $ref: '#/components/schemas/NetcoreInboundFile'
+ voice:
+ $ref: '#/components/schemas/NetcoreInboundFile'
+ audio:
+ $ref: '#/components/schemas/NetcoreInboundFile'
+ video:
+ $ref: '#/components/schemas/NetcoreInboundFile'
+ location:
+ type: string
+ response:
+ type: string
+ extra:
+ type: string
+ app:
+ type: string
+ TextType:
+ type: object
+ properties:
+ text:
+ type: string
+ GSWhatsAppMessage:
+ type: object
+ properties:
+ waNumber:
+ type: string
+ mobile:
+ type: string
+ replyId:
+ type: string
+ messageId:
+ type: string
+ timestamp:
+ type: integer
+ format: int64
+ name:
+ type: string
+ version:
+ type: integer
+ format: int32
+ type:
+ type: string
+ text:
+ type: string
+ image:
+ $ref: '#/components/schemas/WAInboundFile'
+ document:
+ $ref: '#/components/schemas/WAInboundFile'
+ voice:
+ $ref: '#/components/schemas/WAInboundFile'
+ audio:
+ $ref: '#/components/schemas/WAInboundFile'
+ video:
+ $ref: '#/components/schemas/WAInboundFile'
+ location:
+ type: string
+ response:
+ type: string
+ extra:
+ type: string
+ app:
+ type: string
+ WAInboundFile:
+ type: object
+ properties:
+ mime_type:
+ type: string
+ signature:
+ type: string
+ url:
+ type: string
+ caption:
+ type: string
+ ComponentHealthApiExample:
+ type: object
+ properties:
+ id:
+ type: string
+ example: api.content.health
+ ver:
+ type: string
+ example: "3.0"
+ ts:
+ type: string
+ example: 2021-09-01T11:14:50Z
+ params:
+ $ref: '#/components/schemas/HealthApiParamsParameter'
+ responseCode:
+ type: string
+ example: OK
+ result:
+ $ref: '#/components/schemas/ComponentHealthApiResultParameter'
+ ComponentHealthApiResultParameter:
+ type: object
+ properties:
+ healthy:
+ type: boolean
+ example: true
+ HealthApiParamsParameter:
+ type: object
+ properties:
+ resmsgid:
+ type: string
+ example: 859fee0c-94d6-4a0d-b786-2025d763b78a
+ msgid:
+ type: string
+ example: "null"
+ err:
+ type: string
+ example: "null"
+ status:
+ type: string
+ example: Successful
+ errmsg:
+ type: string
+ example: "null"
+ HealthApiChecksParameter:
+ type: object
+ properties:
+ name:
+ type: string
+ example: Cassandra
+ healthy:
+ type: boolean
+ example: true
+ HealthApiResultParameter:
+ type: object
+ properties:
+ checks:
+ type: array
+ items:
+ $ref: '#/components/schemas/HealthApiChecksParameter'
+ healthy:
+ type: boolean
+ example: true
+ SystemHealthApiExample:
+ type: object
+ properties:
+ id:
+ type: string
+ example: api.content.health
+ ver:
+ type: string
+ example: "3.0"
+ ts:
+ type: string
+ example: 2021-09-01T11:14:50Z
+ params:
+ $ref: '#/components/schemas/HealthApiParamsParameter'
+ responseCode:
+ type: string
+ example: OK
+ result:
+ $ref: '#/components/schemas/HealthApiResultParameter'
diff --git a/pom.xml b/pom.xml
index ae45bec..1ea5e65 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
jaxb-impl
2.2.11
-
+
org.springframework.boot
spring-boot-starter-test
@@ -98,6 +98,11 @@
1.0
compile
+
+ org.springdoc
+ springdoc-openapi-ui
+ 1.5.2
+
diff --git a/src/main/java/com/uci/inbound/AppConfigInbound.java b/src/main/java/com/uci/inbound/AppConfigInbound.java
index 4706c8e..25ee8c6 100644
--- a/src/main/java/com/uci/inbound/AppConfigInbound.java
+++ b/src/main/java/com/uci/inbound/AppConfigInbound.java
@@ -1,14 +1,27 @@
package com.uci.inbound;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.uci.dao.service.HealthService;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.info.License;
+
@Configuration
public class AppConfigInbound {
- @Bean
- public HealthService healthService() {
- return new HealthService();
- }
+ @Bean
+ public HealthService healthService() {
+ return new HealthService();
+ }
+
+ @Bean
+ public OpenAPI customOpenAPI(@Value("${application-title}") String appTitle,
+ @Value("${application-version}") String appVersion) {
+ return new OpenAPI().info(new Info().title(appTitle).version(appVersion)
+ .description(appTitle + " Api Documentation").termsOfService("http://swagger.io/terms/")
+ .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+ }
}
diff --git a/src/main/java/com/uci/inbound/api/response/examples/ComponentHealthApiExample.java b/src/main/java/com/uci/inbound/api/response/examples/ComponentHealthApiExample.java
new file mode 100644
index 0000000..da05cb0
--- /dev/null
+++ b/src/main/java/com/uci/inbound/api/response/examples/ComponentHealthApiExample.java
@@ -0,0 +1,8 @@
+package com.uci.inbound.api.response.examples;
+
+import com.uci.inbound.api.response.examples.params.ComponentHealthApiResultParameter;
+import com.uci.inbound.api.response.examples.params.HealthApiResultParameter;
+
+public class ComponentHealthApiExample extends HealthApiExample {
+ public ComponentHealthApiResultParameter result;
+}
diff --git a/src/main/java/com/uci/inbound/api/response/examples/HealthApiExample.java b/src/main/java/com/uci/inbound/api/response/examples/HealthApiExample.java
new file mode 100644
index 0000000..1e35117
--- /dev/null
+++ b/src/main/java/com/uci/inbound/api/response/examples/HealthApiExample.java
@@ -0,0 +1,22 @@
+package com.uci.inbound.api.response.examples;
+
+import com.uci.inbound.api.response.examples.params.HealthApiParamsParameter;
+import com.uci.inbound.api.response.examples.params.HealthApiResultParameter;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+public class HealthApiExample {
+ @Schema(example = "api.content.health")
+ public String id;
+
+ @Schema(example = "3.0")
+ public String ver;
+
+ @Schema(example = "2021-09-01T11:14:50Z")
+ public String ts;
+
+ public HealthApiParamsParameter params;
+
+ @Schema(example = "OK")
+ public String responseCode;
+}
diff --git a/src/main/java/com/uci/inbound/api/response/examples/SystemHealthApiExample.java b/src/main/java/com/uci/inbound/api/response/examples/SystemHealthApiExample.java
new file mode 100644
index 0000000..081957d
--- /dev/null
+++ b/src/main/java/com/uci/inbound/api/response/examples/SystemHealthApiExample.java
@@ -0,0 +1,7 @@
+package com.uci.inbound.api.response.examples;
+
+import com.uci.inbound.api.response.examples.params.HealthApiResultParameter;
+
+public class SystemHealthApiExample extends HealthApiExample{
+ public HealthApiResultParameter result;
+}
diff --git a/src/main/java/com/uci/inbound/api/response/examples/params/ComponentHealthApiResultParameter.java b/src/main/java/com/uci/inbound/api/response/examples/params/ComponentHealthApiResultParameter.java
new file mode 100644
index 0000000..82dc0df
--- /dev/null
+++ b/src/main/java/com/uci/inbound/api/response/examples/params/ComponentHealthApiResultParameter.java
@@ -0,0 +1,10 @@
+package com.uci.inbound.api.response.examples.params;
+
+import java.util.List;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+public class ComponentHealthApiResultParameter {
+ @Schema(example = "true")
+ public Boolean healthy;
+}
diff --git a/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiChecksParameter.java b/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiChecksParameter.java
new file mode 100644
index 0000000..a744f1c
--- /dev/null
+++ b/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiChecksParameter.java
@@ -0,0 +1,11 @@
+package com.uci.inbound.api.response.examples.params;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+public class HealthApiChecksParameter {
+ @Schema(example = "Cassandra")
+ public String name;
+
+ @Schema(example = "true")
+ public Boolean healthy;
+}
diff --git a/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiParamsParameter.java b/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiParamsParameter.java
new file mode 100644
index 0000000..23338d2
--- /dev/null
+++ b/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiParamsParameter.java
@@ -0,0 +1,20 @@
+package com.uci.inbound.api.response.examples.params;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+public class HealthApiParamsParameter {
+ @Schema(example = "859fee0c-94d6-4a0d-b786-2025d763b78a")
+ public String resmsgid;
+
+ @Schema(example = "null")
+ public String msgid;
+
+ @Schema(example = "null")
+ public String err;
+
+ @Schema(example = "Successful")
+ public String status;
+
+ @Schema(example = "null")
+ public String errmsg;
+}
diff --git a/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiResultParameter.java b/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiResultParameter.java
new file mode 100644
index 0000000..e989b07
--- /dev/null
+++ b/src/main/java/com/uci/inbound/api/response/examples/params/HealthApiResultParameter.java
@@ -0,0 +1,12 @@
+package com.uci.inbound.api.response.examples.params;
+
+import java.util.List;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+public class HealthApiResultParameter {
+ public List checks;
+
+ @Schema(example = "true")
+ public Boolean healthy;
+}
diff --git a/src/main/java/com/uci/inbound/cdac/CDACConverter.java b/src/main/java/com/uci/inbound/cdac/CDACConverter.java
index 29da7e6..b07bcb5 100644
--- a/src/main/java/com/uci/inbound/cdac/CDACConverter.java
+++ b/src/main/java/com/uci/inbound/cdac/CDACConverter.java
@@ -6,6 +6,8 @@
import com.uci.inbound.utils.XMsgProcessingUtil;
import com.uci.dao.repository.XMessageRepository;
import com.uci.utils.kafka.SimpleProducer;
+
+import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -42,7 +44,8 @@ public class CDACConverter {
@Autowired
public XMessageRepository xmsgRepo;
-
+
+ @Operation(hidden = true)
@RequestMapping(value = "/sms/bulk/", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void cdacBulk(@Valid CommonMessage message) throws JsonProcessingException {
@@ -56,6 +59,7 @@ public void cdacBulk(@Valid CommonMessage message) throws JsonProcessingExceptio
.build().process();
}
+ @Operation(hidden = true)
@RequestMapping(value = "/sms/single/", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void cdacSingle(@Valid CommonMessage message) throws JsonProcessingException {
diff --git a/src/main/java/com/uci/inbound/diksha/web/DikshaWebController.java b/src/main/java/com/uci/inbound/diksha/web/DikshaWebController.java
index e6db773..8845af7 100644
--- a/src/main/java/com/uci/inbound/diksha/web/DikshaWebController.java
+++ b/src/main/java/com/uci/inbound/diksha/web/DikshaWebController.java
@@ -3,10 +3,17 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.uci.adapter.sunbird.web.SunbirdWebPortalAdapter;
import com.uci.adapter.sunbird.web.inbound.DikshaWebMessageFormat;
+import com.uci.inbound.api.response.examples.ComponentHealthApiExample;
import com.uci.inbound.utils.XMsgProcessingUtil;
import com.uci.dao.repository.XMessageRepository;
import com.uci.utils.BotService;
import com.uci.utils.kafka.SimpleProducer;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -23,39 +30,35 @@
@RequestMapping(value = "/diksha")
public class DikshaWebController {
- @Value("${inboundProcessed}")
- private String inboundProcessed;
+ @Value("${inboundProcessed}")
+ private String inboundProcessed;
- @Value("${inbound-error}")
- private String inboundError;
+ @Value("${inbound-error}")
+ private String inboundError;
- private SunbirdWebPortalAdapter sunbirdWebPortalAdapter;
+ private SunbirdWebPortalAdapter sunbirdWebPortalAdapter;
- @Autowired
- public SimpleProducer kafkaProducer;
+ @Autowired
+ public SimpleProducer kafkaProducer;
- @Autowired
- public XMessageRepository xmsgRepo;
+ @Autowired
+ public XMessageRepository xmsgRepo;
- @Autowired
- public BotService botService;
+ @Autowired
+ public BotService botService;
- @RequestMapping(value = "/web", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
- public void dikshaWeb(@RequestBody DikshaWebMessageFormat message) throws JsonProcessingException, JAXBException {
+ @Operation(hidden = true, summary = "Send message to kafka topic via sunbird service", description = "This API is used to get send message to inbound kafka topic received from sunbird service.")
+ @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK!", content = {
+ @Content }) })
+ @RequestMapping(value = "/web", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
+ public void dikshaWeb(@RequestBody DikshaWebMessageFormat message) throws JsonProcessingException, JAXBException {
- System.out.println(message.toString());
+ System.out.println(message.toString());
- sunbirdWebPortalAdapter = SunbirdWebPortalAdapter.builder()
- .build();
+ sunbirdWebPortalAdapter = SunbirdWebPortalAdapter.builder().build();
- XMsgProcessingUtil.builder()
- .adapter(sunbirdWebPortalAdapter)
- .xMsgRepo(xmsgRepo)
- .inboundMessage(message.getMessages()[0])
- .topicFailure(inboundError)
- .topicSuccess(inboundProcessed)
- .kafkaProducer(kafkaProducer)
- .build()
- .process();
- }
+ XMsgProcessingUtil.builder().adapter(sunbirdWebPortalAdapter).xMsgRepo(xmsgRepo)
+ .inboundMessage(message.getMessages()[0]).topicFailure(inboundError).topicSuccess(inboundProcessed)
+ .kafkaProducer(kafkaProducer).build().process();
+ }
}
diff --git a/src/main/java/com/uci/inbound/health/HealthController.java b/src/main/java/com/uci/inbound/health/HealthController.java
index b490b83..e14a6e4 100644
--- a/src/main/java/com/uci/inbound/health/HealthController.java
+++ b/src/main/java/com/uci/inbound/health/HealthController.java
@@ -5,7 +5,15 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.uci.dao.service.HealthService;
+import com.uci.inbound.api.response.examples.HealthApiExample;
+import com.uci.inbound.api.response.examples.SystemHealthApiExample;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@@ -20,24 +28,30 @@
@Slf4j
@RestController
+@Tag(name = "System Health Apis")
public class HealthController {
-
+
@Autowired
private HealthService healthService;
-
- @RequestMapping(value = "/health", method = RequestMethod.GET, produces = { "application/json", "text/json" })
- public ResponseEntity statusCheck() throws JsonProcessingException, IOException {
- ObjectMapper mapper = new ObjectMapper();
- /* Current Date Time */
- LocalDateTime localNow = LocalDateTime.now();
- DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
- String dateString = fmt.format(localNow).toString();
-
- JsonNode jsonNode = mapper.readTree("{\"id\":\"api.content.health\",\"ver\":\"3.0\",\"ts\":\"2021-06-26T22:47:05Z+05:30\",\"params\":{\"resmsgid\":\"859fee0c-94d6-4a0d-b786-2025d763b78a\",\"msgid\":null,\"err\":null,\"status\":\"successful\",\"errmsg\":null},\"responseCode\":\"OK\",\"result\":{\"checks\":[{\"name\":\"redis cache\",\"healthy\":true},{\"name\":\"graph db\",\"healthy\":true},{\"name\":\"cassandra db\",\"healthy\":true}],\"healthy\":true}}");
-
- ((ObjectNode) jsonNode).put("ts", dateString);
- ((ObjectNode) jsonNode).put("result", healthService.getAllHealthNode());
-
- return ResponseEntity.ok(jsonNode);
- }
+
+ @Operation(summary = "Get System Health", description = "This API is used to get system health. It included health of two components.\n"
+ + "- Kafka\n" + "- Cassandra")
+ @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK!", content = {
+ @Content(mediaType = "application/json", schema = @Schema(implementation = SystemHealthApiExample.class)) }) })
+ @RequestMapping(value = "/health", method = RequestMethod.GET, produces = { "application/json", "text/json" })
+ public ResponseEntity statusCheck() throws JsonProcessingException, IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ /* Current Date Time */
+ LocalDateTime localNow = LocalDateTime.now();
+ DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ String dateString = fmt.format(localNow).toString();
+
+ JsonNode jsonNode = mapper.readTree(
+ "{\"id\":\"api.content.health\",\"ver\":\"3.0\",\"ts\":\"2021-06-26T22:47:05Z+05:30\",\"params\":{\"resmsgid\":\"859fee0c-94d6-4a0d-b786-2025d763b78a\",\"msgid\":null,\"err\":null,\"status\":\"successful\",\"errmsg\":null},\"responseCode\":\"OK\",\"result\":{\"checks\":[{\"name\":\"redis cache\",\"healthy\":true},{\"name\":\"graph db\",\"healthy\":true},{\"name\":\"cassandra db\",\"healthy\":true}],\"healthy\":true}}");
+
+ ((ObjectNode) jsonNode).put("ts", dateString);
+ ((ObjectNode) jsonNode).put("result", healthService.getAllHealthNode());
+
+ return ResponseEntity.ok(jsonNode);
+ }
}
diff --git a/src/main/java/com/uci/inbound/health/ServiceStatusController.java b/src/main/java/com/uci/inbound/health/ServiceStatusController.java
index 9a80d13..9272b4c 100644
--- a/src/main/java/com/uci/inbound/health/ServiceStatusController.java
+++ b/src/main/java/com/uci/inbound/health/ServiceStatusController.java
@@ -9,8 +9,16 @@
import com.uci.dao.repository.XMessageRepository;
import com.uci.utils.BotService;
import com.uci.dao.service.HealthService;
+import com.uci.inbound.api.response.examples.ComponentHealthApiExample;
+import com.uci.inbound.api.response.examples.HealthApiExample;
import com.uci.utils.kafka.KafkaConfig;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -31,44 +39,57 @@
@Slf4j
@RestController
@RequestMapping(value = "/service")
+@Tag(name = "Services Health Api")
public class ServiceStatusController {
- @Autowired
+ @Autowired
private HealthService healthService;
-
- @RequestMapping(value = "/health/cassandra", method = RequestMethod.GET, produces = { "application/json", "text/json" })
- public ResponseEntity cassandraStatusCheck() throws IOException, JsonProcessingException {
- JsonNode jsonNode = getResponseJsonNode();
- ((ObjectNode) jsonNode).put("result", healthService.getCassandraHealthNode());
-
- return ResponseEntity.ok(jsonNode);
- }
-
- @RequestMapping(value = "/health/kafka", method = RequestMethod.GET, produces = { "application/json", "text/json" })
- public ResponseEntity kafkaStatusCheck() throws IOException, JsonProcessingException {
- JsonNode jsonNode = getResponseJsonNode();
- ((ObjectNode) jsonNode).put("result", healthService.getKafkaHealthNode());
-
- return ResponseEntity.ok(jsonNode);
- }
-
- @RequestMapping(value = "/health/campaign", method = RequestMethod.GET, produces = { "application/json", "text/json" })
- public ResponseEntity campaignUrlStatusCheck() throws JsonProcessingException, IOException {
- JsonNode jsonNode = getResponseJsonNode();
- ((ObjectNode) jsonNode).put("result", healthService.getCampaignUrlHealthNode());
-
- return ResponseEntity.ok(jsonNode);
- }
-
- /**
- * Returns json node for service response
- *
- * @return JsonNode
- * @throws JsonMappingException
- * @throws JsonProcessingException
- */
- private JsonNode getResponseJsonNode() throws JsonMappingException, JsonProcessingException {
- ObjectMapper mapper = new ObjectMapper();
- JsonNode jsonNode = mapper.readTree("{\"id\":\"api.content.service.health\",\"ver\":\"3.0\",\"ts\":null,\"params\":{\"resmsgid\":null,\"msgid\":null,\"err\":null,\"status\":\"successful\",\"errmsg\":null},\"responseCode\":\"OK\",\"result\":{\"healthy\":false}}");
- return jsonNode;
- }
+
+ @Operation(summary = "Get Cassandra Health", description = "This API is used to get cassandra health status")
+ @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK!", content = {
+ @Content(mediaType = "application/json", schema = @Schema(implementation = ComponentHealthApiExample.class)) }) })
+ @RequestMapping(value = "/health/cassandra", method = RequestMethod.GET, produces = { "application/json",
+ "text/json" })
+ public ResponseEntity cassandraStatusCheck() throws IOException, JsonProcessingException {
+ JsonNode jsonNode = getResponseJsonNode();
+ ((ObjectNode) jsonNode).put("result", healthService.getCassandraHealthNode());
+
+ return ResponseEntity.ok(jsonNode);
+ }
+
+ @Operation(summary = "Get Kafka Health", description = "This API is used to get kafka health status")
+ @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK!", content = {
+ @Content(mediaType = "application/json", schema = @Schema(implementation = ComponentHealthApiExample.class)) }) })
+ @RequestMapping(value = "/health/kafka", method = RequestMethod.GET, produces = { "application/json", "text/json" })
+ public ResponseEntity kafkaStatusCheck() throws IOException, JsonProcessingException {
+ JsonNode jsonNode = getResponseJsonNode();
+ ((ObjectNode) jsonNode).put("result", healthService.getKafkaHealthNode());
+
+ return ResponseEntity.ok(jsonNode);
+ }
+
+ @Operation(summary = "Get Campaign Health", description = "This API is used to get campaign health status")
+ @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK!", content = {
+ @Content(mediaType = "application/json", schema = @Schema(implementation = ComponentHealthApiExample.class)) }) })
+ @RequestMapping(value = "/health/campaign", method = RequestMethod.GET, produces = { "application/json",
+ "text/json" })
+ public ResponseEntity campaignUrlStatusCheck() throws JsonProcessingException, IOException {
+ JsonNode jsonNode = getResponseJsonNode();
+ ((ObjectNode) jsonNode).put("result", healthService.getCampaignUrlHealthNode());
+
+ return ResponseEntity.ok(jsonNode);
+ }
+
+ /**
+ * Returns json node for service response
+ *
+ * @return JsonNode
+ * @throws JsonMappingException
+ * @throws JsonProcessingException
+ */
+ private JsonNode getResponseJsonNode() throws JsonMappingException, JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonNode = mapper.readTree(
+ "{\"id\":\"api.content.service.health\",\"ver\":\"3.0\",\"ts\":null,\"params\":{\"resmsgid\":null,\"msgid\":null,\"err\":null,\"status\":\"successful\",\"errmsg\":null},\"responseCode\":\"OK\",\"result\":{\"healthy\":false}}");
+ return jsonNode;
+ }
}
diff --git a/src/main/java/com/uci/inbound/incoming/Campaign.java b/src/main/java/com/uci/inbound/incoming/Campaign.java
index 3f759e9..7f98467 100644
--- a/src/main/java/com/uci/inbound/incoming/Campaign.java
+++ b/src/main/java/com/uci/inbound/incoming/Campaign.java
@@ -6,6 +6,12 @@
import com.uci.adapter.cdac.TrackDetails;
import com.uci.adapter.provider.factory.ProviderFactory;
import com.uci.utils.kafka.SimpleProducer;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -17,6 +23,7 @@
@CrossOrigin
@RestController
@RequestMapping(value = "/campaign")
+@Tag(name = "Campaign Apis")
public class Campaign {
@Value("${campaign}")
private String campaign;
@@ -27,25 +34,32 @@ public class Campaign {
@Autowired
private ProviderFactory factoryProvider;
- @RequestMapping(value = "/start", method = RequestMethod.GET)
+ @Operation(summary = "Start Campaign", description = "This API is used to start the campaign kafka topic."
+ + "- The fields marked with an asterisk (*) are mandatory. They cannot be null or empty.")
+ @RequestMapping(value = "/start", method = RequestMethod.GET)
public void startCampaign(@RequestParam("campaignId") String campaignId) throws JsonProcessingException, JAXBException {
kafkaProducer.send(campaign, campaignId);
return;
}
- @RequestMapping(value = "/pause", method = RequestMethod.GET)
+ @Operation(summary = "Pause Campaign", description = "This API is used to pause the campaign kafka topic.")
+ @RequestMapping(value = "/pause", method = RequestMethod.GET)
public void pauseCampaign(@RequestParam("campaignId") String campaignId) throws JsonProcessingException, JAXBException {
kafkaProducer.send(campaign, campaignId);
return;
}
- @RequestMapping(value = "/resume", method = RequestMethod.GET)
+ @Operation(summary = "Resume Campaign", description = "This API is used to start campaign kafka topic.")
+ @RequestMapping(value = "/resume", method = RequestMethod.GET)
public void resumeCampaign(@RequestParam("campaignId") String campaignId) throws JsonProcessingException, JAXBException {
kafkaProducer.send(campaign, campaignId);
return;
}
- @RequestMapping(value = "/status/cdac/bulk", method = RequestMethod.GET)
+ @Operation(hidden = true, summary = "Get Campaign Status", description = "This API is used to get campaign status from CDAC Sms Adapter.")
+ @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK!", content = {
+ @Content }) })
+ @RequestMapping(value = "/status/cdac/bulk", method = RequestMethod.GET)
public TrackDetails getCampaignStatus(@RequestParam("campaignId") String campaignId) {
CdacBulkSmsAdapter iprovider = (CdacBulkSmsAdapter) factoryProvider.getProvider("cdac", "SMS");
try {
diff --git a/src/main/java/com/uci/inbound/incoming/GupShupOptIn.java b/src/main/java/com/uci/inbound/incoming/GupShupOptIn.java
index 5c8839a..da3cc05 100644
--- a/src/main/java/com/uci/inbound/incoming/GupShupOptIn.java
+++ b/src/main/java/com/uci/inbound/incoming/GupShupOptIn.java
@@ -1,6 +1,8 @@
package com.uci.inbound.incoming;
import com.uci.adapter.gs.whatsapp.GSWhatsAppMessage;
+
+import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -13,6 +15,8 @@
@RestController
@RequestMapping(value = "/whatsapp")
public class GupShupOptIn {
+
+ @Operation(hidden = true)
@RequestMapping(value = "/opt-in", method = RequestMethod.POST)
public void gupShupWhatsApp(@Valid @RequestBody GSWhatsAppMessage message) throws Exception {
diff --git a/src/main/java/com/uci/inbound/incoming/GupShupWhatsappConverter.java b/src/main/java/com/uci/inbound/incoming/GupShupWhatsappConverter.java
index 3a454e7..a3cdaae 100644
--- a/src/main/java/com/uci/inbound/incoming/GupShupWhatsappConverter.java
+++ b/src/main/java/com/uci/inbound/incoming/GupShupWhatsappConverter.java
@@ -4,10 +4,23 @@
import javax.xml.bind.JAXBException;
import com.uci.adapter.gs.whatsapp.GupShupWhatsappAdapter;
+import com.uci.adapter.netcore.whatsapp.inbound.NetcoreMessageFormat;
import com.uci.dao.repository.XMessageRepository;
import com.uci.utils.BotService;
import com.uci.inbound.utils.XMsgProcessingUtil;
import com.uci.utils.kafka.SimpleProducer;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
@@ -23,6 +36,7 @@
@Slf4j
@RestController
@RequestMapping(value = "/gupshup")
+@Tag(name = "Gupshup Apis")
public class GupShupWhatsappConverter {
@Value("${inboundProcessed}")
@@ -45,7 +59,44 @@ public class GupShupWhatsappConverter {
@Autowired
public BotService botService;
- @RequestMapping(value = "/whatsApp", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
+ @Operation(summary = "Send message to kafka topic via gupshup whatsapp service", description = "This API is used to get send message to inbound kafka topic received from gupshup whatsapp service.")
+// @Parameters(value = {
+// @Parameter(name = "waNumber", examples={ @ExampleObject(name = "Text Message", description = "This is WhatsApp Business number on which the "
+// + "customer has sent a message", value = "919560222091")}),
+// @Parameter(name = "mobile", examples={ @ExampleObject(name = "Text Message", description = "The phone number of the customer who has sent "
+// + "the message", value = "919004371797")}),
+// @Parameter(name = "replyId", examples={ @ExampleObject(name = "Text Message", description = "The unique system identifier for the original message sent by the business to the customer, on "
+// + "which the customer has replied (swipe left action on"
+// + "WhatsApp to reply to a specific message). This is the"
+// + "transaction ID of the original message.", value = "3900363981641897487")}),
+// @Parameter(name = "messageId", examples={ @ExampleObject(name = "Text Message", description = "The unique identifier for the original message sent "
+// + "by the business to the customer, on which the"
+// + "customer has replied (swipe left action on WhatsApp"
+// + "to reply to a specific message). This is the message"
+// + "ID that can be a custom value specified in the Send"
+// + "Message API request.", value = "custom Message ID")}),
+// @Parameter(name = "text", examples={ @ExampleObject(name = "Text Message", description = "The text message sent by the user", value = "Hi UCI")}),
+// @Parameter(name = "type", examples={ @ExampleObject(name = "Text Message", description = "The name of the Gupshup app to which the"
+// + "customer has sent a message on WhatsApp\n."
+// + "Must be one of : text, image, document, voice, audio, video,"
+// + "location, contacts", value = "text")}),
+// @Parameter(name = "timestamp", examples={ @ExampleObject(name = "Text Message", description = "The time in unix timestamp in milliseconds when the"
+// + "message sent by the customer was received by"
+// + "Gupshup", value = "1564471290000")})
+// })
+// @RequestBody(content = @Content(
+// mediaType = "application/x-www-form-urlencoded",
+// schema = @Schema(implementation = GSWhatsAppMessage.class),
+// examples = {
+// @ExampleObject(
+// name = "waNumber", description = "Request body for text messages",
+// value = "test")
+// }
+// )
+// )
+ @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK!", content = {
+ @Content }) })
+ @RequestMapping(value = "/whatsApp", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void gupshupWhatsApp(@Valid GSWhatsAppMessage message) throws JsonProcessingException, JAXBException {
gupShupWhatsappAdapter = GupShupWhatsappAdapter.builder()
diff --git a/src/main/java/com/uci/inbound/incoming/InternalBot.java b/src/main/java/com/uci/inbound/incoming/InternalBot.java
index 9f2c45a..10b9407 100644
--- a/src/main/java/com/uci/inbound/incoming/InternalBot.java
+++ b/src/main/java/com/uci/inbound/incoming/InternalBot.java
@@ -4,6 +4,7 @@
import com.uci.adapter.provider.factory.ProviderFactory;
import com.uci.utils.kafka.SimpleProducer;
import io.fusionauth.domain.User;
+import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -30,6 +31,7 @@ public class InternalBot {
@Autowired
private ProviderFactory factoryProvider;
+ @Operation(hidden = true)
@RequestMapping(value = "/delete-leave", method = RequestMethod.GET)
public ResponseEntity deleteLeave(
@RequestParam(value = "userEmail", required = false) String userEmail,
@@ -40,6 +42,7 @@ public ResponseEntity deleteLeave(
return restTemplate.getForEntity(url, User.class);
}
+ @Operation(hidden = true)
@RequestMapping(value = "/approve-leave", method = RequestMethod.GET)
public ResponseEntity approveLeave(
@RequestParam(value = "userEmail", required = false) String userEmail,
@@ -50,6 +53,7 @@ public ResponseEntity approveLeave(
return restTemplate.getForEntity(url, User.class);
}
+ @Operation(hidden = true)
@RequestMapping(value = "/reject-leave", method = RequestMethod.GET)
public ResponseEntity rejectLeave(
@RequestParam(value = "userEmail", required = false) String userEmail,
diff --git a/src/main/java/com/uci/inbound/netcore/NetcoreWhatsappConverter.java b/src/main/java/com/uci/inbound/netcore/NetcoreWhatsappConverter.java
index ba5a200..744addf 100644
--- a/src/main/java/com/uci/inbound/netcore/NetcoreWhatsappConverter.java
+++ b/src/main/java/com/uci/inbound/netcore/NetcoreWhatsappConverter.java
@@ -2,10 +2,21 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.uci.adapter.netcore.whatsapp.inbound.NetcoreMessageFormat;
+import com.uci.adapter.gs.whatsapp.GSWhatsAppMessage;
import com.uci.adapter.netcore.whatsapp.NetcoreWhatsappAdapter;
import com.uci.inbound.utils.XMsgProcessingUtil;
import com.uci.dao.repository.XMessageRepository;
import com.uci.utils.kafka.SimpleProducer;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import com.uci.utils.BotService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -16,51 +27,73 @@
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
+import java.util.ArrayList;
+
import javax.xml.bind.JAXBException;
@Slf4j
@RestController
@RequestMapping(value = "/netcore")
+@Tag(name = "Netcore Apis")
public class NetcoreWhatsappConverter {
- @Value("${inboundProcessed}")
- private String inboundProcessed;
-
- @Value("${gupshup-opted-out}")
- private String optedOut;
+ @Value("${inboundProcessed}")
+ private String inboundProcessed;
- @Value("${inbound-error}")
- private String inboundError;
+ @Value("${gupshup-opted-out}")
+ private String optedOut;
- private NetcoreWhatsappAdapter netcoreWhatsappAdapter;
+ @Value("${inbound-error}")
+ private String inboundError;
- @Autowired
- public SimpleProducer kafkaProducer;
+ private NetcoreWhatsappAdapter netcoreWhatsappAdapter;
- @Autowired
- public XMessageRepository xmsgRepo;
+ @Autowired
+ public SimpleProducer kafkaProducer;
- @Autowired
- public BotService botService;
+ @Autowired
+ public XMessageRepository xmsgRepo;
- @RequestMapping(value = "/whatsApp", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
- public void netcoreWhatsApp(@RequestBody NetcoreMessageFormat message) throws JsonProcessingException, JAXBException {
+ @Autowired
+ public BotService botService;
+
+ @Operation(summary = "Send message to kafka topic via netcore whatsapp service", description = "This API is used to get send message to inbound kafka topic received from netcore whatsapp service.")
+ @io.swagger.v3.oas.annotations.parameters.RequestBody(
+ content = @Content(
+ schema = @Schema(implementation = NetcoreMessageFormat.class),
+ examples = {
+ @ExampleObject(
+ name = "Text Message", description = "Request body for text messages",
+ value = "{\n"
+ + " \"messages\": [\n"
+ + " {\n"
+ + " \"message_id\": \"ABEGkZlgQyWAAgo-sDVSUOa9jH0z\",\n"
+ + " \"from\": \"919960432580\",\n"
+ + " \"received_at\": \"1567090835\",\n"
+ + " \"context\": {\n"
+ + " \"ncmessage_id\": null,\n"
+ + " \"message_id\": null\n"
+ + " },\n"
+ + " \"message_type\": \"TEXT\",\n"
+ + " \"text_type\": {\n"
+ + " \"text\": \"Hi UCI\"\n"
+ + " }\n"
+ + " }\n"
+ + " ]\n"
+ + "}")
+// , @ExampleObject(name = "test2", value = "test2")
+ }))
+ @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK!", content = { @Content }) })
+ @RequestMapping(value = "/whatsApp", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
+ public void netcoreWhatsApp(@RequestBody NetcoreMessageFormat message)
+ throws JsonProcessingException, JAXBException {
- System.out.println(message.toString());
+ System.out.println(message.toString());
- netcoreWhatsappAdapter = NetcoreWhatsappAdapter.builder()
- .botservice(botService)
- .build();
+ netcoreWhatsappAdapter = NetcoreWhatsappAdapter.builder().botservice(botService).build();
- XMsgProcessingUtil.builder()
- .adapter(netcoreWhatsappAdapter)
- .xMsgRepo(xmsgRepo)
- .inboundMessage(message.getMessages()[0])
- .topicFailure(inboundError)
- .topicSuccess(inboundProcessed)
- .kafkaProducer(kafkaProducer)
- .botService(botService)
- .build()
- .process();
- }
+ XMsgProcessingUtil.builder().adapter(netcoreWhatsappAdapter).xMsgRepo(xmsgRepo)
+ .inboundMessage(message.getMessages()[0]).topicFailure(inboundError).topicSuccess(inboundProcessed)
+ .kafkaProducer(kafkaProducer).botService(botService).build().process();
+ }
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 965059e..654f6fc 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -29,5 +29,8 @@ campaign.url = ${CAMPAIGN_URL}
campaign.admin.token = ${CAMPAIGN_ADMIN_TOKEN}
+application-title=UCI Inbound
+application-version=1.0
+