Skip to content

Commit

Permalink
FM2-605: Add Support for FHIR's ETag spec on Medication resource
Browse files Browse the repository at this point in the history
  • Loading branch information
mherman22 committed Jul 25, 2023
1 parent 50e1b5b commit b206de8
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public IBundleProvider searchConditions(ConditionSearchParams conditionSearchPar
conditionSearchParams.toSearchParameterMap().addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, "obsDatetime",
conditionSearchParams.getOnsetDate());

return searchQuery.getQueryResults(conditionSearchParams.toSearchParameterMap(), dao,
translator, searchQueryInclude);
return searchQuery.getQueryResults(conditionSearchParams.toSearchParameterMap(), dao, translator,
searchQueryInclude);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,11 @@
*/
package org.openmrs.module.fhir2.api.impl;

import javax.annotation.Nonnull;

import java.util.Optional;

import ca.uhn.fhir.rest.api.PatchTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.NumberParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
Expand All @@ -35,8 +30,6 @@
import org.openmrs.module.fhir2.api.translators.ObservationTranslator;
import org.openmrs.module.fhir2.api.translators.OpenmrsFhirTranslator;
import org.openmrs.module.fhir2.api.translators.UpdatableOpenmrsTranslator;
import org.openmrs.module.fhir2.api.util.JsonPatchUtils;
import org.openmrs.module.fhir2.api.util.XmlPatchUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package org.openmrs.module.fhir2.api.translators.impl;

import static org.openmrs.module.fhir2.api.translators.impl.FhirTranslatorUtils.getLastUpdated;
import static org.openmrs.module.fhir2.api.translators.impl.FhirTranslatorUtils.getVersionId;

import javax.annotation.Nonnull;

Expand Down Expand Up @@ -75,6 +76,7 @@ public Medication toFhirResource(@Nonnull Drug drug) {
}

medication.getMeta().setLastUpdated(getLastUpdated(drug));
medication.getMeta().setVersionId(getVersionId(drug));

return medication;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public void toFhirResource_shouldTranslateOpenMrsDateChangedToVersionId() {
DiagnosticReport result = translator.toFhirResource(fhirDiagnosticReport);

assertThat(result, notNullValue());
assertThat(result.getMeta().getVersionId(), notNullValue());
assertThat(result.getMeta().getVersionId(), notNullValue());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ public void toFhirResource_shouldTranslateOpenMrsDateChangedToLastUpdatedDate()
assertThat(medication.getMeta().getLastUpdated(), DateMatchers.sameDay(new Date()));
}

@Test
public void toFhirResource_shouldTranslateOpenMrsDateChangedToVersionId() {
drug.setDateChanged(new Date());

org.hl7.fhir.r4.model.Medication medication = medicationTranslator.toFhirResource(drug);
assertThat(medication, notNullValue());
assertThat(medication.getMeta().getVersionId(), notNullValue());
}

@Test
public void toFhirResource_shouldSetFhirMedicationToActiveIfDrugIsNotRetired() {
drug.setRetired(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ public void shouldTranslateOpenMrsDateChangedToVersionId() {
testOrder.setDateChanged(new Date());

when(taskService.searchForTasks(any()))
.thenReturn(new MockIBundleProvider<>(Collections.emptyList(), PREFERRED_PAGE_SIZE, COUNT));
.thenReturn(new MockIBundleProvider<>(Collections.emptyList(), PREFERRED_PAGE_SIZE, COUNT));

org.hl7.fhir.r4.model.ServiceRequest result = translator.toFhirResource(testOrder);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ public void shouldSearchForAllConditionsAsJson() throws Exception {

@Test
public void shouldReturnSortedAndFilteredSearchResultsForConditionsAsJson() throws Exception {
MockHttpServletResponse response = get("/Condition?clinical-status=active?onset-date=2008&_sort=-onset-date").accept(FhirMediaTypes.JSON)
.go();
MockHttpServletResponse response = get("/Condition?clinical-status=active?onset-date=2008&_sort=-onset-date")
.accept(FhirMediaTypes.JSON).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.JSON.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,13 @@
import java.sql.Date;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.List;

import lombok.AccessLevel;
import lombok.Getter;
import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Condition;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.Person;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -357,8 +353,8 @@ public void shouldSearchForAllConditionsAsJson() throws Exception {

@Test
public void shouldReturnSortedAndFilteredSearchResultsForConditionsAsJson() throws Exception {
MockHttpServletResponse response = get("/Condition?clinical-status=active?onset-date=2008&_sort=-onset-date").accept(FhirMediaTypes.JSON)
.go();
MockHttpServletResponse response = get("/Condition?clinical-status=active?onset-date=2008&_sort=-onset-date")
.accept(FhirMediaTypes.JSON).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.JSON.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,8 @@ public void shouldReturnCountForDiagonosticReportAsXml() throws Exception {

@Test
public void shouldReturnAnEtagHeaderWhenRetrievingAnExistingDiagnosticReport() throws Exception {
MockHttpServletResponse response = get("/DiagnosticReport/" + DIAGNOSTIC_REPORT_UUID).accept(FhirMediaTypes.JSON).go();
MockHttpServletResponse response = get("/DiagnosticReport/" + DIAGNOSTIC_REPORT_UUID).accept(FhirMediaTypes.JSON)
.go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.JSON.toString()));
Expand All @@ -705,7 +706,8 @@ public void shouldReturnAnEtagHeaderWhenRetrievingAnExistingDiagnosticReport() t

@Test
public void shouldReturnNotModifiedWhenRetrievingAnExistingDiagnosticReportWithAnEtag() throws Exception {
MockHttpServletResponse response = get("/DiagnosticReport/" + DIAGNOSTIC_REPORT_UUID).accept(FhirMediaTypes.JSON).go();
MockHttpServletResponse response = get("/DiagnosticReport/" + DIAGNOSTIC_REPORT_UUID).accept(FhirMediaTypes.JSON)
.go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.JSON.toString()));
Expand All @@ -714,7 +716,8 @@ public void shouldReturnNotModifiedWhenRetrievingAnExistingDiagnosticReportWithA

String etagValue = response.getHeader("etag");

response = get("/DiagnosticReport/" + DIAGNOSTIC_REPORT_UUID).accept(FhirMediaTypes.JSON).ifNoneMatchHeader(etagValue).go();
response = get("/DiagnosticReport/" + DIAGNOSTIC_REPORT_UUID).accept(FhirMediaTypes.JSON)
.ifNoneMatchHeader(etagValue).go();

assertThat(response, isOk());
assertThat(response, statusEquals(HttpStatus.NOT_MODIFIED));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ public void shouldPatchExistingEncounterUsingXmlPatch() throws Exception {
}

MockHttpServletResponse response = patch("/Encounter/" + ENCOUNTER_UUID).xmlPatch(xmlEncounterPatch)
.accept(FhirMediaTypes.XML).go();
.accept(FhirMediaTypes.XML).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand All @@ -905,8 +905,8 @@ public void shouldPatchExistingEncounterUsingXmlPatch() throws Exception {
assertThat(encounter.getPeriod(), notNullValue());
assertThat(encounter.getPeriod().hasStart(), is(true));
assertThat(encounter.getPeriod().getStart(),
sameDay(LocalDate.of(2005, 2, 1).atStartOfDay(ZoneId.ofOffset("UTC", ZoneOffset.of("+05:30")))
.withZoneSameInstant(ZoneId.systemDefault()).toLocalDate()));
sameDay(LocalDate.of(2005, 2, 1).atStartOfDay(ZoneId.ofOffset("UTC", ZoneOffset.of("+05:30")))
.withZoneSameInstant(ZoneId.systemDefault()).toLocalDate()));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class LocationFhirResourceProviderIntegrationTest extends BaseFhirR4Integ

private static final String JSON_PATCH_LOCATION_PATH = "org/openmrs/module/fhir2/providers/Location_json_patch.json";

private static final String XML_PATCH_LOCATION_PATH= "org/openmrs/module/fhir2/providers/Location_xml_patch.xml";
private static final String XML_PATCH_LOCATION_PATH = "org/openmrs/module/fhir2/providers/Location_xml_patch.xml";

@Getter(AccessLevel.PUBLIC)
@Autowired
Expand Down Expand Up @@ -488,7 +488,7 @@ public void shouldPatchExistingLocationUsingXmlPatch() throws Exception {
xmlLocationPatch = inputStreamToString(is, UTF_8);
}
MockHttpServletResponse response = patch("/Location/" + LOCATION_UUID).xmlPatch(xmlLocationPatch)
.accept(FhirMediaTypes.XML).go();
.accept(FhirMediaTypes.XML).go();

assertThat(response, isOk());
assertThat(response, notNullValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -598,4 +598,40 @@ public void shouldReturnCountForMedicationAsXml() throws Exception {
assertThat(result.getType(), equalTo(Bundle.BundleType.SEARCHSET));
assertThat(result, hasProperty("total", equalTo(4)));
}

@Test
public void shouldReturnAnEtagHeaderWhenRetrievingAnExistingMedication() throws Exception {
MockHttpServletResponse response = get("/Medication/" + MEDICATION_UUID).accept(FhirMediaTypes.JSON).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.JSON.toString()));

assertThat(response.getHeader("etag"), notNullValue());
assertThat(response.getHeader("etag"), startsWith("W/"));

assertThat(response.getContentAsString(), notNullValue());

Medication medication = readResponse(response);

assertThat(medication, notNullValue());
assertThat(medication.getMeta().getVersionId(), notNullValue());
assertThat(medication, validResource());
}

@Test
public void shouldReturnNotModifiedWhenRetrievingAnExistingLocationWithAnEtag() throws Exception {
MockHttpServletResponse response = get("/Medication/" + MEDICATION_UUID).accept(FhirMediaTypes.JSON).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.JSON.toString()));
assertThat(response.getContentAsString(), notNullValue());
assertThat(response.getHeader("etag"), notNullValue());

String etagValue = response.getHeader("etag");

response = get("/Medication/" + MEDICATION_UUID).accept(FhirMediaTypes.JSON).ifNoneMatchHeader(etagValue).go();

assertThat(response, isOk());
assertThat(response, statusEquals(HttpStatus.NOT_MODIFIED));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1507,7 +1507,7 @@ public void shouldPatchExistingObservationUsingJsonMergePatch() throws Exception
}

MockHttpServletResponse response = patch("/Observation/" + OBS_UUID).jsonMergePatch(jsonObservationPatch)
.accept(FhirMediaTypes.JSON).go();
.accept(FhirMediaTypes.JSON).go();

assertThat(response, isOk());
assertThat(response, notNullValue());
Expand All @@ -1531,16 +1531,15 @@ public void shouldPatchExistingObservationUsingJsonPatch() throws Exception {
}

MockHttpServletResponse response = patch("/Observation/" + OBS_UUID).jsonPatch(jsonObservationPatch)
.accept(FhirMediaTypes.JSON).go();

.accept(FhirMediaTypes.JSON).go();

assertThat(response, isOk());
assertThat(response, notNullValue());
assertThat(response.getContentType(), is(BaseFhirIntegrationTest.FhirMediaTypes.JSON.toString()));
assertThat(response.getContentAsString(), notNullValue());

Observation observation = readResponse(response);
System.out.println("entire obs resource: "+ observation.getCode());
System.out.println("entire obs resource: " + observation.getCode());
assertThat(observation, notNullValue());
assertThat(observation.getIdElement().getIdPart(), not(equalTo(OBS_UUID)));
assertThat(observation.getCode().getCodingFirstRep().getCode(), is("5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
Expand All @@ -1556,15 +1555,15 @@ public void shouldPatchExistingObservationUsingXmlPatch() throws Exception {
}

MockHttpServletResponse response = patch("/Observation/" + OBS_UUID).xmlPatch(xmlObservationPatch)
.accept(FhirMediaTypes.XML).go();
.accept(FhirMediaTypes.XML).go();

assertThat(response, isOk());
assertThat(response, notNullValue());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
assertThat(response.getContentAsString(), notNullValue());

Observation observation = readResponse(response);

assertThat(observation, notNullValue());
assertThat(observation.getIdElement().getIdPart(), not(equalTo(OBS_UUID)));
assertThat(observation.getCode().getCodingFirstRep().getCode(), is("5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,16 @@ public void shouldReturnNotModifiedWhenRetrievingAnExistingServiceRequestWithAnE

String etagValue = response.getHeader("etag");

response = get("/ServiceRequest/" + SERVICE_REQUEST_UUID).accept(FhirMediaTypes.JSON).ifNoneMatchHeader(etagValue).go();
response = get("/ServiceRequest/" + SERVICE_REQUEST_UUID).accept(FhirMediaTypes.JSON).ifNoneMatchHeader(etagValue)
.go();

assertThat(response, isOk());
assertThat(response, statusEquals(HttpStatus.NOT_MODIFIED));
}

@Ignore
public void shouldReturnAnUpdatedServiceRequestWithNewEtagWhenRetrievingAnExistingServiceRequestWithAnEtag() throws Exception {
public void shouldReturnAnUpdatedServiceRequestWithNewEtagWhenRetrievingAnExistingServiceRequestWithAnEtag()
throws Exception {
MockHttpServletResponse response = get("/ServiceRequest/" + SERVICE_REQUEST_UUID).accept(FhirMediaTypes.JSON).go();

assertThat(response, isOk());
Expand All @@ -278,7 +280,8 @@ public void shouldReturnAnUpdatedServiceRequestWithNewEtagWhenRetrievingAnExisti
put("/ServiceRequest/" + SERVICE_REQUEST_UUID).jsonContent(toJson(serviceRequest)).accept(FhirMediaTypes.JSON).go();

//send a new GET request, with the “If-None-Match” header specifying the ETag that we previously stored
response = get("/ServiceRequest/" + SERVICE_REQUEST_UUID).accept(FhirMediaTypes.JSON).ifNoneMatchHeader(etagValue).go();
response = get("/ServiceRequest/" + SERVICE_REQUEST_UUID).accept(FhirMediaTypes.JSON).ifNoneMatchHeader(etagValue)
.go();

assertThat(response, isOk());
assertThat(response, statusEquals(HttpStatus.OK));
Expand Down

0 comments on commit b206de8

Please sign in to comment.