Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dheeraj | Synce private gateway repository with the public repository #174

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]
103 changes: 103 additions & 0 deletions pipelines/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -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}"
}
}
}
}
}
}
}
50 changes: 49 additions & 1 deletion src/main/java/in/projecteka/gateway/GatewayConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -98,6 +99,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;

Expand Down Expand Up @@ -907,12 +910,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;
}
Expand Down Expand Up @@ -1421,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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();

Expand Down
10 changes: 8 additions & 2 deletions src/main/java/in/projecteka/gateway/SecurityConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -57,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;
Expand Down Expand Up @@ -117,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[]{
Expand Down Expand Up @@ -147,11 +151,13 @@ 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,
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 = {
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
3 changes: 3 additions & 0 deletions src/main/java/in/projecteka/gateway/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,16 @@ 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";
public static final String HFR_BRIDGES_BRIDGE_ID = "/bridges/{bridgeId}";
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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ public class RabbitmqOptions {
private final int channelPoolMaxCacheSize;
private final String username;
private final String password;
private final boolean useSSL;
}
Original file line number Diff line number Diff line change
@@ -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));
}
}
Loading