From 2da10eb591bbdae702a89bb2a17872be16a8f2c2 Mon Sep 17 00:00:00 2001 From: Surabhi Date: Wed, 25 Aug 2021 14:27:27 +0530 Subject: [PATCH 1/4] Swagger ui - api docs --- pom.xml | 12 +++++++++++- .../java/com/uci/inbound/AppConfigInbound.java | 14 ++++++++++++++ src/main/java/com/uci/inbound/Inbound.java | 3 +++ .../inbound/health/ServiceStatusController.java | 7 +++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ae45bec..58f0bca 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,16 @@ 1.0 compile + + io.springfox + springfox-swagger2 + 2.7.0 + + + io.springfox + springfox-swagger-ui + 2.7.0 + diff --git a/src/main/java/com/uci/inbound/AppConfigInbound.java b/src/main/java/com/uci/inbound/AppConfigInbound.java index 4706c8e..fa4d700 100644 --- a/src/main/java/com/uci/inbound/AppConfigInbound.java +++ b/src/main/java/com/uci/inbound/AppConfigInbound.java @@ -5,10 +5,24 @@ import com.uci.dao.service.HealthService; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + @Configuration public class AppConfigInbound { @Bean public HealthService healthService() { return new HealthService(); } + + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build(); + } } diff --git a/src/main/java/com/uci/inbound/Inbound.java b/src/main/java/com/uci/inbound/Inbound.java index 28792d9..6b50464 100644 --- a/src/main/java/com/uci/inbound/Inbound.java +++ b/src/main/java/com/uci/inbound/Inbound.java @@ -12,6 +12,8 @@ import com.uci.dao.service.HealthService; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + @EnableKafka @EnableReactiveCassandraRepositories("com.uci.dao") @EntityScan("com.uci.dao") @@ -23,6 +25,7 @@ }) @SpringBootApplication @ComponentScan(basePackages = {"com.uci.inbound", "com.uci.adapter", "com.uci.utils"}) +@EnableSwagger2 public class Inbound { public static void main(String[] args) { SpringApplication.run(Inbound.class, args); diff --git a/src/main/java/com/uci/inbound/health/ServiceStatusController.java b/src/main/java/com/uci/inbound/health/ServiceStatusController.java index 9a80d13..90304b8 100644 --- a/src/main/java/com/uci/inbound/health/ServiceStatusController.java +++ b/src/main/java/com/uci/inbound/health/ServiceStatusController.java @@ -59,6 +59,13 @@ public ResponseEntity campaignUrlStatusCheck() throws JsonProcessingEx return ResponseEntity.ok(jsonNode); } + @RequestMapping(value = "/health/test", method = RequestMethod.POST, produces = { "application/json", "text/json" }) + public ResponseEntity testStatusCheck() throws JsonProcessingException, IOException { + JsonNode jsonNode = getResponseJsonNode(); + + return ResponseEntity.ok(jsonNode); + } + /** * Returns json node for service response * From d9e28cfdf4f5242b0d3bc5be112f4402eac46842 Mon Sep 17 00:00:00 2001 From: Surabhi Date: Wed, 1 Sep 2021 10:45:36 +0530 Subject: [PATCH 2/4] api-docs yaml for inbound --- api-docs/api-docs.yaml | 1067 +++++++++++++++++ pom.xml | 11 +- .../com/uci/inbound/AppConfigInbound.java | 14 - src/main/java/com/uci/inbound/Inbound.java | 3 - .../health/ServiceStatusController.java | 7 - 5 files changed, 1070 insertions(+), 32 deletions(-) create mode 100644 api-docs/api-docs.yaml diff --git a/api-docs/api-docs.yaml b/api-docs/api-docs.yaml new file mode 100644 index 0000000..4ddc921 --- /dev/null +++ b/api-docs/api-docs.yaml @@ -0,0 +1,1067 @@ +openapi: 3.0.1 +info: + title: OpenAPI definition + version: v0 +servers: +- url: http://localhost:8085 + description: Generated server url +paths: + /whatsapp/opt-in: + post: + tags: + - gup-shup-opt-in + operationId: gupShupWhatsApp + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GSWhatsAppMessage' + required: true + responses: + "200": + description: OK + /netcore/whatsApp: + post: + tags: + - netcore-whatsapp-converter + operationId: netcoreWhatsApp + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/NetcoreMessageFormat' + required: true + responses: + "200": + description: OK + /gupshup/whatsApp: + post: + tags: + - gup-shup-whatsapp-converter + operationId: gupshupWhatsApp + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/GSWhatsAppMessage' + responses: + "200": + description: OK + /diksha/web: + post: + tags: + - diksha-web-controller + operationId: dikshaWeb + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DikshaWebMessageFormat' + required: true + responses: + "200": + description: OK + /cdac/sms/single/: + post: + tags: + - cdac-converter + operationId: cdacSingle + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/CommonMessage' + responses: + "200": + description: OK + /cdac/sms/bulk/: + post: + tags: + - cdac-converter + operationId: cdacBulk + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/CommonMessage' + responses: + "200": + description: OK + /service/health/kafka: + get: + tags: + - service-status-controller + operationId: kafkaStatusCheck + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/JsonNode' + text/json: + schema: + $ref: '#/components/schemas/JsonNode' + /service/health/cassandra: + get: + tags: + - service-status-controller + operationId: cassandraStatusCheck + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/JsonNode' + text/json: + schema: + $ref: '#/components/schemas/JsonNode' + /service/health/campaign: + get: + tags: + - service-status-controller + operationId: campaignUrlStatusCheck + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/JsonNode' + text/json: + schema: + $ref: '#/components/schemas/JsonNode' + /internalBot/reject-leave: + get: + tags: + - internal-bot + operationId: rejectLeave + parameters: + - name: userEmail + in: query + required: false + schema: + type: string + - name: workingDays + in: query + required: false + schema: + type: integer + format: int32 + responses: + "200": + description: OK + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + /internalBot/delete-leave: + get: + tags: + - internal-bot + operationId: deleteLeave + parameters: + - name: userEmail + in: query + required: false + schema: + type: string + - name: workingDays + in: query + required: false + schema: + type: integer + format: int32 + responses: + "200": + description: OK + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + /internalBot/approve-leave: + get: + tags: + - internal-bot + operationId: approveLeave + parameters: + - name: userEmail + in: query + required: false + schema: + type: string + - name: workingDays + in: query + required: false + schema: + type: integer + format: int32 + responses: + "200": + description: OK + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + /health: + get: + tags: + - health-controller + operationId: statusCheck + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/JsonNode' + text/json: + schema: + $ref: '#/components/schemas/JsonNode' + /campaign/status/cdac/bulk: + get: + tags: + - campaign + operationId: getCampaignStatus + parameters: + - name: campaignId + in: query + required: true + schema: + type: string + responses: + "200": + description: OK + content: + '*/*': + schema: + $ref: '#/components/schemas/TrackDetails' + /campaign/start: + get: + tags: + - campaign + operationId: startCampaign + parameters: + - name: campaignId + in: query + required: true + schema: + type: string + responses: + "200": + description: OK + /campaign/resume: + get: + tags: + - campaign + operationId: resumeCampaign + parameters: + - name: campaignId + in: query + required: true + schema: + type: string + responses: + "200": + description: OK + /campaign/pause: + get: + tags: + - campaign + operationId: pauseCampaign + parameters: + - name: campaignId + in: query + required: true + schema: + type: string + responses: + "200": + description: OK +components: + schemas: + 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 + 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 + DikshaWebMessageFormat: + type: object + properties: + messages: + type: array + items: + $ref: '#/components/schemas/SunbirdWebMessage' + SunbirdWebMessage: + type: object + properties: + messageId: + type: string + text: + type: string + userId: + type: string + appId: + type: string + channel: + type: string + from: + type: string + context: + type: object + additionalProperties: + type: object + CommonMessage: + type: object + JsonNode: + type: object + properties: + number: + type: boolean + bigInteger: + type: boolean + valueNode: + type: boolean + containerNode: + type: boolean + missingNode: + type: boolean + object: + type: boolean + pojo: + type: boolean + integralNumber: + type: boolean + floatingPointNumber: + type: boolean + short: + type: boolean + int: + type: boolean + long: + type: boolean + double: + type: boolean + bigDecimal: + type: boolean + textual: + type: boolean + boolean: + type: boolean + binary: + type: boolean + float: + type: boolean + nodeType: + type: string + enum: + - ARRAY + - BINARY + - BOOLEAN + - MISSING + - "NULL" + - NUMBER + - OBJECT + - POJO + - STRING + array: + type: boolean + empty: + type: boolean + null: + type: boolean + GroupMember: + type: object + properties: + data: + type: object + additionalProperties: + type: object + groupId: + type: string + format: uuid + id: + type: string + format: uuid + insertInstant: + type: string + format: date-time + userId: + type: string + format: uuid + LocalTime: + type: object + properties: + hour: + type: integer + format: int32 + minute: + type: integer + format: int32 + second: + type: integer + format: int32 + nano: + type: integer + format: int32 + User: + type: object + properties: + encryptionScheme: + type: string + factor: + type: integer + format: int32 + id: + type: string + format: uuid + password: + type: string + passwordChangeRequired: + type: boolean + passwordLastUpdateInstant: + type: string + format: date-time + salt: + type: string + verified: + type: boolean + preferredLanguages: + type: array + items: + type: object + properties: + script: + type: string + country: + type: string + variant: + type: string + language: + type: string + unicodeLocaleAttributes: + uniqueItems: true + type: array + items: + type: string + unicodeLocaleKeys: + uniqueItems: true + type: array + items: + type: string + displayLanguage: + type: string + displayScript: + type: string + displayCountry: + type: string + displayVariant: + type: string + displayName: + type: string + extensionKeys: + uniqueItems: true + type: array + items: + type: string + iso3Language: + type: string + iso3Country: + type: string + memberships: + type: array + items: + $ref: '#/components/schemas/GroupMember' + registrations: + type: array + items: + $ref: '#/components/schemas/UserRegistration' + active: + type: boolean + birthDate: + type: string + format: date + cleanSpeakId: + type: string + format: uuid + data: + type: object + additionalProperties: + type: object + email: + type: string + expiry: + type: string + format: date-time + firstName: + type: string + fullName: + type: string + imageUrl: + type: string + format: uri + insertInstant: + type: string + format: date-time + lastLoginInstant: + type: string + format: date-time + lastName: + type: string + middleName: + type: string + mobilePhone: + type: string + parentEmail: + type: string + tenantId: + type: string + format: uuid + timezone: + type: object + properties: + id: + type: string + rules: + type: object + properties: + transitions: + type: array + items: + type: object + properties: + offsetBefore: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + offsetAfter: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + dateTimeBefore: + type: string + format: date-time + duration: + type: object + properties: + seconds: + type: integer + format: int64 + units: + type: array + items: + type: object + properties: + dateBased: + type: boolean + timeBased: + type: boolean + durationEstimated: + type: boolean + negative: + type: boolean + zero: + type: boolean + nano: + type: integer + format: int32 + instant: + type: string + format: date-time + gap: + type: boolean + overlap: + type: boolean + dateTimeAfter: + type: string + format: date-time + transitionRules: + type: array + items: + type: object + properties: + month: + type: string + enum: + - JANUARY + - FEBRUARY + - MARCH + - APRIL + - MAY + - JUNE + - JULY + - AUGUST + - SEPTEMBER + - OCTOBER + - NOVEMBER + - DECEMBER + timeDefinition: + type: string + enum: + - UTC + - WALL + - STANDARD + standardOffset: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + offsetBefore: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + offsetAfter: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + dayOfMonthIndicator: + type: integer + format: int32 + localTime: + $ref: '#/components/schemas/LocalTime' + midnightEndOfDay: + type: boolean + dayOfWeek: + type: string + enum: + - MONDAY + - TUESDAY + - WEDNESDAY + - THURSDAY + - FRIDAY + - SATURDAY + - SUNDAY + fixedOffset: + type: boolean + twoFactorDelivery: + type: string + enum: + - None + - TextMessage + twoFactorEnabled: + type: boolean + twoFactorSecret: + type: string + username: + type: string + usernameStatus: + type: string + enum: + - ACTIVE + - PENDING + - REJECTED + UserRegistration: + type: object + properties: + data: + type: object + additionalProperties: + type: object + preferredLanguages: + type: array + items: + type: object + properties: + script: + type: string + country: + type: string + variant: + type: string + language: + type: string + unicodeLocaleAttributes: + uniqueItems: true + type: array + items: + type: string + unicodeLocaleKeys: + uniqueItems: true + type: array + items: + type: string + displayLanguage: + type: string + displayScript: + type: string + displayCountry: + type: string + displayVariant: + type: string + displayName: + type: string + extensionKeys: + uniqueItems: true + type: array + items: + type: string + iso3Language: + type: string + iso3Country: + type: string + tokens: + type: object + additionalProperties: + type: string + applicationId: + type: string + format: uuid + authenticationToken: + type: string + cleanSpeakId: + type: string + format: uuid + id: + type: string + format: uuid + insertInstant: + type: string + format: date-time + lastLoginInstant: + type: string + format: date-time + roles: + uniqueItems: true + type: array + items: + type: string + timezone: + type: object + properties: + id: + type: string + rules: + type: object + properties: + transitions: + type: array + items: + type: object + properties: + offsetBefore: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + offsetAfter: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + dateTimeBefore: + type: string + format: date-time + duration: + type: object + properties: + seconds: + type: integer + format: int64 + units: + type: array + items: + type: object + properties: + dateBased: + type: boolean + timeBased: + type: boolean + durationEstimated: + type: boolean + negative: + type: boolean + zero: + type: boolean + nano: + type: integer + format: int32 + instant: + type: string + format: date-time + gap: + type: boolean + overlap: + type: boolean + dateTimeAfter: + type: string + format: date-time + transitionRules: + type: array + items: + type: object + properties: + month: + type: string + enum: + - JANUARY + - FEBRUARY + - MARCH + - APRIL + - MAY + - JUNE + - JULY + - AUGUST + - SEPTEMBER + - OCTOBER + - NOVEMBER + - DECEMBER + timeDefinition: + type: string + enum: + - UTC + - WALL + - STANDARD + standardOffset: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + offsetBefore: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + offsetAfter: + type: object + properties: + totalSeconds: + type: integer + format: int32 + id: + type: string + dayOfMonthIndicator: + type: integer + format: int32 + localTime: + $ref: '#/components/schemas/LocalTime' + midnightEndOfDay: + type: boolean + dayOfWeek: + type: string + enum: + - MONDAY + - TUESDAY + - WEDNESDAY + - THURSDAY + - FRIDAY + - SATURDAY + - SUNDAY + fixedOffset: + type: boolean + username: + type: string + usernameStatus: + type: string + enum: + - ACTIVE + - PENDING + - REJECTED + verified: + type: boolean + DeliveryDetails: + type: object + properties: + phoneNumberStatus: + type: array + xml: + name: "no" + items: + $ref: '#/components/schemas/PhoneNumberStatus' + PhoneNumberStatus: + type: object + properties: + mobileNumber: + type: string + xml: + name: mobNo + attribute: true + status: + type: string + TrackDetails: + type: object + properties: + messageId: + type: string + xml: + name: msgid + deliveredSMSCount: + type: string + xml: + name: delvSMSCount + failedSMSCount: + type: string + xml: + name: fldSMSCount + submittedSMSCount: + type: string + xml: + name: subSMSCount + undelivered: + type: string + xml: + name: undelv + delivered: + $ref: '#/components/schemas/DeliveryDetails' + submitted: + $ref: '#/components/schemas/DeliveryDetails' + failed: + $ref: '#/components/schemas/DeliveryDetails' + xml: + name: dept diff --git a/pom.xml b/pom.xml index 58f0bca..1ea5e65 100644 --- a/pom.xml +++ b/pom.xml @@ -99,14 +99,9 @@ compile - io.springfox - springfox-swagger2 - 2.7.0 - - - io.springfox - springfox-swagger-ui - 2.7.0 + 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 fa4d700..4706c8e 100644 --- a/src/main/java/com/uci/inbound/AppConfigInbound.java +++ b/src/main/java/com/uci/inbound/AppConfigInbound.java @@ -5,24 +5,10 @@ import com.uci.dao.service.HealthService; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; - @Configuration public class AppConfigInbound { @Bean public HealthService healthService() { return new HealthService(); } - - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build(); - } } diff --git a/src/main/java/com/uci/inbound/Inbound.java b/src/main/java/com/uci/inbound/Inbound.java index 6b50464..28792d9 100644 --- a/src/main/java/com/uci/inbound/Inbound.java +++ b/src/main/java/com/uci/inbound/Inbound.java @@ -12,8 +12,6 @@ import com.uci.dao.service.HealthService; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - @EnableKafka @EnableReactiveCassandraRepositories("com.uci.dao") @EntityScan("com.uci.dao") @@ -25,7 +23,6 @@ }) @SpringBootApplication @ComponentScan(basePackages = {"com.uci.inbound", "com.uci.adapter", "com.uci.utils"}) -@EnableSwagger2 public class Inbound { public static void main(String[] args) { SpringApplication.run(Inbound.class, args); diff --git a/src/main/java/com/uci/inbound/health/ServiceStatusController.java b/src/main/java/com/uci/inbound/health/ServiceStatusController.java index 90304b8..9a80d13 100644 --- a/src/main/java/com/uci/inbound/health/ServiceStatusController.java +++ b/src/main/java/com/uci/inbound/health/ServiceStatusController.java @@ -59,13 +59,6 @@ public ResponseEntity campaignUrlStatusCheck() throws JsonProcessingEx return ResponseEntity.ok(jsonNode); } - @RequestMapping(value = "/health/test", method = RequestMethod.POST, produces = { "application/json", "text/json" }) - public ResponseEntity testStatusCheck() throws JsonProcessingException, IOException { - JsonNode jsonNode = getResponseJsonNode(); - - return ResponseEntity.ok(jsonNode); - } - /** * Returns json node for service response * From 24459469f3fa09d9b31489e56ba33ea182bc713d Mon Sep 17 00:00:00 2001 From: Surabhi Date: Fri, 3 Sep 2021 15:18:49 +0530 Subject: [PATCH 3/4] Api documentation --- .../com/uci/inbound/AppConfigInbound.java | 21 +++- .../examples/ComponentHealthApiExample.java | 8 ++ .../response/examples/HealthApiExample.java | 22 +++++ .../examples/SystemHealthApiExample.java | 7 ++ .../ComponentHealthApiResultParameter.java | 10 ++ .../params/HealthApiChecksParameter.java | 11 +++ .../params/HealthApiParamsParameter.java | 20 ++++ .../params/HealthApiResultParameter.java | 12 +++ .../com/uci/inbound/cdac/CDACConverter.java | 6 +- .../diksha/web/DikshaWebController.java | 55 ++++++----- .../uci/inbound/health/HealthController.java | 48 +++++---- .../health/ServiceStatusController.java | 97 +++++++++++-------- .../com/uci/inbound/incoming/Campaign.java | 22 ++++- .../uci/inbound/incoming/GupShupOptIn.java | 4 + .../incoming/GupShupWhatsappConverter.java | 53 +++++++++- .../com/uci/inbound/incoming/InternalBot.java | 4 + .../netcore/NetcoreWhatsappConverter.java | 95 ++++++++++++------ src/main/resources/application.properties | 3 + 18 files changed, 376 insertions(+), 122 deletions(-) create mode 100644 src/main/java/com/uci/inbound/api/response/examples/ComponentHealthApiExample.java create mode 100644 src/main/java/com/uci/inbound/api/response/examples/HealthApiExample.java create mode 100644 src/main/java/com/uci/inbound/api/response/examples/SystemHealthApiExample.java create mode 100644 src/main/java/com/uci/inbound/api/response/examples/params/ComponentHealthApiResultParameter.java create mode 100644 src/main/java/com/uci/inbound/api/response/examples/params/HealthApiChecksParameter.java create mode 100644 src/main/java/com/uci/inbound/api/response/examples/params/HealthApiParamsParameter.java create mode 100644 src/main/java/com/uci/inbound/api/response/examples/params/HealthApiResultParameter.java 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 + From ffe867358c9e08d71a4ef16ddfd71ac3ffb55553 Mon Sep 17 00:00:00 2001 From: Surabhi Date: Fri, 3 Sep 2021 15:19:12 +0530 Subject: [PATCH 4/4] - --- api-docs/api-docs.yaml | 992 +++++++---------------------------------- 1 file changed, 153 insertions(+), 839 deletions(-) diff --git a/api-docs/api-docs.yaml b/api-docs/api-docs.yaml index 4ddc921..427d6c3 100644 --- a/api-docs/api-docs.yaml +++ b/api-docs/api-docs.yaml @@ -1,43 +1,54 @@ openapi: 3.0.1 info: - title: OpenAPI definition - version: v0 + 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: - /whatsapp/opt-in: - post: - tags: - - gup-shup-opt-in - operationId: gupShupWhatsApp - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/GSWhatsAppMessage' - required: true - responses: - "200": - description: OK /netcore/whatsApp: post: tags: - - netcore-whatsapp-converter + - 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 + description: OK! /gupshup/whatsApp: post: tags: - - gup-shup-whatsapp-converter + - 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: @@ -46,201 +57,73 @@ paths: $ref: '#/components/schemas/GSWhatsAppMessage' responses: "200": - description: OK - /diksha/web: - post: - tags: - - diksha-web-controller - operationId: dikshaWeb - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/DikshaWebMessageFormat' - required: true - responses: - "200": - description: OK - /cdac/sms/single/: - post: - tags: - - cdac-converter - operationId: cdacSingle - requestBody: - content: - application/x-www-form-urlencoded: - schema: - $ref: '#/components/schemas/CommonMessage' - responses: - "200": - description: OK - /cdac/sms/bulk/: - post: - tags: - - cdac-converter - operationId: cdacBulk - requestBody: - content: - application/x-www-form-urlencoded: - schema: - $ref: '#/components/schemas/CommonMessage' - responses: - "200": - description: OK + description: OK! /service/health/kafka: get: tags: - - service-status-controller + - Services Health Api + summary: Get Kafka Health + description: This API is used to get kafka health status operationId: kafkaStatusCheck responses: "200": - description: OK + description: OK! content: application/json: schema: - $ref: '#/components/schemas/JsonNode' - text/json: - schema: - $ref: '#/components/schemas/JsonNode' + $ref: '#/components/schemas/ComponentHealthApiExample' /service/health/cassandra: get: tags: - - service-status-controller + - Services Health Api + summary: Get Cassandra Health + description: This API is used to get cassandra health status operationId: cassandraStatusCheck responses: "200": - description: OK + description: OK! content: application/json: schema: - $ref: '#/components/schemas/JsonNode' - text/json: - schema: - $ref: '#/components/schemas/JsonNode' + $ref: '#/components/schemas/ComponentHealthApiExample' /service/health/campaign: get: tags: - - service-status-controller + - Services Health Api + summary: Get Campaign Health + description: This API is used to get campaign health status operationId: campaignUrlStatusCheck responses: "200": - description: OK + description: OK! content: application/json: schema: - $ref: '#/components/schemas/JsonNode' - text/json: - schema: - $ref: '#/components/schemas/JsonNode' - /internalBot/reject-leave: - get: - tags: - - internal-bot - operationId: rejectLeave - parameters: - - name: userEmail - in: query - required: false - schema: - type: string - - name: workingDays - in: query - required: false - schema: - type: integer - format: int32 - responses: - "200": - description: OK - content: - '*/*': - schema: - $ref: '#/components/schemas/User' - /internalBot/delete-leave: - get: - tags: - - internal-bot - operationId: deleteLeave - parameters: - - name: userEmail - in: query - required: false - schema: - type: string - - name: workingDays - in: query - required: false - schema: - type: integer - format: int32 - responses: - "200": - description: OK - content: - '*/*': - schema: - $ref: '#/components/schemas/User' - /internalBot/approve-leave: - get: - tags: - - internal-bot - operationId: approveLeave - parameters: - - name: userEmail - in: query - required: false - schema: - type: string - - name: workingDays - in: query - required: false - schema: - type: integer - format: int32 - responses: - "200": - description: OK - content: - '*/*': - schema: - $ref: '#/components/schemas/User' + $ref: '#/components/schemas/ComponentHealthApiExample' /health: get: tags: - - health-controller + - 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 + description: OK! content: application/json: schema: - $ref: '#/components/schemas/JsonNode' - text/json: - schema: - $ref: '#/components/schemas/JsonNode' - /campaign/status/cdac/bulk: - get: - tags: - - campaign - operationId: getCampaignStatus - parameters: - - name: campaignId - in: query - required: true - schema: - type: string - responses: - "200": - description: OK - content: - '*/*': - schema: - $ref: '#/components/schemas/TrackDetails' + $ref: '#/components/schemas/SystemHealthApiExample' /campaign/start: get: tags: - - campaign + - 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 @@ -254,7 +137,9 @@ paths: /campaign/resume: get: tags: - - campaign + - Campaign Apis + summary: Resume Campaign + description: This API is used to start campaign kafka topic. operationId: resumeCampaign parameters: - name: campaignId @@ -268,7 +153,9 @@ paths: /campaign/pause: get: tags: - - campaign + - Campaign Apis + summary: Pause Campaign + description: This API is used to pause the campaign kafka topic. operationId: pauseCampaign parameters: - name: campaignId @@ -281,58 +168,6 @@ paths: description: OK components: schemas: - 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 MessageContext: type: object properties: @@ -411,657 +246,136 @@ components: properties: text: type: string - DikshaWebMessageFormat: - type: object - properties: - messages: - type: array - items: - $ref: '#/components/schemas/SunbirdWebMessage' - SunbirdWebMessage: - type: object - properties: - messageId: - type: string - text: - type: string - userId: - type: string - appId: - type: string - channel: - type: string - from: - type: string - context: - type: object - additionalProperties: - type: object - CommonMessage: - type: object - JsonNode: - type: object - properties: - number: - type: boolean - bigInteger: - type: boolean - valueNode: - type: boolean - containerNode: - type: boolean - missingNode: - type: boolean - object: - type: boolean - pojo: - type: boolean - integralNumber: - type: boolean - floatingPointNumber: - type: boolean - short: - type: boolean - int: - type: boolean - long: - type: boolean - double: - type: boolean - bigDecimal: - type: boolean - textual: - type: boolean - boolean: - type: boolean - binary: - type: boolean - float: - type: boolean - nodeType: - type: string - enum: - - ARRAY - - BINARY - - BOOLEAN - - MISSING - - "NULL" - - NUMBER - - OBJECT - - POJO - - STRING - array: - type: boolean - empty: - type: boolean - null: - type: boolean - GroupMember: + GSWhatsAppMessage: type: object properties: - data: - type: object - additionalProperties: - type: object - groupId: + waNumber: type: string - format: uuid - id: + mobile: type: string - format: uuid - insertInstant: + replyId: type: string - format: date-time - userId: + messageId: type: string - format: uuid - LocalTime: - type: object - properties: - hour: - type: integer - format: int32 - minute: - type: integer - format: int32 - second: - type: integer - format: int32 - nano: + timestamp: type: integer - format: int32 - User: - type: object - properties: - encryptionScheme: + format: int64 + name: type: string - factor: + version: type: integer format: int32 - id: - type: string - format: uuid - password: - type: string - passwordChangeRequired: - type: boolean - passwordLastUpdateInstant: - type: string - format: date-time - salt: - type: string - verified: - type: boolean - preferredLanguages: - type: array - items: - type: object - properties: - script: - type: string - country: - type: string - variant: - type: string - language: - type: string - unicodeLocaleAttributes: - uniqueItems: true - type: array - items: - type: string - unicodeLocaleKeys: - uniqueItems: true - type: array - items: - type: string - displayLanguage: - type: string - displayScript: - type: string - displayCountry: - type: string - displayVariant: - type: string - displayName: - type: string - extensionKeys: - uniqueItems: true - type: array - items: - type: string - iso3Language: - type: string - iso3Country: - type: string - memberships: - type: array - items: - $ref: '#/components/schemas/GroupMember' - registrations: - type: array - items: - $ref: '#/components/schemas/UserRegistration' - active: - type: boolean - birthDate: - type: string - format: date - cleanSpeakId: + type: type: string - format: uuid - data: - type: object - additionalProperties: - type: object - email: + text: type: string - expiry: + 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 - format: date-time - firstName: + response: type: string - fullName: + extra: type: string - imageUrl: + app: type: string - format: uri - insertInstant: + WAInboundFile: + type: object + properties: + mime_type: type: string - format: date-time - lastLoginInstant: + signature: type: string - format: date-time - lastName: + url: type: string - middleName: + caption: type: string - mobilePhone: + ComponentHealthApiExample: + type: object + properties: + id: type: string - parentEmail: + example: api.content.health + ver: type: string - tenantId: + example: "3.0" + ts: type: string - format: uuid - timezone: - type: object - properties: - id: - type: string - rules: - type: object - properties: - transitions: - type: array - items: - type: object - properties: - offsetBefore: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - offsetAfter: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - dateTimeBefore: - type: string - format: date-time - duration: - type: object - properties: - seconds: - type: integer - format: int64 - units: - type: array - items: - type: object - properties: - dateBased: - type: boolean - timeBased: - type: boolean - durationEstimated: - type: boolean - negative: - type: boolean - zero: - type: boolean - nano: - type: integer - format: int32 - instant: - type: string - format: date-time - gap: - type: boolean - overlap: - type: boolean - dateTimeAfter: - type: string - format: date-time - transitionRules: - type: array - items: - type: object - properties: - month: - type: string - enum: - - JANUARY - - FEBRUARY - - MARCH - - APRIL - - MAY - - JUNE - - JULY - - AUGUST - - SEPTEMBER - - OCTOBER - - NOVEMBER - - DECEMBER - timeDefinition: - type: string - enum: - - UTC - - WALL - - STANDARD - standardOffset: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - offsetBefore: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - offsetAfter: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - dayOfMonthIndicator: - type: integer - format: int32 - localTime: - $ref: '#/components/schemas/LocalTime' - midnightEndOfDay: - type: boolean - dayOfWeek: - type: string - enum: - - MONDAY - - TUESDAY - - WEDNESDAY - - THURSDAY - - FRIDAY - - SATURDAY - - SUNDAY - fixedOffset: - type: boolean - twoFactorDelivery: + example: 2021-09-01T11:14:50Z + params: + $ref: '#/components/schemas/HealthApiParamsParameter' + responseCode: type: string - enum: - - None - - TextMessage - twoFactorEnabled: + example: OK + result: + $ref: '#/components/schemas/ComponentHealthApiResultParameter' + ComponentHealthApiResultParameter: + type: object + properties: + healthy: type: boolean - twoFactorSecret: - type: string - username: - type: string - usernameStatus: - type: string - enum: - - ACTIVE - - PENDING - - REJECTED - UserRegistration: + example: true + HealthApiParamsParameter: type: object properties: - data: - type: object - additionalProperties: - type: object - preferredLanguages: - type: array - items: - type: object - properties: - script: - type: string - country: - type: string - variant: - type: string - language: - type: string - unicodeLocaleAttributes: - uniqueItems: true - type: array - items: - type: string - unicodeLocaleKeys: - uniqueItems: true - type: array - items: - type: string - displayLanguage: - type: string - displayScript: - type: string - displayCountry: - type: string - displayVariant: - type: string - displayName: - type: string - extensionKeys: - uniqueItems: true - type: array - items: - type: string - iso3Language: - type: string - iso3Country: - type: string - tokens: - type: object - additionalProperties: - type: string - applicationId: + resmsgid: type: string - format: uuid - authenticationToken: + example: 859fee0c-94d6-4a0d-b786-2025d763b78a + msgid: type: string - cleanSpeakId: + example: "null" + err: type: string - format: uuid - id: - type: string - format: uuid - insertInstant: - type: string - format: date-time - lastLoginInstant: + example: "null" + status: type: string - format: date-time - roles: - uniqueItems: true - type: array - items: - type: string - timezone: - type: object - properties: - id: - type: string - rules: - type: object - properties: - transitions: - type: array - items: - type: object - properties: - offsetBefore: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - offsetAfter: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - dateTimeBefore: - type: string - format: date-time - duration: - type: object - properties: - seconds: - type: integer - format: int64 - units: - type: array - items: - type: object - properties: - dateBased: - type: boolean - timeBased: - type: boolean - durationEstimated: - type: boolean - negative: - type: boolean - zero: - type: boolean - nano: - type: integer - format: int32 - instant: - type: string - format: date-time - gap: - type: boolean - overlap: - type: boolean - dateTimeAfter: - type: string - format: date-time - transitionRules: - type: array - items: - type: object - properties: - month: - type: string - enum: - - JANUARY - - FEBRUARY - - MARCH - - APRIL - - MAY - - JUNE - - JULY - - AUGUST - - SEPTEMBER - - OCTOBER - - NOVEMBER - - DECEMBER - timeDefinition: - type: string - enum: - - UTC - - WALL - - STANDARD - standardOffset: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - offsetBefore: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - offsetAfter: - type: object - properties: - totalSeconds: - type: integer - format: int32 - id: - type: string - dayOfMonthIndicator: - type: integer - format: int32 - localTime: - $ref: '#/components/schemas/LocalTime' - midnightEndOfDay: - type: boolean - dayOfWeek: - type: string - enum: - - MONDAY - - TUESDAY - - WEDNESDAY - - THURSDAY - - FRIDAY - - SATURDAY - - SUNDAY - fixedOffset: - type: boolean - username: + example: Successful + errmsg: type: string - usernameStatus: + example: "null" + HealthApiChecksParameter: + type: object + properties: + name: type: string - enum: - - ACTIVE - - PENDING - - REJECTED - verified: + example: Cassandra + healthy: type: boolean - DeliveryDetails: + example: true + HealthApiResultParameter: type: object properties: - phoneNumberStatus: + checks: type: array - xml: - name: "no" items: - $ref: '#/components/schemas/PhoneNumberStatus' - PhoneNumberStatus: - type: object - properties: - mobileNumber: - type: string - xml: - name: mobNo - attribute: true - status: - type: string - TrackDetails: + $ref: '#/components/schemas/HealthApiChecksParameter' + healthy: + type: boolean + example: true + SystemHealthApiExample: type: object properties: - messageId: - type: string - xml: - name: msgid - deliveredSMSCount: + id: type: string - xml: - name: delvSMSCount - failedSMSCount: + example: api.content.health + ver: type: string - xml: - name: fldSMSCount - submittedSMSCount: + example: "3.0" + ts: type: string - xml: - name: subSMSCount - undelivered: + example: 2021-09-01T11:14:50Z + params: + $ref: '#/components/schemas/HealthApiParamsParameter' + responseCode: type: string - xml: - name: undelv - delivered: - $ref: '#/components/schemas/DeliveryDetails' - submitted: - $ref: '#/components/schemas/DeliveryDetails' - failed: - $ref: '#/components/schemas/DeliveryDetails' - xml: - name: dept + example: OK + result: + $ref: '#/components/schemas/HealthApiResultParameter'