Merge branch 'master' of github.com:jamesagnew/hapi-fhir

This commit is contained in:
jamesagnew 2019-05-08 15:52:39 -04:00
commit 6fd66b404f
8 changed files with 247 additions and 62 deletions

View File

@ -1266,7 +1266,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
IIdType resourceId; IIdType resourceId;
if (isNotBlank(theMatchUrl)) { if (isNotBlank(theMatchUrl)) {
StopWatch sw = new StopWatch();
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType); Set<Long> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType);
if (match.size() > 1) { if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "UPDATE", theMatchUrl, match.size()); String msg = getContext().getLocalizer().getMessage(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "UPDATE", theMatchUrl, match.size());
@ -1315,6 +1314,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
* See SystemProviderR4Test#testTransactionReSavesPreviouslyDeletedResources * See SystemProviderR4Test#testTransactionReSavesPreviouslyDeletedResources
* for a test that needs this. * for a test that needs this.
*/ */
boolean wasDeleted = entity.getDeleted() != null;
entity.setDeleted(null); entity.setDeleted(null);
/* /*
@ -1325,7 +1325,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
*/ */
if (!thePerformIndexing) { if (!thePerformIndexing) {
theResource.setId(entity.getIdDt().getValue()); theResource.setId(entity.getIdDt().getValue());
DaoMethodOutcome outcome = toMethodOutcome(theRequestDetails, entity, theResource).setCreated(false); DaoMethodOutcome outcome = toMethodOutcome(theRequestDetails, entity, theResource).setCreated(wasDeleted);
outcome.setPreviousResource(oldResource); outcome.setPreviousResource(oldResource);
return outcome; return outcome;
} }
@ -1334,7 +1334,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
* Otherwise, we're not in a transaction * Otherwise, we're not in a transaction
*/ */
ResourceTable savedEntity = updateInternal(theRequestDetails, theResource, thePerformIndexing, theForceUpdateVersion, entity, resourceId, oldResource); ResourceTable savedEntity = updateInternal(theRequestDetails, theResource, thePerformIndexing, theForceUpdateVersion, entity, resourceId, oldResource);
DaoMethodOutcome outcome = toMethodOutcome(theRequestDetails, savedEntity, theResource).setCreated(false); DaoMethodOutcome outcome = toMethodOutcome(theRequestDetails, savedEntity, theResource).setCreated(wasDeleted);
if (!thePerformIndexing) { if (!thePerformIndexing) {
outcome.setId(theResource.getIdElement()); outcome.setId(theResource.getIdElement());

View File

@ -154,7 +154,7 @@ public class JpaConformanceProviderR4 extends org.hl7.fhir.r4.hapi.rest.server.S
if (isNotBlank(myDaoConfig.getWebsocketContextPath())) { if (isNotBlank(myDaoConfig.getWebsocketContextPath())) {
Extension websocketExtension = new Extension(); Extension websocketExtension = new Extension();
websocketExtension.setUrl(Constants.CAPABILITYSTATEMENT_WEBSOCKET_URL); websocketExtension.setUrl(Constants.CAPABILITYSTATEMENT_WEBSOCKET_URL);
websocketExtension.setValue(new org.hl7.fhir.dstu3.model.UriType(myDaoConfig.getWebsocketContextPath())); websocketExtension.setValue(new UriType(myDaoConfig.getWebsocketContextPath()));
retVal.getRestFirstRep().addExtension(websocketExtension); retVal.getRestFirstRep().addExtension(websocketExtension);
} }
} }

View File

@ -1,9 +1,5 @@
package ca.uhn.fhir.jpa.dao.dstu3; package ca.uhn.fhir.jpa.dao.dstu3;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.jpa.util.TestUtil;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
@ -12,21 +8,33 @@ import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.validation.IValidatorModule;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus; import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.utils.IResourceValidator;
import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.util.AopTestUtils;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test { public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3ValidateTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3ValidateTest.class);
@Autowired
private IValidatorModule myValidatorModule;
@Test @Test
public void testValidateChangedQuestionnaire() { public void testValidateChangedQuestionnaire() {
@ -73,6 +81,77 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
} }
@After
public void after() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning);
}
@Test
public void testValidateWithCanonicalReference() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
IResourceValidator.BestPracticeWarningLevel a = IResourceValidator.BestPracticeWarningLevel.Ignore;
val.setBestPracticeWarningLevel(a);
ValueSet vs = new ValueSet();
vs.setId("MYVS");
vs.setUrl("http://myvs");
vs.getCompose()
.addInclude()
.setSystem("http://hl7.org/fhir/administrative-gender")
.addConcept(new ValueSet.ConceptReferenceComponent().setCode("male"))
.addConcept(new ValueSet.ConceptReferenceComponent().setCode("female"));
myValueSetDao.update(vs);
Questionnaire q = new Questionnaire();
q.setId("MYQ");
q.setUrl("http://hl7.org/fhir/Questionnaire/myq");
q.addItem()
.setLinkId("LINKID")
.setType(Questionnaire.QuestionnaireItemType.CHOICE)
.setOptions(new Reference().setReference("ValueSet/MYVS"));
myQuestionnaireDao.update(q);
// Validate with matching code
QuestionnaireResponse qr = new QuestionnaireResponse();
qr.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
qr.setQuestionnaire(new Reference("Questionnaire/MYQ"));
qr.addItem()
.setLinkId("LINKID")
.addAnswer()
.setValue(new Coding().setSystem("http://hl7.org/fhir/administrative-gender").setCode("aaa").setDisplay("AAAA"));
// Validate as resource
try {
MethodOutcome outcome = myQuestionnaireResponseDao.validate(qr, null, null, null, ValidationModeEnum.CREATE, null, mySrd);
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo));
fail();
} catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
String encoded = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
ourLog.info(encoded);
assertThat(encoded, containsString("is not in the options value set"));
}
// Validate as string
try {
String raw = myFhirCtx.newJsonParser().encodeResourceToString(qr);
MethodOutcome outcome = myQuestionnaireResponseDao.validate(qr, null, raw, EncodingEnum.JSON, ValidationModeEnum.CREATE, null, mySrd);
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo));
fail();
} catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
String encoded = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
ourLog.info(encoded);
assertThat(encoded, containsString("is not in the options value set"));
}
}
@Test @Test
public void testValidateStructureDefinition() throws Exception { public void testValidateStructureDefinition() throws Exception {
String input = IOUtils.toString(getClass().getResourceAsStream("/sd-david-dhtest7.json"), StandardCharsets.UTF_8); String input = IOUtils.toString(getClass().getResourceAsStream("/sd-david-dhtest7.json"), StandardCharsets.UTF_8);

View File

@ -1,9 +1,5 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao.r4;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum; import ca.uhn.fhir.rest.api.ValidationModeEnum;
@ -13,34 +9,33 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.validation.IValidatorModule;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Observation.ObservationStatus; import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.r4.model.OperationOutcome; import org.hl7.fhir.r4.utils.IResourceValidator;
import org.hl7.fhir.r4.model.Organization; import org.junit.After;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.ValueSet;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.util.AopTestUtils;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test { public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4ValidateTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4ValidateTest.class);
@Autowired
@AfterClass private IValidatorModule myValidatorModule;
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
@Test @Test
public void testValidateStructureDefinition() throws Exception { public void testValidateStructureDefinition() throws Exception {
@ -139,24 +134,24 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
MethodOutcome outcome = null; MethodOutcome outcome = null;
ValidationModeEnum mode = ValidationModeEnum.CREATE; ValidationModeEnum mode = ValidationModeEnum.CREATE;
switch (enc) { switch (enc) {
case JSON: case JSON:
encoded = myFhirCtx.newJsonParser().encodeResourceToString(input); encoded = myFhirCtx.newJsonParser().encodeResourceToString(input);
try { try {
myObservationDao.validate(input, null, encoded, EncodingEnum.JSON, mode, null, mySrd); myObservationDao.validate(input, null, encoded, EncodingEnum.JSON, mode, null, mySrd);
fail(); fail();
} catch (PreconditionFailedException e) { } catch (PreconditionFailedException e) {
return (OperationOutcome) e.getOperationOutcome(); return (OperationOutcome) e.getOperationOutcome();
} }
break; break;
case XML: case XML:
encoded = myFhirCtx.newXmlParser().encodeResourceToString(input); encoded = myFhirCtx.newXmlParser().encodeResourceToString(input);
try { try {
myObservationDao.validate(input, null, encoded, EncodingEnum.XML, mode, null, mySrd); myObservationDao.validate(input, null, encoded, EncodingEnum.XML, mode, null, mySrd);
fail(); fail();
} catch (PreconditionFailedException e) { } catch (PreconditionFailedException e) {
return (OperationOutcome) e.getOperationOutcome(); return (OperationOutcome) e.getOperationOutcome();
} }
break; break;
} }
throw new IllegalStateException(); // shouldn't get here throw new IllegalStateException(); // shouldn't get here
@ -185,6 +180,57 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
} }
@Test
public void testValidateWithCanonicalReference() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore);
ValueSet vs = new ValueSet();
vs.setId("MYVS");
vs.setUrl("http://myvs");
vs.getCompose()
.addInclude()
.setSystem("http://hl7.org/fhir/administrative-gender")
.addConcept(new ValueSet.ConceptReferenceComponent().setCode("male"))
.addConcept(new ValueSet.ConceptReferenceComponent().setCode("female"));
myValueSetDao.update(vs);
Questionnaire q = new Questionnaire();
q.setId("MYQ");
q.setUrl("http://myquestionnaire");
q.addItem()
.setLinkId("LINKID")
.setType(Questionnaire.QuestionnaireItemType.CHOICE)
.setAnswerValueSet("ValueSet/MYVS");
myQuestionnaireDao.update(q);
// Validate with matching code
QuestionnaireResponse qr = new QuestionnaireResponse();
qr.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
qr.setQuestionnaire("Questionnaire/MYQ");
qr.addItem()
.setLinkId("LINKID")
.addAnswer()
.setValue(new Coding().setSystem("http://hl7.org/fhir/administrative-gender").setCode("aaa"));
try {
MethodOutcome outcome = myQuestionnaireResponseDao.validate(qr, null, null, null, ValidationModeEnum.CREATE, null, mySrd);
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo));
fail();
} catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
String encoded = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
ourLog.info(encoded);
assertThat(encoded, containsString("is not in the options value set"));
}
}
@After
public void after() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning);
}
@Test @Test
public void testValidateForCreate() { public void testValidateForCreate() {
String methodName = "testValidateForCreate"; String methodName = "testValidateForCreate";
@ -344,11 +390,11 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test @Test
@Ignore @Ignore
public void testValidateNewQuestionnaireFormat() throws Exception { public void testValidateNewQuestionnaireFormat() throws Exception {
String input =IOUtils.toString(FhirResourceDaoR4ValidateTest.class.getResourceAsStream("/questionnaire_r4.xml")); String input = IOUtils.toString(FhirResourceDaoR4ValidateTest.class.getResourceAsStream("/questionnaire_r4.xml"));
try { try {
MethodOutcome results = myQuestionnaireDao.validate(null, null, input, EncodingEnum.XML, ValidationModeEnum.UPDATE, null, mySrd); MethodOutcome results = myQuestionnaireDao.validate(null, null, input, EncodingEnum.XML, ValidationModeEnum.UPDATE, null, mySrd);
OperationOutcome oo = (OperationOutcome) results.getOperationOutcome(); OperationOutcome oo = (OperationOutcome) results.getOperationOutcome();
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo)); ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo));
} catch (PreconditionFailedException e) { } catch (PreconditionFailedException e) {
// this is a failure of the test // this is a failure of the test
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome())); ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
@ -356,4 +402,9 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
} }
} }
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
} }

View File

@ -391,6 +391,50 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
} }
@Test
public void testCreateWithClientAssignedId() throws IOException {
// Create with client assigned ID
Patient p = new Patient();
p.setActive(true);
p.setId("AAA");
String encoded = myFhirCtx.newJsonParser().encodeResourceToString(p);
HttpPut httpPut = new HttpPut(ourServerBase + "/Patient/AAA");
httpPut.setEntity(new StringEntity(encoded, ContentType.parse("application/json+fhir")));
try (CloseableHttpResponse status = ourHttpClient.execute(httpPut)) {
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(status.getStatusLine().toString());
ourLog.info(responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("true"));
}
// Delete
HttpDelete httpDelete = new HttpDelete(ourServerBase + "/Patient/AAA");
try (CloseableHttpResponse status = ourHttpClient.execute(httpDelete)) {
assertEquals(200, status.getStatusLine().getStatusCode());
}
// Create it again
p = new Patient();
p.setActive(true);
p.setId("AAA");
encoded = myFhirCtx.newJsonParser().encodeResourceToString(p);
httpPut = new HttpPut(ourServerBase + "/Patient/AAA");
httpPut.setEntity(new StringEntity(encoded, ContentType.parse("application/json+fhir")));
try (CloseableHttpResponse status = ourHttpClient.execute(httpPut)) {
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(status.getStatusLine().toString());
ourLog.info(responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("true"));
}
}
@Before @Before

View File

@ -63,7 +63,6 @@ public class BaseController {
final String serverName = theRequest.getServerName(myConfig); final String serverName = theRequest.getServerName(myConfig);
final String apiKey = theRequest.getApiKey(theServletRequest, myConfig); final String apiKey = theRequest.getApiKey(theServletRequest, myConfig);
theModel.put("serverId", sanitizeInput(serverId)); theModel.put("serverId", sanitizeInput(serverId));
theModel.put("base", sanitizeInput(serverBase));
theModel.put("baseName", sanitizeInput(serverName)); theModel.put("baseName", sanitizeInput(serverName));
theModel.put("apiKey", sanitizeInput(apiKey)); theModel.put("apiKey", sanitizeInput(apiKey));
theModel.put("resourceName", sanitizeInput(defaultString(theRequest.getResource()))); theModel.put("resourceName", sanitizeInput(defaultString(theRequest.getResource())));
@ -72,6 +71,9 @@ public class BaseController {
theModel.put("_summary", sanitizeInput(theRequest.get_summary())); theModel.put("_summary", sanitizeInput(theRequest.get_summary()));
theModel.put("serverEntries", myConfig.getIdToServerName()); theModel.put("serverEntries", myConfig.getIdToServerName());
// doesn't need sanitizing
theModel.put("base", serverBase);
return loadAndAddConf(theServletRequest, theRequest, theModel); return loadAndAddConf(theServletRequest, theRequest, theModel);
} }

View File

@ -2371,10 +2371,14 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return null; return null;
} else { } else {
long t = System.nanoTime(); long t = System.nanoTime();
if (!Utilities.isAbsoluteUrl(reference)) ValueSet fr = context.fetchResource(ValueSet.class, reference);
reference = resolve(uri, reference); if (fr == null) {
ValueSet fr = context.fetchResource(ValueSet.class, reference); if (!Utilities.isAbsoluteUrl(reference)) {
txTime = txTime + (System.nanoTime() - t); reference = resolve(uri, reference);
fr = context.fetchResource(ValueSet.class, reference);
}
}
txTime = txTime + (System.nanoTime() - t);
return fr; return fr;
} }
} else } else

View File

@ -208,6 +208,11 @@
calling fetchCodeSystem() in order to reduce the work required by chain entries. Thanks to calling fetchCodeSystem() in order to reduce the work required by chain entries. Thanks to
Anders Havn for the suggestion! Anders Havn for the suggestion!
</action> </action>
<action type="fix" issue="1299">
In JPA server when updating a resource using a client assigned ID, if the resource was previously
deleted (meaning that the operation is actually a create), the server will now return
an HTTP 201 instead of an HTTP 200. Thanks to Mario Hyland for reporting!
</action>
</release> </release>
<release version="3.7.0" date="2019-02-06" description="Gale"> <release version="3.7.0" date="2019-02-06" description="Gale">
<action type="add"> <action type="add">