added UserInfoInterceptor to pass user context for auditing, added narratives for Medication Prescription, moved URL into RequestDetails so it's available to interceptors

This commit is contained in:
lmds1 2014-09-17 11:35:15 -04:00
parent 13dd6d5e11
commit 9906b61987
8 changed files with 164 additions and 9 deletions

View File

@ -0,0 +1,64 @@
package ca.uhn.fhir.rest.client.interceptor;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import ca.uhn.fhir.rest.client.IClientInterceptor;
/**
* HTTP interceptor to be used for adding HTTP headers containing user identifying info for auditing purposes to the request
* <p>
* See the <a href="http://hl7api.sourceforge.net/hapi-fhir/doc_rest_client.html#User_Info">HAPI Documentation</a>
* for information on how to use this class.
* </p>
*/
public class UserInfoInterceptor implements IClientInterceptor {
public static final String HEADER_USER_ID = "fhir-user-id";
public static final String HEADER_USER_NAME = "fhir-user-name";
private String myUserId;
private String myUserName;
public UserInfoInterceptor(String theUserId, String theUserName) {
super();
myUserId = theUserId;
myUserName = theUserName;
}
@Override
public void interceptRequest(HttpRequestBase theRequest) {
if(myUserId != null) theRequest.addHeader(HEADER_USER_ID, myUserId);
if(myUserName != null) theRequest.addHeader(HEADER_USER_NAME, myUserName);
}
@Override
public void interceptResponse(HttpResponse theResponse) throws IOException {
// nothing
}
}

View File

@ -37,7 +37,6 @@ import ca.uhn.fhir.rest.method.SearchMethodBinding.RequestType;
*/ */
public class Request extends RequestDetails { public class Request extends RequestDetails {
private String myCompleteUrl;
private String myFhirServerBase; private String myFhirServerBase;
private String myOperation; private String myOperation;
private RequestType myRequestType; private RequestType myRequestType;
@ -47,10 +46,6 @@ public class Request extends RequestDetails {
private HttpServletResponse myServletResponse; private HttpServletResponse myServletResponse;
private Map<String, List<String>> myUnqualifiedToQualifiedNames; private Map<String, List<String>> myUnqualifiedToQualifiedNames;
public String getCompleteUrl() {
return myCompleteUrl;
}
public String getFhirServerBase() { public String getFhirServerBase() {
return myFhirServerBase; return myFhirServerBase;
} }
@ -84,10 +79,6 @@ public class Request extends RequestDetails {
return myRespondGzip; return myRespondGzip;
} }
public void setCompleteUrl(String theCompleteUrl) {
myCompleteUrl = theCompleteUrl;
}
public void setFhirServerBase(String theFhirServerBase) { public void setFhirServerBase(String theFhirServerBase) {
myFhirServerBase = theFhirServerBase; myFhirServerBase = theFhirServerBase;
} }

View File

@ -35,6 +35,7 @@ public class RequestDetails {
private String myResourceName; private String myResourceName;
private RestfulOperationTypeEnum myResourceOperationType; private RestfulOperationTypeEnum myResourceOperationType;
private RestfulOperationSystemEnum mySystemOperationType; private RestfulOperationSystemEnum mySystemOperationType;
private String myCompleteUrl;
public String getCompartmentName() { public String getCompartmentName() {
return myCompartmentName; return myCompartmentName;
@ -92,4 +93,12 @@ public class RequestDetails {
mySystemOperationType = theSystemOperationType; mySystemOperationType = theSystemOperationType;
} }
public String getCompleteUrl() {
return myCompleteUrl;
}
public void setCompleteUrl(String theCompleteUrl) {
myCompleteUrl = theCompleteUrl;
}
} }

View File

@ -0,0 +1,20 @@
<!--/*
This top section is not exported as a part of the Narrative,
it is only present so that this template can be viewed in
a browser.
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="narrative.css"/>
</head>
<body>
<!--*/-->
<div>
<div class="hapiHeaderText" th:if="${not resource.name.empty}" th:narrative="${resource.name}"></div>
</div>
<!--/*-->
</body>
</html>
<!--*/-->

View File

@ -0,0 +1,36 @@
<!--/*
This top section is not exported as a part of the Narrative,
it is only present so that this template can be viewed in
a browser.
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="narrative.css"/>
</head>
<body>
<!--*/-->
<div>
<div class="hapiHeaderText" th:if="${not resource.medication.resource.name.empty}" th:narrative="${resource.medication.resource.name}"></div>
<table class="hapiPropertyTable">
<tbody>
<tr th:if="${not resource.id.empty}">
<td>Id</td>
<td th:text="${resource.id.value}"></td>
</tr>
<tr th:if="${not resource.dateWritten.empty}">
<td>Date</td>
<td ><span th:text="${#dates.format(resource.dateWritten.value,'dd MMMM yyyy')}"></span></td>
</tr>
<tr th:if="${not resource.status.empty}">
<td>Status</td>
<td><span th:text="${resource.status.valueAsEnum}"></span></td>
</tr>
</tbody>
</table>
</div>
<!--/*-->
</body>
</html>
<!--*/-->

View File

@ -60,3 +60,11 @@ patient.class=ca.uhn.fhir.model.dstu.resource.Patient
patient.narrative=classpath:ca/uhn/fhir/narrative/Patient.html patient.narrative=classpath:ca/uhn/fhir/narrative/Patient.html
patient.title=classpath:ca/uhn/fhir/narrative/title/Patient.html patient.title=classpath:ca/uhn/fhir/narrative/title/Patient.html
medicationprescription.class=ca.uhn.fhir.model.dstu.resource.MedicationPrescription
medicationprescription.narrative=classpath:ca/uhn/fhir/narrative/MedicationPrescription.html
medicationprescription.title=classpath:ca/uhn/fhir/narrative/title/MedicationPrescription.html
medication.class=ca.uhn.fhir.model.dstu.resource.Medication
medication.narrative=classpath:ca/uhn/fhir/narrative/Medication.html
medication.title=classpath:ca/uhn/fhir/narrative/Medication.html

View File

@ -0,0 +1,3 @@
<div>
<div class="hapiHeaderText" th:if="${not resource.medication.resource.name.empty}" th:narrative="${resource.medication.resource.name}"></div>
</div>

View File

@ -10,6 +10,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt; import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt; import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
@ -19,6 +20,8 @@ import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Conformance; import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport; import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu.resource.Encounter; import ca.uhn.fhir.model.dstu.resource.Encounter;
import ca.uhn.fhir.model.dstu.resource.Medication;
import ca.uhn.fhir.model.dstu.resource.MedicationPrescription;
import ca.uhn.fhir.model.dstu.resource.Observation; import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome; import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.resource.Organization; import ca.uhn.fhir.model.dstu.resource.Organization;
@ -26,6 +29,7 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.DiagnosticReportStatusEnum; import ca.uhn.fhir.model.dstu.valueset.DiagnosticReportStatusEnum;
import ca.uhn.fhir.model.dstu.valueset.EncounterClassEnum; import ca.uhn.fhir.model.dstu.valueset.EncounterClassEnum;
import ca.uhn.fhir.model.dstu.valueset.EncounterTypeEnum; import ca.uhn.fhir.model.dstu.valueset.EncounterTypeEnum;
import ca.uhn.fhir.model.dstu.valueset.MedicationPrescriptionStatusEnum;
import ca.uhn.fhir.model.dstu.valueset.ObservationStatusEnum; import ca.uhn.fhir.model.dstu.valueset.ObservationStatusEnum;
import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
@ -204,4 +208,24 @@ public class DefaultThymeleafNarrativeGeneratorTest {
} }
@Test
public void testGenerateMedicationPrescription(){
MedicationPrescription mp = new MedicationPrescription();
mp.setId("12345");
Medication med = new Medication();
med.setName("ciprofloaxin");
ResourceReferenceDt medRef = new ResourceReferenceDt(med);
mp.setMedication(medRef );
mp.setStatus(MedicationPrescriptionStatusEnum.ACTIVE);
mp.setDateWritten(new DateTimeDt("2014-09-01"));
NarrativeDt narrative = gen.generateNarrative(mp);
assertTrue("Expected medication name of ciprofloaxin within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ciprofloaxin")>-1);
assertTrue("Expected string status of ACTIVE within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ACTIVE")>-1);
String title = gen.generateTitle(mp);
assertEquals("ciprofloaxin", title);
}
} }