Allowing any client assigned ID throws ResourceNotFoundException when creating a CodeSystem (#3505)

* add test and potential fix

* add changelog

* fix

* add tests again

* oops. missed a file.

* clean up

* fix resolveResourcePersistentIds

* fix RESOURCE_PID constant

* format

* apply suggestion

* get R5 pid key

* better solution

Co-authored-by: olivia-you <olivia.you@smilecdr.com>
This commit is contained in:
Olivia You 2022-04-17 08:02:50 -04:00 committed by GitHub
parent 7dec2e334d
commit e0cc325294
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 9 deletions

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 3504
jira: SMILE-3958,SMILE-4048
title: "Previously, allowing any client assigned ID by setting `ClientIdStrategyEnum` to `ANY` threw an exception when
creating CodeSystem resources. This has been corrected."

View File

@ -120,7 +120,7 @@ public class IdHelperService implements IIdHelperService {
} }
/** /**
* Given a forced ID, convert it to it's Long value. Since you are allowed to use string IDs for resources, we need to * Given a forced ID, convert it to its Long value. Since you are allowed to use string IDs for resources, we need to
* convert those to the underlying Long values that are stored, for lookup and comparison purposes. * convert those to the underlying Long values that are stored, for lookup and comparison purposes.
* *
* @throws ResourceNotFoundException If the ID can not be found * @throws ResourceNotFoundException If the ID can not be found

View File

@ -160,10 +160,12 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate, theCreateNewHistoryEntry); ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate, theCreateNewHistoryEntry);
if (!retVal.isUnchangedInCurrentOperation()) { if (!retVal.isUnchangedInCurrentOperation()) {
CodeSystem cs = (CodeSystem) theResource; CodeSystem csR5 = (CodeSystem) theResource;
addPidToResource(theEntity, theResource);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded((org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_40_50.convertResource(cs, new BaseAdvisor_40_50(false)), (ResourceTable) theEntity); org.hl7.fhir.r4.model.CodeSystem cs = (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_40_50.convertResource(csR5, new BaseAdvisor_40_50(false));
addPidToResource(theEntity, cs);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, (ResourceTable) theEntity);
} }
return retVal; return retVal;

View File

@ -88,6 +88,7 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static ca.uhn.fhir.jpa.api.dao.IDao.RESOURCE_PID_KEY;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW; import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
@ -277,7 +278,9 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
if (theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.COMPLETE || theCodeSystem.getContent() == null || theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.NOTPRESENT) { if (theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.COMPLETE || theCodeSystem.getContent() == null || theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.NOTPRESENT) {
ourLog.info("CodeSystem {} has a status of {}, going to store concepts in terminology tables", theResourceEntity.getIdDt().getValue(), theCodeSystem.getContentElement().getValueAsString()); ourLog.info("CodeSystem {} has a status of {}, going to store concepts in terminology tables", theResourceEntity.getIdDt().getValue(), theCodeSystem.getContentElement().getValueAsString());
ResourcePersistentId codeSystemResourcePid = getCodeSystemResourcePid(theCodeSystem.getIdElement()); Long pid = (Long)theCodeSystem.getUserData(RESOURCE_PID_KEY);
assert pid != null;
ResourcePersistentId codeSystemResourcePid = new ResourcePersistentId(pid);
/* /*
* If this is a not-present codesystem and codesystem version already exists, we don't want to * If this is a not-present codesystem and codesystem version already exists, we don't want to
@ -559,10 +562,6 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
} }
private ResourcePersistentId getCodeSystemResourcePid(IIdType theIdType) {
return myIdHelperService.resolveResourcePersistentIds(RequestPartitionId.allPartitions(), theIdType.getResourceType(), theIdType.getIdPart());
}
private void persistChildren(TermConcept theConcept, TermCodeSystemVersion theCodeSystem, IdentityHashMap<TermConcept, Object> theConceptsStack, int theTotalConcepts) { private void persistChildren(TermConcept theConcept, TermCodeSystemVersion theCodeSystem, IdentityHashMap<TermConcept, Object> theConceptsStack, int theTotalConcepts) {
if (theConceptsStack.put(theConcept, PLACEHOLDER_OBJECT) != null) { if (theConceptsStack.put(theConcept, PLACEHOLDER_OBJECT) != null) {
return; return;

View File

@ -31,6 +31,7 @@ import org.apache.commons.lang3.time.DateUtils;
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.model.Bundle;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.DateType; import org.hl7.fhir.r4.model.DateType;
import org.hl7.fhir.r4.model.DecimalType; import org.hl7.fhir.r4.model.DecimalType;
@ -424,6 +425,28 @@ public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
} }
@Test
public void testCreateWithUuidServerResourceStrategy_AnyClientIdAllowed() {
myDaoConfig.setResourceServerIdStrategy(DaoConfig.IdStrategyEnum.UUID);
myDaoConfig.setResourceClientIdStrategy(DaoConfig.ClientIdStrategyEnum.ANY);
CodeSystem cs = new CodeSystem();
// alphanumeric ID
cs.setId("123a");
cs.setUrl("http://foo");
IIdType id = myCodeSystemDao.create(cs).getId();
cs = myCodeSystemDao.read(id);
assertEquals("http://foo", cs.getUrl());
// purely numeric ID
cs.setId("123");
cs.setUrl("http://fooCS");
id = myCodeSystemDao.update(cs).getId();
cs = myCodeSystemDao.read(id);
assertEquals("http://fooCS", cs.getUrl());
}
/** /**
* See #1352 * See #1352
*/ */