From 5855133b96506e1c199fc75d5cddc317b6bd8de9 Mon Sep 17 00:00:00 2001
From: Nakka Leela Prasanth <prasanthleela299@gmail.com>
Date: Mon, 19 Apr 2021 16:44:20 +0530
Subject: [PATCH 1/8] #Leela | Adds Jenkinsfile for Jenkins integration

---
 pipelines/Jenkinsfile | 103 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 pipelines/Jenkinsfile

diff --git a/pipelines/Jenkinsfile b/pipelines/Jenkinsfile
new file mode 100644
index 0000000..f50dc10
--- /dev/null
+++ b/pipelines/Jenkinsfile
@@ -0,0 +1,103 @@
+pipeline {
+    agent {
+        kubernetes {
+             yaml """
+                apiVersion: v1
+                kind: Pod
+                spec:
+                  containers:
+                    - name: docker
+                      image: registry.nhadclmgm.tcl.com:5000/docker:dind
+                      securityContext:
+                        privileged: true
+                      resources:
+                        limits:
+                          cpu: '300m'
+                          memory: '500Mi'
+                        requests:
+                          cpu: '100m'
+                          memory: '300Mi'
+                    - name: java11
+                      image: adoptopenjdk/maven-openjdk11
+                      command:
+                        - sleep
+                      args:
+                        - infinity
+                      resources:
+                        limits:
+                          cpu: '1000m'
+                          memory: '2000Mi'
+                        requests:
+                          cpu: '400m'
+                          memory: '1200Mi'
+                        """
+            defaultContainer 'java11'
+        }
+    }
+
+    options {
+        skipDefaultCheckout()
+    }
+
+    environment {
+        def IMAGE_NAME= 'gateway'
+        def DOCKER_FILE_DIRECTORY = "Dockerfile"
+        def DOCKER_HARBOR_URL = "harbor.nhadclmgm.tatacommunications.com"
+        def HARBOR_REPO = "gateway"
+        def IMAGE_TAG = "latest"
+        def IMAGE_REPO = "${DOCKER_HARBOR_URL + '/' + HARBOR_REPO + '/'+ IMAGE_NAME}"
+        def IMAGE = "${IMAGE_REPO + ':' + IMAGE_TAG}"
+    }
+
+    stages {
+        stage('Get latest version of code') {
+            steps {
+                script{
+                   def scmVar =  checkout([
+                        $class: 'GitSCM', branches: scm.branches,
+                        extensions: scm.extensions + [[$class: 'CleanBeforeCheckout', deleteUntrackedNestedRepositories: true]],
+                        userRemoteConfigs: scm.userRemoteConfigs])
+                   sh "echo ${scmVar.GIT_COMMIT} | head -c7 >> commit_sha.txt"
+                   if(env.TAG_NAME){
+                       sh "echo $TAG_NAME > commit_sha.txt"
+                       sh "cat commit_sha.txt"
+                   }
+                }
+            }
+        }
+
+        stage("Run tests and Build"){
+            steps{
+                container('java11'){
+                    sh "./gradlew clean test"
+                    sh "./gradlew clean bootJar"
+                }
+            }
+        }
+
+        stage ('Build Docker Image and Push to NHA Harbor') {
+             when {
+                anyOf{
+                   branch 'master'
+                   buildingTag()
+                }
+             }
+             steps {
+                 withCredentials([
+                        usernamePassword(credentialsId: 'NDHM_HARBOR_HUB_PASSWORD_GATEWAY', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]
+                 ){
+                    container('docker'){
+                        script{
+                            def COMMIT_SHA=readFile(file: 'commit_sha.txt')
+                            dockerImage = docker.build IMAGE
+                            sh "docker login ${DOCKER_HARBOR_URL} -u ${USERNAME} -p ${PASSWORD}"
+                            sh "docker push ${IMAGE}"
+                            sh "docker tag ${IMAGE_REPO} ${IMAGE_REPO}:${COMMIT_SHA}"
+                            sh "docker push ${IMAGE_REPO}:${COMMIT_SHA}"
+                        }
+                    }
+                 }
+             }
+        }
+    }
+}
\ No newline at end of file

From e0ce70c22ad56c9dcad266943ccb410c1f1c919b Mon Sep 17 00:00:00 2001
From: "richa.singh" <richa.singh@akalinfosys.com>
Date: Thu, 22 Apr 2021 15:40:34 +0530
Subject: [PATCH 2/8] Richa | API to get govt programs as HIPs

---
 .../gateway/SecurityConfiguration.java        |  4 ++-
 .../projecteka/gateway/common/Constants.java  |  1 +
 .../gateway/registry/RegistryController.java  |  7 +++++
 .../gateway/registry/RegistryRepository.java  | 30 +++++++++++++++++++
 .../gateway/registry/RegistryService.java     |  5 ++++
 .../gateway/registry/model/GovtProgram.java   | 13 ++++++++
 6 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/in/projecteka/gateway/registry/model/GovtProgram.java

diff --git a/src/main/java/in/projecteka/gateway/SecurityConfiguration.java b/src/main/java/in/projecteka/gateway/SecurityConfiguration.java
index c5fa092..5993f55 100644
--- a/src/main/java/in/projecteka/gateway/SecurityConfiguration.java
+++ b/src/main/java/in/projecteka/gateway/SecurityConfiguration.java
@@ -33,6 +33,7 @@
 import static in.projecteka.gateway.common.Constants.HFR_BRIDGES_BRIDGE_ID_SERVICES;
 import static in.projecteka.gateway.common.Constants.INTERNAL_BRIDGES;
 import static in.projecteka.gateway.common.Constants.INTERNAL_BRIDGES_BRIDGE_ID_SERVICES;
+import static in.projecteka.gateway.common.Constants.INTERNAL_PATH_GET_GOVT_PROGRAMS_LIST;
 import static in.projecteka.gateway.common.Constants.INTERNAL_CM;
 import static in.projecteka.gateway.common.Constants.INTERNAL_GET_FACILITY_BY_ID;
 import static in.projecteka.gateway.common.Constants.INTERNAL_SEARCH_FACILITY_BY_NAME;
@@ -151,7 +152,8 @@ public class SecurityConfiguration {
             PATH_SUBSCRIPTION_REQUESTS_NOTIFY,
             INTERNAL_SEARCH_FACILITY_BY_NAME,
             INTERNAL_GET_FACILITY_BY_ID,
-            PATH_PATIENTS_SMS_ON_NOTIFY
+            PATH_PATIENTS_SMS_ON_NOTIFY,
+            INTERNAL_PATH_GET_GOVT_PROGRAMS_LIST
     };
 
     protected static final String[] ALLOW_LIST_APIS = {
diff --git a/src/main/java/in/projecteka/gateway/common/Constants.java b/src/main/java/in/projecteka/gateway/common/Constants.java
index 6328693..6445f66 100644
--- a/src/main/java/in/projecteka/gateway/common/Constants.java
+++ b/src/main/java/in/projecteka/gateway/common/Constants.java
@@ -93,6 +93,7 @@ public class Constants {
     public static final String HFR_BRIDGES_BRIDGE_ID_SERVICES = "/bridges/{bridgeId}/services";
     public static final String INTERNAL_SEARCH_FACILITY_BY_NAME = CURRENT_VERSION + "/internal/facilities";
     public static final String INTERNAL_GET_FACILITY_BY_ID = CURRENT_VERSION + "/internal/facilities/{serviceId}";
+    public static final String INTERNAL_PATH_GET_GOVT_PROGRAMS_LIST = CURRENT_VERSION + "/internal/govt-programs";
 
     //API to be called on HIP/HIU bridge
     public static final String PATH_BRIDGE_ON_FETCH_AUTH_MODES = CURRENT_VERSION + "/users/auth/on-fetch-modes";
diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryController.java b/src/main/java/in/projecteka/gateway/registry/RegistryController.java
index b40011e..56502f3 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryController.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryController.java
@@ -5,6 +5,7 @@
 import in.projecteka.gateway.registry.model.BridgeServiceRequest;
 import in.projecteka.gateway.registry.model.CMServiceRequest;
 import in.projecteka.gateway.registry.model.FacilityRepresentation;
+import in.projecteka.gateway.registry.model.GovtProgram;
 import in.projecteka.gateway.registry.model.HFRBridgeResponse;
 import in.projecteka.gateway.registry.model.ServiceDetailsResponse;
 import in.projecteka.gateway.registry.model.ServiceProfileResponse;
@@ -28,6 +29,7 @@
 import static in.projecteka.gateway.common.Constants.INTERNAL_BRIDGES_BRIDGE_ID_SERVICES;
 import static in.projecteka.gateway.common.Constants.INTERNAL_CM;
 import static in.projecteka.gateway.common.Constants.INTERNAL_GET_FACILITY_BY_ID;
+import static in.projecteka.gateway.common.Constants.INTERNAL_PATH_GET_GOVT_PROGRAMS_LIST;
 import static in.projecteka.gateway.common.Constants.INTERNAL_SEARCH_FACILITY_BY_NAME;
 import static in.projecteka.gateway.common.Constants.UNSPECIFIED_SERVICE_TYPE;
 
@@ -79,4 +81,9 @@ public Mono<List<FacilityRepresentation>> searchFacilityByName(@RequestParam Str
     public Mono<FacilityRepresentation> searchFacilityByName(@PathVariable String serviceId) {
         return registryService.getFacilityById(serviceId);
     }
+
+    @GetMapping(INTERNAL_PATH_GET_GOVT_PROGRAMS_LIST)
+    public Mono<List<GovtProgram>> fetchGovtPrograms() {
+        return registryService.fetchGovtPrograms();
+    }
 }
diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
index 6062968..dc6eb48 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
@@ -10,6 +10,7 @@
 import in.projecteka.gateway.registry.model.EndpointDetails;
 import in.projecteka.gateway.registry.model.Endpoints;
 import in.projecteka.gateway.registry.model.FacilityRepresentation;
+import in.projecteka.gateway.registry.model.GovtProgram;
 import in.projecteka.gateway.registry.model.HFRBridgeResponse;
 import in.projecteka.gateway.registry.model.ServiceDetailsResponse;
 import in.projecteka.gateway.registry.model.ServiceProfile;
@@ -72,6 +73,7 @@ public class RegistryRepository {
     private static final String SELECT_FACILITIES_BY_NAME = "SELECT service_id, name, is_hip, is_hiu, is_health_locker " +
             "FROM bridge_service WHERE UPPER(name) LIKE $1 AND is_hip = true";
 
+    private static final String SELECT_GOVT_PROGRAMS = "SELECT hip_id, name FROM govt_programs";
     private final PgPool readWriteClient;
     private final PgPool readOnlyClient;
 
@@ -496,4 +498,32 @@ private FacilityRepresentation toFacilityRepresentation(Row row) {
                 .facilityType(serviceTypes)
                 .build();
     }
+
+    public Mono<List<GovtProgram>> fetchGovtPrograms() {
+        return Mono.create(monoSink -> this.readOnlyClient.preparedQuery(SELECT_GOVT_PROGRAMS)
+                .execute(
+                        handler -> {
+                            if (handler.failed()) {
+                                logger.error(handler.cause().getMessage(), handler.cause());
+                                monoSink.error(new DbOperationError("Failed to fetch govt programs from govt_programs"));
+                                return;
+                            }
+                            var iterator = handler.result().iterator();
+                            if (!iterator.hasNext()) {
+                                monoSink.success();
+                                return;
+                            }
+                            RowSet<Row> rowSet = handler.result();
+                            List<GovtProgram> results = new ArrayList<>();
+                            if (rowSet.iterator().hasNext()) {
+                                rowSet.forEach(row -> {
+                                    results.add(GovtProgram.builder()
+                                            .hipId(row.getString("hip_id"))
+                                            .name(row.getString("name"))
+                                            .build());
+                                });
+                            }
+                            monoSink.success(results);
+                        }));
+    }
 }
diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryService.java b/src/main/java/in/projecteka/gateway/registry/RegistryService.java
index 837e5e7..678035a 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryService.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryService.java
@@ -15,6 +15,7 @@
 import in.projecteka.gateway.registry.model.EndpointDetails;
 import in.projecteka.gateway.registry.model.Endpoints;
 import in.projecteka.gateway.registry.model.FacilityRepresentation;
+import in.projecteka.gateway.registry.model.GovtProgram;
 import in.projecteka.gateway.registry.model.HFRBridgeResponse;
 import in.projecteka.gateway.registry.model.ServiceDetailsResponse;
 import in.projecteka.gateway.registry.model.ServiceProfileResponse;
@@ -374,5 +375,9 @@ public Mono<FacilityRepresentation> getFacilityById(String serviceId) {
                             .build();
                 });
     }
+
+    public Mono<List<GovtProgram>> fetchGovtPrograms(){
+        return registryRepository.fetchGovtPrograms();
+    }
 }
 
diff --git a/src/main/java/in/projecteka/gateway/registry/model/GovtProgram.java b/src/main/java/in/projecteka/gateway/registry/model/GovtProgram.java
new file mode 100644
index 0000000..69410c5
--- /dev/null
+++ b/src/main/java/in/projecteka/gateway/registry/model/GovtProgram.java
@@ -0,0 +1,13 @@
+package in.projecteka.gateway.registry.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+
+@AllArgsConstructor
+@Data
+@Builder
+public class GovtProgram {
+    private String hipId;
+    private String name;
+}

From 0ace8a81aa3e405f370e1d6791d923177f4553d9 Mon Sep 17 00:00:00 2001
From: "richa.singh" <richa.singh@akalinfosys.com>
Date: Mon, 26 Apr 2021 15:56:22 +0530
Subject: [PATCH 3/8] Richa | Fetch govt programs api| change responsebody

---
 .../gateway/registry/RegistryController.java  |  2 +-
 .../gateway/registry/RegistryRepository.java  | 31 +++++++------------
 .../gateway/registry/RegistryService.java     |  4 +--
 3 files changed, 14 insertions(+), 23 deletions(-)

diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryController.java b/src/main/java/in/projecteka/gateway/registry/RegistryController.java
index 56502f3..8bc2960 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryController.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryController.java
@@ -83,7 +83,7 @@ public Mono<FacilityRepresentation> searchFacilityByName(@PathVariable String se
     }
 
     @GetMapping(INTERNAL_PATH_GET_GOVT_PROGRAMS_LIST)
-    public Mono<List<GovtProgram>> fetchGovtPrograms() {
+    public Mono<List<FacilityRepresentation>> fetchGovtPrograms() {
         return registryService.fetchGovtPrograms();
     }
 }
diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
index dc6eb48..01b9547 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
@@ -73,7 +73,9 @@ public class RegistryRepository {
     private static final String SELECT_FACILITIES_BY_NAME = "SELECT service_id, name, is_hip, is_hiu, is_health_locker " +
             "FROM bridge_service WHERE UPPER(name) LIKE $1 AND is_hip = true";
 
-    private static final String SELECT_GOVT_PROGRAMS = "SELECT hip_id, name FROM govt_programs";
+    private static final String SELECT_GOVT_PROGRAMS = "SELECT service_id, gp.name as name, is_hip, is_hiu, is_health_locker " +
+            " FROM bridge_service INNER JOIN govt_programs AS gp ON gp.hip_id = service_id" +
+            " WHERE active = true AND is_hip = true";
     private final PgPool readWriteClient;
     private final PgPool readOnlyClient;
 
@@ -499,31 +501,20 @@ private FacilityRepresentation toFacilityRepresentation(Row row) {
                 .build();
     }
 
-    public Mono<List<GovtProgram>> fetchGovtPrograms() {
-        return Mono.create(monoSink -> this.readOnlyClient.preparedQuery(SELECT_GOVT_PROGRAMS)
-                .execute(
-                        handler -> {
+    public Flux<FacilityRepresentation> fetchGovtPrograms() {
+        return Flux.create(fluxSink -> this.readOnlyClient.preparedQuery(SELECT_GOVT_PROGRAMS)
+                .execute(handler -> {
                             if (handler.failed()) {
                                 logger.error(handler.cause().getMessage(), handler.cause());
-                                monoSink.error(new DbOperationError("Failed to fetch govt programs from govt_programs"));
-                                return;
-                            }
-                            var iterator = handler.result().iterator();
-                            if (!iterator.hasNext()) {
-                                monoSink.success();
+                                fluxSink.error(new DbOperationError("Failed to fetch govt programs from govt_programs"));
                                 return;
                             }
                             RowSet<Row> rowSet = handler.result();
-                            List<GovtProgram> results = new ArrayList<>();
-                            if (rowSet.iterator().hasNext()) {
-                                rowSet.forEach(row -> {
-                                    results.add(GovtProgram.builder()
-                                            .hipId(row.getString("hip_id"))
-                                            .name(row.getString("name"))
-                                            .build());
-                                });
+                            for (var row: rowSet) {
+                                fluxSink.next(toFacilityRepresentation(row));
                             }
-                            monoSink.success(results);
+
+                            fluxSink.complete();
                         }));
     }
 }
diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryService.java b/src/main/java/in/projecteka/gateway/registry/RegistryService.java
index 678035a..f63cce3 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryService.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryService.java
@@ -376,8 +376,8 @@ public Mono<FacilityRepresentation> getFacilityById(String serviceId) {
                 });
     }
 
-    public Mono<List<GovtProgram>> fetchGovtPrograms(){
-        return registryRepository.fetchGovtPrograms();
+    public Mono<List<FacilityRepresentation>> fetchGovtPrograms(){
+        return registryRepository.fetchGovtPrograms().collectList();
     }
 }
 

From 92964947dd1c0e654e22346d501f54090079f76a Mon Sep 17 00:00:00 2001
From: "richa.singh" <richa.singh@akalinfosys.com>
Date: Mon, 26 Apr 2021 16:03:38 +0530
Subject: [PATCH 4/8] Richa | Fetch govt programs api| Remove GovtProgram class

---
 .../gateway/registry/RegistryController.java        |  1 -
 .../gateway/registry/RegistryRepository.java        |  3 ---
 .../gateway/registry/RegistryService.java           |  1 -
 .../gateway/registry/model/GovtProgram.java         | 13 -------------
 4 files changed, 18 deletions(-)
 delete mode 100644 src/main/java/in/projecteka/gateway/registry/model/GovtProgram.java

diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryController.java b/src/main/java/in/projecteka/gateway/registry/RegistryController.java
index 8bc2960..3fa69ba 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryController.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryController.java
@@ -5,7 +5,6 @@
 import in.projecteka.gateway.registry.model.BridgeServiceRequest;
 import in.projecteka.gateway.registry.model.CMServiceRequest;
 import in.projecteka.gateway.registry.model.FacilityRepresentation;
-import in.projecteka.gateway.registry.model.GovtProgram;
 import in.projecteka.gateway.registry.model.HFRBridgeResponse;
 import in.projecteka.gateway.registry.model.ServiceDetailsResponse;
 import in.projecteka.gateway.registry.model.ServiceProfileResponse;
diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
index 01b9547..bd4f30a 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
@@ -1,6 +1,5 @@
 package in.projecteka.gateway.registry;
 
-import in.projecteka.gateway.clients.ClientError;
 import in.projecteka.gateway.common.DbOperationError;
 import in.projecteka.gateway.registry.model.Bridge;
 import in.projecteka.gateway.registry.model.BridgeRegistryRequest;
@@ -10,7 +9,6 @@
 import in.projecteka.gateway.registry.model.EndpointDetails;
 import in.projecteka.gateway.registry.model.Endpoints;
 import in.projecteka.gateway.registry.model.FacilityRepresentation;
-import in.projecteka.gateway.registry.model.GovtProgram;
 import in.projecteka.gateway.registry.model.HFRBridgeResponse;
 import in.projecteka.gateway.registry.model.ServiceDetailsResponse;
 import in.projecteka.gateway.registry.model.ServiceProfile;
@@ -30,7 +28,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Objects;
 
 import static in.projecteka.gateway.common.Serializer.from;
 import static in.projecteka.gateway.common.Serializer.to;
diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryService.java b/src/main/java/in/projecteka/gateway/registry/RegistryService.java
index f63cce3..7807af3 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryService.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryService.java
@@ -15,7 +15,6 @@
 import in.projecteka.gateway.registry.model.EndpointDetails;
 import in.projecteka.gateway.registry.model.Endpoints;
 import in.projecteka.gateway.registry.model.FacilityRepresentation;
-import in.projecteka.gateway.registry.model.GovtProgram;
 import in.projecteka.gateway.registry.model.HFRBridgeResponse;
 import in.projecteka.gateway.registry.model.ServiceDetailsResponse;
 import in.projecteka.gateway.registry.model.ServiceProfileResponse;
diff --git a/src/main/java/in/projecteka/gateway/registry/model/GovtProgram.java b/src/main/java/in/projecteka/gateway/registry/model/GovtProgram.java
deleted file mode 100644
index 69410c5..0000000
--- a/src/main/java/in/projecteka/gateway/registry/model/GovtProgram.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package in.projecteka.gateway.registry.model;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-
-@AllArgsConstructor
-@Data
-@Builder
-public class GovtProgram {
-    private String hipId;
-    private String name;
-}

From 83a99e619de4873eb877cf5ebd2f9a0903cf0176 Mon Sep 17 00:00:00 2001
From: "richa.singh" <richa.singh@akalinfosys.com>
Date: Mon, 26 Apr 2021 16:47:03 +0530
Subject: [PATCH 5/8] Richa | SHubhanshu | Minor log fix

---
 .../java/in/projecteka/gateway/registry/RegistryRepository.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
index bd4f30a..ae57911 100644
--- a/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
+++ b/src/main/java/in/projecteka/gateway/registry/RegistryRepository.java
@@ -503,7 +503,7 @@ public Flux<FacilityRepresentation> fetchGovtPrograms() {
                 .execute(handler -> {
                             if (handler.failed()) {
                                 logger.error(handler.cause().getMessage(), handler.cause());
-                                fluxSink.error(new DbOperationError("Failed to fetch govt programs from govt_programs"));
+                                fluxSink.error(new DbOperationError("Failed to fetch govt programs"));
                                 return;
                             }
                             RowSet<Row> rowSet = handler.result();

From 8f6d570c139d421917a029518e433227fb3739df Mon Sep 17 00:00:00 2001
From: MD Dubey <mddubey409@gmail.com>
Date: Thu, 29 Apr 2021 11:56:08 +0530
Subject: [PATCH 6/8] Dubey | Toggle to disable correlation-ids

---
 Dockerfile                                                      | 2 +-
 .../in/projecteka/gateway/MdcContextLifterConfiguration.java    | 2 ++
 src/main/resources/application.yaml                             | 1 +
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/Dockerfile b/Dockerfile
index 6a02f4b..b38cea0 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,4 +2,4 @@ FROM adoptopenjdk/openjdk11:jre-11.0.8_10-alpine
 VOLUME /tmp
 COPY build/libs/* app.jar
 EXPOSE 8000
-ENTRYPOINT ["java", "-jar", "/app.jar"]
\ No newline at end of file
+ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]
\ No newline at end of file
diff --git a/src/main/java/in/projecteka/gateway/MdcContextLifterConfiguration.java b/src/main/java/in/projecteka/gateway/MdcContextLifterConfiguration.java
index 59d0896..ea6793a 100644
--- a/src/main/java/in/projecteka/gateway/MdcContextLifterConfiguration.java
+++ b/src/main/java/in/projecteka/gateway/MdcContextLifterConfiguration.java
@@ -1,5 +1,6 @@
 package in.projecteka.gateway;
 
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Configuration;
 import reactor.core.publisher.Hooks;
 import reactor.core.publisher.Operators;
@@ -8,6 +9,7 @@
 import javax.annotation.PreDestroy;
 
 @Configuration
+@ConditionalOnProperty(value = "logging.correlation-enabled", havingValue = "true")
 public class MdcContextLifterConfiguration {
     private String MDC_CONTEXT_REACTOR_KEY = in.projecteka.gateway.MdcContextLifterConfiguration.class.getName();
 
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index ea70a68..22ebe06 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -67,3 +67,4 @@ webclient:
 logging:
   level:
     ROOT: ${LOG_LEVEL:INFO}
+  correlation-enabled: ${LOG_CORRELATION_ID:true}

From 7e46a036b7f1805f591097dd86e9b6086d0cc359 Mon Sep 17 00:00:00 2001
From: Dheeraj Pundir <1236dheeraj.ds@gmail.com>
Date: Tue, 11 May 2021 10:43:48 +0530
Subject: [PATCH 7/8] Dheeraj | Add config to use rabbitMQ with SSL

---
 .../java/in/projecteka/gateway/GatewayConfiguration.java | 7 ++++++-
 .../projecteka/gateway/common/heartbeat/Heartbeat.java   | 9 +++++++--
 .../gateway/common/heartbeat/RabbitmqOptions.java        | 1 +
 src/main/resources/application-local.yml                 | 1 +
 src/main/resources/application.yaml                      | 1 +
 5 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/main/java/in/projecteka/gateway/GatewayConfiguration.java b/src/main/java/in/projecteka/gateway/GatewayConfiguration.java
index e7d9743..f0dbbd5 100644
--- a/src/main/java/in/projecteka/gateway/GatewayConfiguration.java
+++ b/src/main/java/in/projecteka/gateway/GatewayConfiguration.java
@@ -98,6 +98,8 @@
 import reactor.rabbitmq.ReceiverOptions;
 import reactor.rabbitmq.SenderOptions;
 
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
 import java.time.Duration;
 import java.util.concurrent.TimeUnit;
 
@@ -907,12 +909,15 @@ public ResponseOrchestrator authConfirmResponseOrchestrator(
     }
 
     @Bean
-    public ConnectionFactory connectionFactory(RabbitmqOptions rabbitmqOptions) {
+    public ConnectionFactory connectionFactory(RabbitmqOptions rabbitmqOptions) throws KeyManagementException, NoSuchAlgorithmException {
         ConnectionFactory connectionFactory = new ConnectionFactory();
         connectionFactory.setHost(rabbitmqOptions.getHost());
         connectionFactory.setPort(rabbitmqOptions.getPort());
         connectionFactory.setUsername(rabbitmqOptions.getUsername());
         connectionFactory.setPassword(rabbitmqOptions.getPassword());
+        if(rabbitmqOptions.isUseSSL()){
+            connectionFactory.useSslProtocol();
+        }
         connectionFactory.useNio();
         return connectionFactory;
     }
diff --git a/src/main/java/in/projecteka/gateway/common/heartbeat/Heartbeat.java b/src/main/java/in/projecteka/gateway/common/heartbeat/Heartbeat.java
index 509b722..8496549 100644
--- a/src/main/java/in/projecteka/gateway/common/heartbeat/Heartbeat.java
+++ b/src/main/java/in/projecteka/gateway/common/heartbeat/Heartbeat.java
@@ -10,6 +10,8 @@
 import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
 import java.util.concurrent.TimeoutException;
 
 import static in.projecteka.gateway.clients.model.Error.of;
@@ -34,17 +36,20 @@ public Mono<HeartbeatResponse> getStatus() {
             return (cacheHealth.isUp() && isRabbitMQUp() && isKeycloakUp())
                    ? just(HeartbeatResponse.builder().timeStamp(now(UTC)).status(UP).build())
                    : just(HeartbeatResponse.builder().timeStamp(now(UTC)).status(DOWN).error(of(SERVICE_DOWN)).build());
-        } catch (IOException | TimeoutException e) {
+        } catch (IOException | TimeoutException | KeyManagementException | NoSuchAlgorithmException e) {
             return just(HeartbeatResponse.builder().timeStamp(now(UTC)).status(DOWN).error(of(SERVICE_DOWN)).build());
         }
     }
 
-    private boolean isRabbitMQUp() throws IOException, TimeoutException {
+    private boolean isRabbitMQUp() throws IOException, TimeoutException, KeyManagementException, NoSuchAlgorithmException {
         var factory = new ConnectionFactory();
         factory.setHost(rabbitmqOptions.getHost());
         factory.setPort(rabbitmqOptions.getPort());
         factory.setUsername(rabbitmqOptions.getUsername());
         factory.setPassword(rabbitmqOptions.getPassword());
+        if(rabbitmqOptions.isUseSSL()){
+            factory.useSslProtocol();
+        }
         try (Connection connection = factory.newConnection()) {
             return connection.isOpen();
         }
diff --git a/src/main/java/in/projecteka/gateway/common/heartbeat/RabbitmqOptions.java b/src/main/java/in/projecteka/gateway/common/heartbeat/RabbitmqOptions.java
index 8fe22af..fb9a36f 100644
--- a/src/main/java/in/projecteka/gateway/common/heartbeat/RabbitmqOptions.java
+++ b/src/main/java/in/projecteka/gateway/common/heartbeat/RabbitmqOptions.java
@@ -15,4 +15,5 @@ public class RabbitmqOptions {
     private final int channelPoolMaxCacheSize;
     private final String username;
     private final String password;
+    private final boolean useSSL;
 }
diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml
index f5f55b8..e816b90 100644
--- a/src/main/resources/application-local.yml
+++ b/src/main/resources/application-local.yml
@@ -6,6 +6,7 @@ spring:
     port: 5672
     username: guest
     password: guest
+    useSSL: false
 identity:
   clientId: gateway
   clientSecret: ${CLIENT_SECRET}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index 22ebe06..ea99a4e 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -42,6 +42,7 @@ spring:
     username: ${RABBITMQ_USERNAME:guest}
     password: ${RABBITMQ_PASSWORD:guest}
     channelPoolMaxCacheSize: ${RABBITMQ_CHANNEL_POOL_SIZE:10}
+    useSSL: ${RABBITMQ_USE_SSL:true}
 identity:
   clientId: ${GATEWAY_CLIENT_ID}
   clientSecret: ${GATEWAY_CLIENT_SECRET}

From a7e0fa1f077cb1064852548f0dc17f285e3fb2de Mon Sep 17 00:00:00 2001
From: Dheeraj Pundir <1236dheeraj.ds@gmail.com>
Date: Fri, 21 May 2021 19:08:54 +0530
Subject: [PATCH 8/8] Dheeraj | Add routes for hip data notification and it's
 acknowledgment

---
 .../gateway/GatewayConfiguration.java         | 43 +++++++++
 .../gateway/SecurityConfiguration.java        |  6 +-
 .../HipDataNotificationServiceClient.java     | 35 +++++++
 .../projecteka/gateway/common/Constants.java  |  2 +
 .../DataNotificationController.java           | 47 +++++++++
 .../DataNotificationControllerTest.java       | 96 +++++++++++++++++++
 6 files changed, 228 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/in/projecteka/gateway/clients/HipDataNotificationServiceClient.java
 create mode 100644 src/main/java/in/projecteka/gateway/data_notification/DataNotificationController.java
 create mode 100644 src/test/java/in/projecteka/gateway/data_notification/DataNotificationControllerTest.java

diff --git a/src/main/java/in/projecteka/gateway/GatewayConfiguration.java b/src/main/java/in/projecteka/gateway/GatewayConfiguration.java
index f0dbbd5..7557506 100644
--- a/src/main/java/in/projecteka/gateway/GatewayConfiguration.java
+++ b/src/main/java/in/projecteka/gateway/GatewayConfiguration.java
@@ -22,6 +22,7 @@
 import in.projecteka.gateway.clients.HealthInfoNotificationServiceClient;
 import in.projecteka.gateway.clients.HipConsentNotifyServiceClient;
 import in.projecteka.gateway.clients.HipDataFlowServiceClient;
+import in.projecteka.gateway.clients.HipDataNotificationServiceClient;
 import in.projecteka.gateway.clients.HipInitLinkServiceClient;
 import in.projecteka.gateway.clients.HiuConsentNotifyServiceClient;
 import in.projecteka.gateway.clients.HiuSubscriptionNotifyServiceClient;
@@ -1426,4 +1427,46 @@ public ResponseOrchestrator patientSMSNotifyResponseOrchestrator(
             DefaultValidatedResponseAction<PatientSMSNotificationClient> patientSMSNotificationResponseAction) {
         return new ResponseOrchestrator(validator, patientSMSNotificationResponseAction);
     }
+
+    @Bean("hipDataNotificationServiceClient")
+    public HipDataNotificationServiceClient hipDataNotificationServiceClient(ServiceOptions serviceOptions,
+                                                                             @Qualifier("customBuilder") WebClient.Builder builder,
+                                                                             CMRegistry cmRegistry,
+                                                                             IdentityService identityService,
+                                                                             BridgeRegistry bridgeRegistry) {
+        return new HipDataNotificationServiceClient(serviceOptions, builder, identityService, cmRegistry, bridgeRegistry);
+    }
+
+    @Bean("hipDataNotificationRequestAction")
+    public DefaultValidatedRequestAction<HipDataNotificationServiceClient> hipDataNotificationRequestAction(
+            HipDataNotificationServiceClient hipDataNotificationServiceClient) {
+        return new DefaultValidatedRequestAction<>(hipDataNotificationServiceClient);
+    }
+
+    @Bean("hipDataNotificationRequestOrchestrator")
+    public RequestOrchestrator<HipDataNotificationServiceClient> hipDataNotificationRequestOrchestrator(
+            @Qualifier("requestIdMappings") CacheAdapter<String, String> requestIdMappings,
+            RedundantRequestValidator redundantRequestValidator,
+            Validator validator,
+            HipDataNotificationServiceClient hipDataNotificationServiceClient,
+            DefaultValidatedRequestAction<HipDataNotificationServiceClient> hipDataNotificationRequestAction) {
+        return new RequestOrchestrator<>(requestIdMappings,
+                redundantRequestValidator,
+                validator,
+                hipDataNotificationServiceClient,
+                hipDataNotificationRequestAction);
+    }
+
+    @Bean("hipDataNotificationResponseAction")
+    public DefaultValidatedResponseAction<HipDataNotificationServiceClient> hipDataNotificationResponseAction(
+            HipDataNotificationServiceClient hipDataNotificationServiceClient) {
+        return new DefaultValidatedResponseAction<>(hipDataNotificationServiceClient);
+    }
+
+    @Bean("hipDataNotificationResponseOrchestrator")
+    public ResponseOrchestrator hipDataNotificationResponseOrchestrator(
+            Validator validator,
+            DefaultValidatedResponseAction<HipDataNotificationServiceClient> hipDataNotificationResponseAction) {
+        return new ResponseOrchestrator(validator, hipDataNotificationResponseAction);
+    }
 }
diff --git a/src/main/java/in/projecteka/gateway/SecurityConfiguration.java b/src/main/java/in/projecteka/gateway/SecurityConfiguration.java
index 5993f55..99ab626 100644
--- a/src/main/java/in/projecteka/gateway/SecurityConfiguration.java
+++ b/src/main/java/in/projecteka/gateway/SecurityConfiguration.java
@@ -58,6 +58,8 @@
 import static in.projecteka.gateway.common.Constants.PATH_HEALTH_INFORMATION_HIP_REQUEST;
 import static in.projecteka.gateway.common.Constants.PATH_HEALTH_INFORMATION_NOTIFY;
 import static in.projecteka.gateway.common.Constants.PATH_HEARTBEAT;
+import static in.projecteka.gateway.common.Constants.PATH_HIP_DATA_NOTIFICATION;
+import static in.projecteka.gateway.common.Constants.PATH_HIP_DATA_NOTIFICATION_ACKNOWLEDGEMENT;
 import static in.projecteka.gateway.common.Constants.PATH_HIU_SUBSCRIPTION_NOTIFY;
 import static in.projecteka.gateway.common.Constants.PATH_HIU_SUBSCRIPTION_ON_NOTIFY;
 import static in.projecteka.gateway.common.Constants.PATH_LINK_CONFIRM;
@@ -118,7 +120,8 @@ public class SecurityConfiguration {
             PATH_HEALTH_INFORMATION_HIP_ON_REQUEST,
             PATH_ADD_CARE_CONTEXTS,
             PATH_PATIENT_ON_SHARE,
-            PATH_PATIENTS_SMS_NOTIFY
+            PATH_PATIENTS_SMS_NOTIFY,
+            PATH_HIP_DATA_NOTIFICATION
     };
 
     protected static final String[] HIU_HIP_APIS = new String[]{
@@ -148,6 +151,7 @@ public class SecurityConfiguration {
             PATH_CONSENT_REQUEST_ON_STATUS,
             PATH_PATIENT_SHARE,
             PATH_ON_FETCH_AUTH_MODES,
+            PATH_HIP_DATA_NOTIFICATION_ACKNOWLEDGEMENT,
             PATH_HIU_SUBSCRIPTION_NOTIFY,
             PATH_SUBSCRIPTION_REQUESTS_NOTIFY,
             INTERNAL_SEARCH_FACILITY_BY_NAME,
diff --git a/src/main/java/in/projecteka/gateway/clients/HipDataNotificationServiceClient.java b/src/main/java/in/projecteka/gateway/clients/HipDataNotificationServiceClient.java
new file mode 100644
index 0000000..541238a
--- /dev/null
+++ b/src/main/java/in/projecteka/gateway/clients/HipDataNotificationServiceClient.java
@@ -0,0 +1,35 @@
+package in.projecteka.gateway.clients;
+
+import in.projecteka.gateway.common.Constants;
+import in.projecteka.gateway.common.IdentityService;
+import in.projecteka.gateway.common.cache.ServiceOptions;
+import in.projecteka.gateway.registry.BridgeRegistry;
+import in.projecteka.gateway.registry.CMRegistry;
+import in.projecteka.gateway.registry.ServiceType;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+
+public class HipDataNotificationServiceClient extends ServiceClient {
+    private final CMRegistry cmRegistry;
+    private final BridgeRegistry bridgeRegistry;
+
+    public HipDataNotificationServiceClient(ServiceOptions serviceOptions,
+                                    WebClient.Builder webClientBuilder,
+                                    IdentityService identityService,
+                                    CMRegistry cmRegistry,
+                                    BridgeRegistry bridgeRegistry) {
+        super(serviceOptions, webClientBuilder, identityService);
+        this.cmRegistry = cmRegistry;
+        this.bridgeRegistry = bridgeRegistry;
+    }
+
+    @Override
+    protected Mono<String> getResponseUrl(String clientId, ServiceType serviceType) {
+        return bridgeRegistry.getHostFor(clientId, serviceType).map(host -> host + Constants.PATH_HIP_DATA_NOTIFICATION_ACKNOWLEDGEMENT);
+    }
+
+    @Override
+    protected Mono<String> getRequestUrl(String clientId, ServiceType serviceType) {
+        return cmRegistry.getHostFor(clientId).map(host -> host + Constants.PATH_HIP_DATA_NOTIFICATION);
+    }
+}
diff --git a/src/main/java/in/projecteka/gateway/common/Constants.java b/src/main/java/in/projecteka/gateway/common/Constants.java
index 6445f66..2e0c804 100644
--- a/src/main/java/in/projecteka/gateway/common/Constants.java
+++ b/src/main/java/in/projecteka/gateway/common/Constants.java
@@ -86,6 +86,8 @@ public class Constants {
     public static final String PATH_HIU_SUBSCRIPTION_ON_NOTIFY = CURRENT_VERSION + "/subscriptions/hiu/on-notify";
     public static final String PATH_PATIENTS_SMS_NOTIFY = CURRENT_VERSION + "/patients/sms/notify";
     public static final String PATH_PATIENTS_SMS_ON_NOTIFY = CURRENT_VERSION + "/patients/sms/on-notify";
+    public static final String PATH_HIP_DATA_NOTIFICATION = CURRENT_VERSION + "/links/context/notify";
+    public static final String PATH_HIP_DATA_NOTIFICATION_ACKNOWLEDGEMENT = CURRENT_VERSION + "/links/context/on-notify";
     public static final String ROUTE_PATH_CM_HIU_SUBSCRIPTION_ON_NOTIFY = CURRENT_VERSION + "/subscriptions/on-notify";
     public static final String GW_PATH_HI_SERVICE_BY_ID = CURRENT_VERSION + "/hi-services/{service-id}";
     public static final String GW_PATH_HI_SERVICES = CURRENT_VERSION + "/hi-services";
diff --git a/src/main/java/in/projecteka/gateway/data_notification/DataNotificationController.java b/src/main/java/in/projecteka/gateway/data_notification/DataNotificationController.java
new file mode 100644
index 0000000..313be46
--- /dev/null
+++ b/src/main/java/in/projecteka/gateway/data_notification/DataNotificationController.java
@@ -0,0 +1,47 @@
+package in.projecteka.gateway.data_notification;
+
+import in.projecteka.gateway.clients.HipDataNotificationServiceClient;
+import in.projecteka.gateway.common.Caller;
+import in.projecteka.gateway.common.RequestOrchestrator;
+import in.projecteka.gateway.common.ResponseOrchestrator;
+import lombok.AllArgsConstructor;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.core.context.ReactiveSecurityContextHolder;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+import static in.projecteka.gateway.common.Constants.API_CALLED;
+import static in.projecteka.gateway.common.Constants.PATH_HIP_DATA_NOTIFICATION;
+import static in.projecteka.gateway.common.Constants.PATH_HIP_DATA_NOTIFICATION_ACKNOWLEDGEMENT;
+import static in.projecteka.gateway.common.Constants.X_CM_ID;
+import static in.projecteka.gateway.common.Constants.X_HIP_ID;
+import static in.projecteka.gateway.common.Constants.bridgeId;
+
+
+@RestController
+@AllArgsConstructor
+public class DataNotificationController {
+    RequestOrchestrator<HipDataNotificationServiceClient> hipDataNotificationRequestOrchestrator;
+    ResponseOrchestrator hipDataNotificationResponseOrchestrator;
+
+    @ResponseStatus(HttpStatus.ACCEPTED)
+    @PostMapping(PATH_HIP_DATA_NOTIFICATION)
+    public Mono<Void> hipDataNotification(HttpEntity<String> requestEntity) {
+        return ReactiveSecurityContextHolder.getContext()
+                .map(securityContext -> (Caller) securityContext.getAuthentication().getPrincipal())
+                .map(Caller::getClientId)
+                .flatMap(clientId -> hipDataNotificationRequestOrchestrator
+                        .handleThis(requestEntity, X_CM_ID, X_HIP_ID, bridgeId(clientId))
+                        .subscriberContext(context -> context.put(API_CALLED, PATH_HIP_DATA_NOTIFICATION)));
+    }
+
+    @ResponseStatus(HttpStatus.ACCEPTED)
+    @PostMapping(PATH_HIP_DATA_NOTIFICATION_ACKNOWLEDGEMENT)
+    public Mono<Void> hipDataNotificationAcknowledgement(HttpEntity<String> requestEntity) {
+        return hipDataNotificationResponseOrchestrator.processResponse(requestEntity, X_HIP_ID)
+                .subscriberContext(context -> context.put(API_CALLED, PATH_HIP_DATA_NOTIFICATION_ACKNOWLEDGEMENT));
+    }
+}
diff --git a/src/test/java/in/projecteka/gateway/data_notification/DataNotificationControllerTest.java b/src/test/java/in/projecteka/gateway/data_notification/DataNotificationControllerTest.java
new file mode 100644
index 0000000..31e233b
--- /dev/null
+++ b/src/test/java/in/projecteka/gateway/data_notification/DataNotificationControllerTest.java
@@ -0,0 +1,96 @@
+package in.projecteka.gateway.data_notification;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import in.projecteka.gateway.clients.HipDataNotificationServiceClient;
+import in.projecteka.gateway.common.Authenticator;
+import in.projecteka.gateway.common.Constants;
+import in.projecteka.gateway.common.RequestOrchestrator;
+import in.projecteka.gateway.common.ResponseOrchestrator;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.reactive.server.WebTestClient;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+import static in.projecteka.gateway.common.Constants.BRIDGE_ID_PREFIX;
+import static in.projecteka.gateway.common.Constants.X_CM_ID;
+import static in.projecteka.gateway.common.Constants.X_HIP_ID;
+import static in.projecteka.gateway.common.Role.CM;
+import static in.projecteka.gateway.common.Role.HIP;
+import static in.projecteka.gateway.testcommon.TestBuilders.caller;
+import static in.projecteka.gateway.testcommon.TestBuilders.string;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+import static org.springframework.http.HttpHeaders.AUTHORIZATION;
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static reactor.core.publisher.Mono.empty;
+import static reactor.core.publisher.Mono.just;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureWebTestClient
+class DataNotificationControllerTest {
+    @MockBean
+    @Qualifier("hipDataNotificationRequestOrchestrator")
+    RequestOrchestrator<HipDataNotificationServiceClient> hipDataNotificationRequestOrchestrator;
+
+    @Autowired
+    WebTestClient webTestClient;
+
+    @MockBean(name = "centralRegistryJWKSet")
+    JWKSet centralRegistryJWKSet;
+
+    @MockBean
+    Authenticator authenticator;
+
+    @Qualifier("hipDataNotificationResponseOrchestrator")
+    @MockBean
+    ResponseOrchestrator hipDataNotificationResponseOrchestrator;
+
+    @Test
+    void shouldFireAndForgetForHipDataNotification() {
+        var token = string();
+        var clientId = string();
+        when(hipDataNotificationRequestOrchestrator
+                .handleThis(any(), eq(X_CM_ID), eq(X_HIP_ID), eq(BRIDGE_ID_PREFIX + clientId)))
+                .thenReturn(empty());
+        when(authenticator.verify(token))
+                .thenReturn(just(caller().clientId(clientId).roles(List.of(HIP)).build()));
+
+        webTestClient
+                .post()
+                .uri(Constants.PATH_HIP_DATA_NOTIFICATION)
+                .header(AUTHORIZATION, token)
+                .contentType(APPLICATION_JSON)
+                .bodyValue("{}")
+                .exchange()
+                .expectStatus()
+                .isAccepted();
+    }
+
+    @Test
+    void shouldFireAndForgetForHipDataNotificationAcknowledgment() {
+        var token = string();
+        when(authenticator.verify(token)).thenReturn(just(caller().roles(List.of(CM)).build()));
+        when(hipDataNotificationResponseOrchestrator.processResponse(any(), eq(X_HIP_ID)))
+                .thenReturn(Mono.empty());
+
+        webTestClient
+                .post()
+                .uri(Constants.PATH_HIP_DATA_NOTIFICATION_ACKNOWLEDGEMENT)
+                .contentType(APPLICATION_JSON)
+                .header(AUTHORIZATION, token)
+                .bodyValue("{}")
+                .exchange()
+                .expectStatus()
+                .isAccepted();
+    }
+}