<commit_before>/* 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/. */
package org.jembi.rhea.orchestration;

import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathException;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jembi.rhea.Constants;
import org.jembi.rhea.RestfulHttpRequest;
import org.jembi.rhea.RestfulHttpResponse;
import org.jembi.rhea.orchestration.exceptions.ClientValidationException;
import org.jembi.rhea.orchestration.exceptions.EncounterEnrichmentException;
import org.jembi.rhea.orchestration.exceptions.LocationValidationException;
import org.jembi.rhea.orchestration.exceptions.ProviderValidationException;
import org.mule.api.MuleContext;
import org.mule.api.MuleEventContext;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.lifecycle.Callable;
import org.mule.module.client.MuleClient;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.DataTypeException;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.v25.datatype.CX;
import ca.uhn.hl7v2.model.v25.message.ORU_R01;
import ca.uhn.hl7v2.model.v25.segment.PID;
import ca.uhn.hl7v2.model.v25.segment.PV1;
import ca.uhn.hl7v2.parser.GenericParser;
import ca.uhn.hl7v2.parser.Parser;
import ca.uhn.hl7v2.validation.impl.DefaultValidation;

public class SaveEncounterORU_R01ValidatorAndEnricher implements Callable {
	
	private Log log = LogFactory.getLog(this.getClass());
	
	private static boolean validateClient = true;
	private static boolean validateProvider = true;
	private static boolean validateLocation = true;
	private static boolean enrichClientDemographics = true;
	
	protected String validateAndEnrichORU_R01(RestfulHttpRequest request, MuleClient client)
			throws MuleException, EncounterEnrichmentException, ClientValidationException, ProviderValidationException, LocationValidationException {
		String ORU_R01_str = request.getBody();
		ORU_R01 oru_r01 = parseORU_R01(ORU_R01_str);
		
		String ecid = null;
		if (validateClient) {
			ecid = validateAndEnrichClient(client, oru_r01);
			request.setPath("ws/rest/v1/patient/" + Constants.ECID_ID_TYPE + "-" + ecid + "/encounters");
		}
		
		if (validateProvider) {
			validateAndEnrichProvider(client, oru_r01);
		}
		
		if (validateLocation) {
			validateAndEnrichLocation(client, oru_r01);
		}
		
		if (enrichClientDemographics) {
			enrichClientDemographics(client, oru_r01, ecid);
		}
		
		try {
			return new GenericParser().encode(oru_r01, "XML");
		} catch (HL7Exception ex) {
			throw new EncounterEnrichmentException(ex);
		}
		
	}
	
	protected ORU_R01 parseORU_R01(String ORU_R01_str) throws EncounterEnrichmentException {
		Parser parser = new GenericParser();
		DefaultValidation defaultValidation = new DefaultValidation();
		parser.setValidationContext(defaultValidation);
		
		Message msg;
		try {
			msg = parser.parse(ORU_R01_str);
		} catch (HL7Exception ex) {
			throw new EncounterEnrichmentException("Failed to parse HL7 ORU_R01 message", ex);
		}
		
		return (ORU_R01)msg;
	}

	/**
	 * Validate the patient against the Client Registry and enrich the message with the patient's ECID.
	 * Each of the patient's identifiers will validate until the first valid id is found.
	 */
	protected String validateAndEnrichClient(MuleClient client, ORU_R01 oru_r01)
			throws ClientValidationException, MuleException, EncounterEnrichmentException {
		// Validate that one of the patient ID's is correct
		PID pid = oru_r01.getPATIENT_RESULT().getPATIENT().getPID();
		CX[] patientIdentifierList = pid.getPatientIdentifierList();
		
		String ecid = null;
		if (patientIdentifierList.length < 1) {
			throw new ClientValidationException("No patient identifiers found in ORU_R01 message");
		}
		
		for (int i = 0 ; i < patientIdentifierList.length ; i++) {
			String id = patientIdentifierList[i].getIDNumber().getValue();
			String idType = patientIdentifierList[i].getIdentifierTypeCode().getValue();
			ecid = getECID(client, idType, id);
			
			if (ecid!=null) break;
		}
		
		if (ecid == null) {
			throw new ClientValidationException("Invalid client ID");
		} else {
			// Enrich the message
			CX id = pid.getPatientIdentifierList(pid.getPatientIdentifierListReps());
			try {
				id.getIdentifierTypeCode().setValue("ECID");
				id.getIDNumber().setValue(ecid);
			} catch (DataTypeException ex) {
				throw new EncounterEnrichmentException(ex);
			}
		}
		
		return ecid;
	}
	
	private String getECID(MuleClient client, String idType, String id) throws ClientValidationException, MuleException {
		Map<String, String> idMap = new HashMap<String, String>();
		idMap.put("id", id);
		idMap.put("idType", idType);
		
		MuleMessage response = client.send("vm://getecid", idMap, null, 5000);
		
		String success = response.getInboundProperty("success");
		if (success != null && success.equals("true")) {
			try {
				return response.getPayloadAsString();
			} catch (Exception ex) {
				//argh! getPayloadAsString throws exception.. bad bad bad
				throw new ClientValidationException(ex);
			}
		}
		
		return null;
	}

	/**
	 * Validate the Provider ID against the Provider Registry and enrich the message with the provider's EPID.
	 */
	protected void validateAndEnrichProvider(MuleClient client, ORU_R01 oru_r01)
			throws MuleException, ProviderValidationException, EncounterEnrichmentException {
		// Validate provider ID and location ID is correct
		String epid = null;
		PV1 pv1 = oru_r01.getPATIENT_RESULT().getPATIENT().getVISIT().getPV1();
		String proID = pv1.getAttendingDoctor(0).getIDNumber().getValue();
		String proIDType = pv1.getAttendingDoctor(0).getIdentifierTypeCode().getValue();
		
		Map<String, String> ProIdMap = new HashMap<String, String>();
		ProIdMap.put("id", proID);
		ProIdMap.put("idType", proIDType);
		
		MuleMessage response = client.send("vm://getepid-openldap", ProIdMap, null, 5000);
		
		String success = response.getInboundProperty("success");
		if (success.equals("true")) {
			try {
				epid = response.getPayloadAsString();
			} catch (Exception ex) {
				throw new ProviderValidationException(ex);
			}
			
			// Enrich message
			try {
				pv1.getAttendingDoctor(0).getIDNumber().setValue(epid);
				pv1.getAttendingDoctor(0).getIdentifierTypeCode().setValue(Constants.EPID_ID_TYPE);
			} catch (DataTypeException ex) {
				throw new EncounterEnrichmentException(ex);
			}
		}
		
		if (epid == null) {
			throw new ProviderValidationException("Invalid provider ID");
		}
	}

	/**
	 * Validate the location id against the Facility Registry.
	 * 
	 * This method does not alter the ORU_R01 message.
	 */
	protected void validateAndEnrichLocation(MuleClient client, ORU_R01 oru_r01)
			throws MuleException, LocationValidationException {
		// Validate location ID is correct - sending facility
		String elid = oru_r01.getMSH().getSendingFacility().getHd1_NamespaceID().getValue();
		
		MuleMessage response = client.send("vm://validateFacility-resourcemap", elid, null, 5000);
		
		String success = response.getInboundProperty("success");
		if (!success.equals("true")) {
			throw new LocationValidationException("Invalid location ID");
		}
	}
	
	/**
	 * Fetch patient demographic data from the Client Registry and enrich the ORU_R01 with any details that may be missing.
	 * @throws ClientValidationException 
	 */
	protected void enrichClientDemographics(MuleClient client, ORU_R01 oru_r01, String ecid) throws MuleException, EncounterEnrichmentException, ClientValidationException {
		PID pid = oru_r01.getPATIENT_RESULT().getPATIENT().getPID();
		String givenName = pid.getPatientName(0).getGivenName().getValue();
		String familyName = pid.getPatientName(0).getFamilyName().getFn1_Surname().getValue();
		String gender = pid.getAdministrativeSex().getValue();
		String dob = pid.getDateTimeOfBirth().getTime().getValue();
		
		try {
			if ((givenName == null || givenName.isEmpty()) || (familyName == null || familyName.isEmpty()) || (gender == null || gender.isEmpty()) || (dob == null || dob.isEmpty())) {
				// fetch client record from CR to enrich message as it is missing key values
				String clientRecord = fetchClientRecord_OpenEMPI(ecid, client);
				if (clientRecord==null)
					throw new ClientValidationException();
				
				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				Document document = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(clientRecord)));
	
				XPathFactory xpf = XPathFactory.newInstance();
				XPath xpath = xpf.newXPath();
				
				String givenNameFromCR = getNodeContent(xpath, document, "/ADT_A05/PID/PID.5/XPN.2");
				String familyNameFromCR = getNodeContent(xpath, document, "/ADT_A05/PID/PID.5/XPN.1/FN.1");
				String genderFromCR = getNodeContent(xpath, document, "/ADT_A05/PID/PID.8");
				String dobStrFromCR = getNodeContent(xpath, document, "/ADT_A05/PID/PID.7/TS.1");
				
				// replace the missing fields with the CR content
				if (givenName == null || givenName.isEmpty()) {
					pid.getPatientName(0).getGivenName().setValue(givenNameFromCR);
				}
				if (familyName == null || familyName.isEmpty()) {
					pid.getPatientName(0).getFamilyName().getFn1_Surname().setValue(familyNameFromCR);
				}
				if (gender == null || gender.isEmpty()) {
					pid.getAdministrativeSex().setValue(genderFromCR);
				}
				if (dob == null || dob.isEmpty()) {
					pid.getDateTimeOfBirth().getTime().setValue(dobStrFromCR);
				}
			}
		} catch (XPathException ex) {
			throw new EncounterEnrichmentException(ex);
		} catch (SAXException ex) {
			throw new EncounterEnrichmentException(ex);
		} catch (IOException ex) {
			throw new EncounterEnrichmentException(ex);
		} catch (ParserConfigurationException ex) {
			throw new EncounterEnrichmentException(ex);
		} catch (DataTypeException ex) {
			throw new EncounterEnrichmentException(ex);
		}
	}
	
	private String getNodeContent(XPath xpath, Document document, String path) throws XPathExpressionException {
		XPathExpression expression = xpath.compile(path);
		Node givenNameNode = (Node) expression.evaluate(document, XPathConstants.NODE);
		return givenNameNode.getTextContent();
	}
	
	/**
	 * Fetch client record from OpenEMPI for a patient with the specified ECID
	 * 
	 * @return The response from OpenEMPI in XML
	 */
	private String fetchClientRecord_OpenEMPI(String ecid, MuleClient client) throws MuleException {
		RestfulHttpRequest req = new RestfulHttpRequest();
		req.setHttpMethod(RestfulHttpRequest.HTTP_GET);
		req.setPath("ws/rest/v1/patient/" + Constants.ECID_ID_TYPE + "-" + ecid);
		MuleMessage response = client.send("vm://getPatient-De-normailization-OpenEMPI", req, null, 5000);
		RestfulHttpResponse res = (RestfulHttpResponse) response.getPayload();
		
		/*String success = response.getInboundProperty("success");
		if (success==null || !success.equals("true"))
			return null;*/
		
		return res.getBody();
	}
	

	@Override
	public Object onCall(MuleEventContext eventContext) throws Exception {
		MuleContext muleContext = eventContext.getMuleContext();
		MuleClient client = new MuleClient(muleContext);
		MuleMessage msg = eventContext.getMessage();
		RestfulHttpRequest payload = (RestfulHttpRequest) msg.getPayload();
		
		String newORU_R01 = validateAndEnrichORU_R01(payload, client);
		payload.setBody(newORU_R01);<commit_msg>Removed commented out code so that it doesn't 'rot'<commit_after>/* 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/. */
package org.jembi.rhea.orchestration;

import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathException;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jembi.rhea.Constants;
import org.jembi.rhea.RestfulHttpRequest;
import org.jembi.rhea.RestfulHttpResponse;
import org.jembi.rhea.orchestration.exceptions.ClientValidationException;
import org.jembi.rhea.orchestration.exceptions.EncounterEnrichmentException;
import org.jembi.rhea.orchestration.exceptions.LocationValidationException;
import org.jembi.rhea.orchestration.exceptions.ProviderValidationException;
import org.mule.api.MuleContext;
import org.mule.api.MuleEventContext;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.lifecycle.Callable;
import org.mule.module.client.MuleClient;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.DataTypeException;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.v25.datatype.CX;
import ca.uhn.hl7v2.model.v25.message.ORU_R01;
import ca.uhn.hl7v2.model.v25.segment.PID;
import ca.uhn.hl7v2.model.v25.segment.PV1;
import ca.uhn.hl7v2.parser.GenericParser;
import ca.uhn.hl7v2.parser.Parser;
import ca.uhn.hl7v2.validation.impl.DefaultValidation;

public class SaveEncounterORU_R01ValidatorAndEnricher implements Callable {
	
	private Log log = LogFactory.getLog(this.getClass());
	
	private static boolean validateClient = true;
	private static boolean validateProvider = true;
	private static boolean validateLocation = true;
	private static boolean enrichClientDemographics = true;
	
	protected String validateAndEnrichORU_R01(RestfulHttpRequest request, MuleClient client)
			throws MuleException, EncounterEnrichmentException, ClientValidationException, ProviderValidationException, LocationValidationException {
		String ORU_R01_str = request.getBody();
		ORU_R01 oru_r01 = parseORU_R01(ORU_R01_str);
		
		String ecid = null;
		if (validateClient) {
			ecid = validateAndEnrichClient(client, oru_r01);
			request.setPath("ws/rest/v1/patient/" + Constants.ECID_ID_TYPE + "-" + ecid + "/encounters");
		}
		
		if (validateProvider) {
			validateAndEnrichProvider(client, oru_r01);
		}
		
		if (validateLocation) {
			validateAndEnrichLocation(client, oru_r01);
		}
		
		if (enrichClientDemographics) {
			enrichClientDemographics(client, oru_r01, ecid);
		}
		
		try {
			return new GenericParser().encode(oru_r01, "XML");
		} catch (HL7Exception ex) {
			throw new EncounterEnrichmentException(ex);
		}
		
	}
	
	protected ORU_R01 parseORU_R01(String ORU_R01_str) throws EncounterEnrichmentException {
		Parser parser = new GenericParser();
		DefaultValidation defaultValidation = new DefaultValidation();
		parser.setValidationContext(defaultValidation);
		
		Message msg;
		try {
			msg = parser.parse(ORU_R01_str);
		} catch (HL7Exception ex) {
			throw new EncounterEnrichmentException("Failed to parse HL7 ORU_R01 message", ex);
		}
		
		return (ORU_R01)msg;
	}

	/**
	 * Validate the patient against the Client Registry and enrich the message with the patient's ECID.
	 * Each of the patient's identifiers will validate until the first valid id is found.
	 */
	protected String validateAndEnrichClient(MuleClient client, ORU_R01 oru_r01)
			throws ClientValidationException, MuleException, EncounterEnrichmentException {
		// Validate that one of the patient ID's is correct
		PID pid = oru_r01.getPATIENT_RESULT().getPATIENT().getPID();
		CX[] patientIdentifierList = pid.getPatientIdentifierList();
		
		String ecid = null;
		if (patientIdentifierList.length < 1) {
			throw new ClientValidationException("No patient identifiers found in ORU_R01 message");
		}
		
		for (int i = 0 ; i < patientIdentifierList.length ; i++) {
			String id = patientIdentifierList[i].getIDNumber().getValue();
			String idType = patientIdentifierList[i].getIdentifierTypeCode().getValue();
			ecid = getECID(client, idType, id);
			
			if (ecid!=null) break;
		}
		
		if (ecid == null) {
			throw new ClientValidationException("Invalid client ID");
		} else {
			// Enrich the message
			CX id = pid.getPatientIdentifierList(pid.getPatientIdentifierListReps());
			try {
				id.getIdentifierTypeCode().setValue("ECID");
				id.getIDNumber().setValue(ecid);
			} catch (DataTypeException ex) {
				throw new EncounterEnrichmentException(ex);
			}
		}
		
		return ecid;
	}
	
	private String getECID(MuleClient client, String idType, String id) throws ClientValidationException, MuleException {
		Map<String, String> idMap = new HashMap<String, String>();
		idMap.put("id", id);
		idMap.put("idType", idType);
		
		MuleMessage response = client.send("vm://getecid", idMap, null, 5000);
		
		String success = response.getInboundProperty("success");
		if (success != null && success.equals("true")) {
			try {
				return response.getPayloadAsString();
			} catch (Exception ex) {
				//argh! getPayloadAsString throws exception.. bad bad bad
				throw new ClientValidationException(ex);
			}
		}
		
		return null;
	}

	/**
	 * Validate the Provider ID against the Provider Registry and enrich the message with the provider's EPID.
	 */
	protected void validateAndEnrichProvider(MuleClient client, ORU_R01 oru_r01)
			throws MuleException, ProviderValidationException, EncounterEnrichmentException {
		// Validate provider ID and location ID is correct
		String epid = null;
		PV1 pv1 = oru_r01.getPATIENT_RESULT().getPATIENT().getVISIT().getPV1();
		String proID = pv1.getAttendingDoctor(0).getIDNumber().getValue();
		String proIDType = pv1.getAttendingDoctor(0).getIdentifierTypeCode().getValue();
		
		Map<String, String> ProIdMap = new HashMap<String, String>();
		ProIdMap.put("id", proID);
		ProIdMap.put("idType", proIDType);
		
		MuleMessage response = client.send("vm://getepid-openldap", ProIdMap, null, 5000);
		
		String success = response.getInboundProperty("success");
		if (success.equals("true")) {
			try {
				epid = response.getPayloadAsString();
			} catch (Exception ex) {
				throw new ProviderValidationException(ex);
			}
			
			// Enrich message
			try {
				pv1.getAttendingDoctor(0).getIDNumber().setValue(epid);
				pv1.getAttendingDoctor(0).getIdentifierTypeCode().setValue(Constants.EPID_ID_TYPE);
			} catch (DataTypeException ex) {
				throw new EncounterEnrichmentException(ex);
			}
		}
		
		if (epid == null) {
			throw new ProviderValidationException("Invalid provider ID");
		}
	}

	/**
	 * Validate the location id against the Facility Registry.
	 * 
	 * This method does not alter the ORU_R01 message.
	 */
	protected void validateAndEnrichLocation(MuleClient client, ORU_R01 oru_r01)
			throws MuleException, LocationValidationException {
		// Validate location ID is correct - sending facility
		String elid = oru_r01.getMSH().getSendingFacility().getHd1_NamespaceID().getValue();
		
		MuleMessage response = client.send("vm://validateFacility-resourcemap", elid, null, 5000);
		
		String success = response.getInboundProperty("success");
		if (!success.equals("true")) {
			throw new LocationValidationException("Invalid location ID");
		}
	}
	
	/**
	 * Fetch patient demographic data from the Client Registry and enrich the ORU_R01 with any details that may be missing.
	 * @throws ClientValidationException 
	 */
	protected void enrichClientDemographics(MuleClient client, ORU_R01 oru_r01, String ecid) throws MuleException, EncounterEnrichmentException, ClientValidationException {
		PID pid = oru_r01.getPATIENT_RESULT().getPATIENT().getPID();
		String givenName = pid.getPatientName(0).getGivenName().getValue();
		String familyName = pid.getPatientName(0).getFamilyName().getFn1_Surname().getValue();
		String gender = pid.getAdministrativeSex().getValue();
		String dob = pid.getDateTimeOfBirth().getTime().getValue();
		
		try {
			if ((givenName == null || givenName.isEmpty()) || (familyName == null || familyName.isEmpty()) || (gender == null || gender.isEmpty()) || (dob == null || dob.isEmpty())) {
				// fetch client record from CR to enrich message as it is missing key values
				String clientRecord = fetchClientRecord_OpenEMPI(ecid, client);
				if (clientRecord==null)
					throw new ClientValidationException();
				
				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				Document document = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(clientRecord)));
	
				XPathFactory xpf = XPathFactory.newInstance();
				XPath xpath = xpf.newXPath();
				
				String givenNameFromCR = getNodeContent(xpath, document, "/ADT_A05/PID/PID.5/XPN.2");
				String familyNameFromCR = getNodeContent(xpath, document, "/ADT_A05/PID/PID.5/XPN.1/FN.1");
				String genderFromCR = getNodeContent(xpath, document, "/ADT_A05/PID/PID.8");
				String dobStrFromCR = getNodeContent(xpath, document, "/ADT_A05/PID/PID.7/TS.1");
				
				// replace the missing fields with the CR content
				if (givenName == null || givenName.isEmpty()) {
					pid.getPatientName(0).getGivenName().setValue(givenNameFromCR);
				}
				if (familyName == null || familyName.isEmpty()) {
					pid.getPatientName(0).getFamilyName().getFn1_Surname().setValue(familyNameFromCR);
				}
				if (gender == null || gender.isEmpty()) {
					pid.getAdministrativeSex().setValue(genderFromCR);
				}
				if (dob == null || dob.isEmpty()) {
					pid.getDateTimeOfBirth().getTime().setValue(dobStrFromCR);
				}
			}
		} catch (XPathException ex) {
			throw new EncounterEnrichmentException(ex);
		} catch (SAXException ex) {
			throw new EncounterEnrichmentException(ex);
		} catch (IOException ex) {
			throw new EncounterEnrichmentException(ex);
		} catch (ParserConfigurationException ex) {
			throw new EncounterEnrichmentException(ex);
		} catch (DataTypeException ex) {
			throw new EncounterEnrichmentException(ex);
		}
	}
	
	private String getNodeContent(XPath xpath, Document document, String path) throws XPathExpressionException {
		XPathExpression expression = xpath.compile(path);
		Node givenNameNode = (Node) expression.evaluate(document, XPathConstants.NODE);
		return givenNameNode.getTextContent();
	}
	
	/**
	 * Fetch client record from OpenEMPI for a patient with the specified ECID
	 * 
	 * @return The response from OpenEMPI in XML
	 */
	private String fetchClientRecord_OpenEMPI(String ecid, MuleClient client) throws MuleException {
		RestfulHttpRequest req = new RestfulHttpRequest();
		req.setHttpMethod(RestfulHttpRequest.HTTP_GET);
		req.setPath("ws/rest/v1/patient/" + Constants.ECID_ID_TYPE + "-" + ecid);
		MuleMessage response = client.send("vm://getPatient-De-normailization-OpenEMPI", req, null, 5000);
		RestfulHttpResponse res = (RestfulHttpResponse) response.getPayload();
		
		return res.getBody();
	}
	

	@Override
	public Object onCall(MuleEventContext eventContext) throws Exception {
		MuleContext muleContext = eventContext.getMuleContext();
		MuleClient client = new MuleClient(muleContext);
		MuleMessage msg = eventContext.getMessage();
		RestfulHttpRequest payload = (RestfulHttpRequest) msg.getPayload();
		
		String newORU_R01 = validateAndEnrichORU_R01(payload, client);
		payload.setBody(newORU_R01);
{'fraction_non_alphanumeric': 0.10934218264303117, 'fraction_numerical': 0.014030076451314795, 'mean_word_length': 4.776995874787673, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 20}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5456100', 'n_tokens_mistral': 8401, 'n_tokens_neox': 7296, 'n_words': 1653}