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

RWA-940 - Register a patient from NIDA #13

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
74 changes: 74 additions & 0 deletions api/src/main/java/org/openmrs/module/imbemr/ImbEmrConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.imbemr;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.PatientIdentifierType;
import org.openmrs.PersonAttributeType;
import org.openmrs.api.PatientService;
import org.openmrs.api.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
* Config used by the IMB EMR module
*/
@Component
public class ImbEmrConfig {

protected Log log = LogFactory.getLog(getClass());

private final PersonService personService;

private final PatientService patientService;

public ImbEmrConfig(@Autowired PatientService patientService,
@Autowired PersonService personService) {
this.patientService = patientService;
this.personService = personService;
}

public PatientIdentifierType getNationalId() {
return getPatientIdentifierTypeByUuid(ImbEmrConstants.NATIONAL_ID_UUID);
}

public PersonAttributeType getTelephoneNumber() {
return getPersonAttributeTypeByUuid(ImbEmrConstants.TELEPHONE_NUMBER_UUID);
}

public PersonAttributeType getMothersName() {
return getPersonAttributeTypeByUuid(ImbEmrConstants.MOTHERS_NAME_UUID);
}

public PersonAttributeType getFathersName() {
return getPersonAttributeTypeByUuid(ImbEmrConstants.FATHERS_NAME_UUID);
}

public PersonAttributeType getEducationLevel() {
return getPersonAttributeTypeByUuid(ImbEmrConstants.EDUCATION_LEVEL_UUID);
}

public PersonAttributeType getProfession() {
return getPersonAttributeTypeByUuid(ImbEmrConstants.PROFESSION_UUID);
}

public PersonAttributeType getReligion() {
return getPersonAttributeTypeByUuid(ImbEmrConstants.RELIGION_UUID);
}

public PatientIdentifierType getPatientIdentifierTypeByUuid(String uuid) {
return patientService.getPatientIdentifierTypeByUuid(uuid);
}

public PersonAttributeType getPersonAttributeTypeByUuid(String uuid) {
return personService.getPersonAttributeTypeByUuid(uuid);
}
}
33 changes: 33 additions & 0 deletions api/src/main/java/org/openmrs/module/imbemr/ImbEmrConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.imbemr;

/**
* Constants used by the IMB EMR module
*/
public class ImbEmrConstants {

public static final String NATIONAL_ID_UUID = "ed52ec82-4b7c-411b-804a-13bd9651bb3e";
public static final String NID_APPLICATION_NUMBER_UUID = "0f7d2e40-956a-11ef-93fa-0242ac120002";
public static final String UPID_UUID = "01edaedd-956a-11ef-93fa-0242ac120002";
public static final String NIN_UUID = "0c69d739-956a-11ef-93fa-0242ac120002";
public static final String PASSPORT_NUMBER_UUID = "12a72978-956a-11ef-93fa-0242ac120002";

public static final String TELEPHONE_NUMBER_UUID = "d6bcc287-4576-4264-961b-6bf1c08fbf68";
public static final String MOTHERS_NAME_UUID = "8d871d18-c2cc-11de-8d13-0010c6dffd0f";
public static final String FATHERS_NAME_UUID = "b7e948d4-9458-4f06-8d93-e859b6be9b76";
public static final String RELIGION_UUID = "287ad1fe-cd21-4577-bb32-7cd36d6a0ebb";
public static final String PROFESSION_UUID = "ceb19b28-4327-472f-aac4-4c6c6106c7f9";
public static final String EDUCATION_LEVEL_UUID = "9add985a-cba2-421a-8dd5-6323eb5bda4f";

public static final String CLIENT_REGISTRY_URL_PROPERTY = "imbemr.clientregistry.url";
public static final String CLIENT_REGISTRY_USERNAME_PROPERTY = "imbemr.clientregistry.username";
public static final String CLIENT_REGISTRY_PASSWORD_PROPERTY = "imbemr.clientregistry.password";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.openmrs.module.imbemr.integration;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

public class HttpUtils {

public static CloseableHttpClient getHttpClient(String username, String password, boolean trustAllCertificates) {
try {
HttpClientBuilder builder = HttpClients.custom();
if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
builder.setDefaultCredentialsProvider(credentialsProvider);
}
if (trustAllCertificates) {
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustAllStrategy()).build();
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
builder.setSSLSocketFactory(sslFactory);
}
return builder.build();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.imbemr.integration;

import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.hl7.fhir.r4.model.Bundle;
import org.openmrs.Patient;
import org.openmrs.module.imbemr.ImbEmrConstants;
import org.openmrs.util.ConfigUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
* Implementation of MpiPatientFetcher that connects to the Rwandan Client Register
*/
@Component("nidaMpiProvider")
public class NidaMpiProvider {

protected Log log = LogFactory.getLog(getClass());

public static final List<String> SUPPORTED_IDENTIFIER_TYPES = Arrays.asList(
ImbEmrConstants.NATIONAL_ID_UUID,
ImbEmrConstants.NID_APPLICATION_NUMBER_UUID,
ImbEmrConstants.NIN_UUID,
ImbEmrConstants.UPID_UUID,
ImbEmrConstants.PASSPORT_NUMBER_UUID
);

private final FhirContext fhirContext;
private final NidaPatientTranslator patientTranslator;

public NidaMpiProvider(
@Autowired @Qualifier("fhirR4") FhirContext fhirContext,
@Autowired NidaPatientTranslator nidaPatientTranslator
) {
this.fhirContext = fhirContext;
this.patientTranslator = nidaPatientTranslator;
}

public boolean isEnabled() {
String url = ConfigUtil.getProperty(ImbEmrConstants.CLIENT_REGISTRY_URL_PROPERTY);
String username = ConfigUtil.getProperty(ImbEmrConstants.CLIENT_REGISTRY_USERNAME_PROPERTY);
String password = ConfigUtil.getProperty(ImbEmrConstants.CLIENT_REGISTRY_PASSWORD_PROPERTY);
return StringUtils.isNotBlank(url) && StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password);
}

/**
* Ultimately, we should likely adopt and integrate this solution:
* https://github.com/openmrs/openmrs-module-clientregistry
*/
public Patient fetchPatient(String patientId, String identifierTypeUuid) {
if (!SUPPORTED_IDENTIFIER_TYPES.contains(identifierTypeUuid)) {
return null;
}
String url = ConfigUtil.getProperty(ImbEmrConstants.CLIENT_REGISTRY_URL_PROPERTY);
String username = ConfigUtil.getProperty(ImbEmrConstants.CLIENT_REGISTRY_USERNAME_PROPERTY);
String password = ConfigUtil.getProperty(ImbEmrConstants.CLIENT_REGISTRY_PASSWORD_PROPERTY);
if (StringUtils.isBlank(url) || StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
log.debug("Incomplete credentials supplied to fetch patient from NIDA, skipping");
return null;
}

try (CloseableHttpClient httpClient = HttpUtils.getHttpClient(username, password, true)) {
HttpGet httpGet = new HttpGet(url + "/Patient?identifier=" + patientId);
log.debug("Attempting to find patient " + patientId + " from NIDA");
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String data = "";
try {
data = EntityUtils.toString(entity);
} catch (Exception ignored) {
}
if (statusCode != 200) {
throw new IllegalStateException("Http Status Code: " + statusCode + "; Response: " + data);
}
Bundle bundle = fhirContext.newJsonParser().parseResource(Bundle.class, data);
if (bundle == null || bundle.getEntry() == null || bundle.getEntry().size() != 1) {
throw new IllegalStateException("Unexpected bundle found: " + bundle);
}
org.hl7.fhir.r4.model.Patient fhirPatient = (org.hl7.fhir.r4.model.Patient) bundle.getEntry().get(0).getResource();
return patientTranslator.toOpenmrsType(fhirPatient);
}
} catch (Exception e) {
log.debug("An error occurred trying to fetch patients from NIDA, returning null", e);
}

return null;
}
}
Loading