Merge pull request #2913 from hapifhir/rel_5_5_0

v5.5.0 Release branch merge-back.
This commit is contained in:
Tadgh 2021-08-23 14:53:40 -04:00 committed by GitHub
commit 75ff7557fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 600 additions and 333 deletions

View File

@ -51,7 +51,7 @@ public enum SearchContainedModeEnum {
myCode = theCode;
}
private String getCode() {
public String getCode() {
return myCode;
}

View File

@ -76,6 +76,7 @@ public enum VersionEnum {
V5_4_2,
V5_5_0,
V5_6_0
;
public static VersionEnum latestVersion() {

View File

@ -26,6 +26,7 @@ import org.apache.commons.cli.Options;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.QuoteMode;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.ConceptMap;
@ -42,7 +43,6 @@ import java.util.List;
import java.util.concurrent.ExecutionException;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
public class ExportConceptMapToCsvCommand extends AbstractImportExportCsvConceptMapCommand {
// TODO: Don't use qualified names for loggers in HAPI CLI.
@ -110,7 +110,7 @@ public class ExportConceptMapToCsvCommand extends AbstractImportExportCsvConcept
private void convertConceptMapToCsv(org.hl7.fhir.dstu3.model.ConceptMap theConceptMap) throws ExecutionException {
try {
convertConceptMapToCsv(convertConceptMap(theConceptMap));
convertConceptMapToCsv((ConceptMap) VersionConvertorFactory_30_40.convertResource(theConceptMap));
} catch (FHIRException fe) {
throw new ExecutionException(fe);
}

View File

@ -28,6 +28,7 @@ import org.apache.commons.cli.Options;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ConceptMap.ConceptMapGroupComponent;
@ -47,7 +48,6 @@ import java.util.concurrent.ExecutionException;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
public class ImportCsvToConceptMapCommand extends AbstractImportExportCsvConceptMapCommand {
// TODO: Don't use qualified names for loggers in HAPI CLI.
@ -152,7 +152,7 @@ public class ImportCsvToConceptMapCommand extends AbstractImportExportCsvConcept
private org.hl7.fhir.dstu3.model.ConceptMap convertCsvToConceptMapDstu3() throws ExecutionException {
try {
return convertConceptMap(convertCsvToConceptMapR4());
return (org.hl7.fhir.dstu3.model.ConceptMap) VersionConvertorFactory_30_40.convertResource(convertCsvToConceptMapR4());
} catch (FHIRException fe) {
throw new ExecutionException(fe);
}

View File

@ -29,11 +29,11 @@ import ca.uhn.fhir.rest.api.server.ResponseDetails;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
import org.hl7.fhir.converter.NullVersionConverterAdvisor30;
import org.hl7.fhir.converter.NullVersionConverterAdvisor40;
import org.hl7.fhir.convertors.VersionConvertor_10_30;
import org.hl7.fhir.convertors.VersionConvertor_10_40;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.converter.NullVersionConverterAdvisor10_30;
import org.hl7.fhir.converter.NullVersionConverterAdvisor10_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_30;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -42,9 +42,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.StringTokenizer;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.*;
/**
* <b>This is an experimental interceptor! Use with caution as
@ -58,12 +56,12 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class VersionedApiConverterInterceptor extends InterceptorAdapter {
private final FhirContext myCtxDstu2;
private final FhirContext myCtxDstu2Hl7Org;
private final NullVersionConverterAdvisor40 advisor40;
private final NullVersionConverterAdvisor30 advisor30;
private final NullVersionConverterAdvisor10_40 advisor40;
private final NullVersionConverterAdvisor10_30 advisor30;
public VersionedApiConverterInterceptor() {
advisor40 = new NullVersionConverterAdvisor40();
advisor30 = new NullVersionConverterAdvisor30();
advisor40 = new NullVersionConverterAdvisor10_40();
advisor30 = new NullVersionConverterAdvisor10_30();
myCtxDstu2 = FhirContext.forDstu2();
myCtxDstu2Hl7Org = FhirContext.forDstu2Hl7Org();
@ -104,17 +102,17 @@ public class VersionedApiConverterInterceptor extends InterceptorAdapter {
IBaseResource converted = null;
try {
if (wantVersion == FhirVersionEnum.R4 && haveVersion == FhirVersionEnum.DSTU3) {
converted = VersionConvertor_30_40.convertResource(toDstu3(responseResource), true);
converted = VersionConvertorFactory_30_40.convertResource(toDstu3(responseResource));
} else if (wantVersion == FhirVersionEnum.DSTU3 && haveVersion == FhirVersionEnum.R4) {
converted = VersionConvertor_30_40.convertResource(toR4(responseResource), true);
converted = VersionConvertorFactory_30_40.convertResource(toR4(responseResource));
} else if (wantVersion == FhirVersionEnum.DSTU2 && haveVersion == FhirVersionEnum.R4) {
converted = VersionConvertor_10_40.convertResource(toR4(responseResource), advisor40);
converted = VersionConvertorFactory_10_40.convertResource(toR4(responseResource), advisor40);
} else if (wantVersion == FhirVersionEnum.R4 && haveVersion == FhirVersionEnum.DSTU2) {
converted = VersionConvertor_10_40.convertResource(toDstu2(responseResource), advisor40);
converted = VersionConvertorFactory_10_40.convertResource(toDstu2(responseResource), advisor40);
} else if (wantVersion == FhirVersionEnum.DSTU2 && haveVersion == FhirVersionEnum.DSTU3) {
converted = VersionConvertor_10_30.convertResource(toDstu3(responseResource), advisor30);
converted = VersionConvertorFactory_10_30.convertResource(toDstu3(responseResource), advisor30);
} else if (wantVersion == FhirVersionEnum.DSTU3 && haveVersion == FhirVersionEnum.DSTU2) {
converted = VersionConvertor_10_30.convertResource(toDstu2(responseResource), advisor30);
converted = VersionConvertorFactory_10_30.convertResource(toDstu2(responseResource), advisor30);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);

View File

@ -20,8 +20,7 @@ package org.hl7.fhir.converter;
* #L%
*/
import org.hl7.fhir.convertors.advisors.VersionConvertorAdvisor30;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_30;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.ValueSet;
@ -31,7 +30,7 @@ import org.hl7.fhir.r5.model.FhirPublication;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class NullVersionConverterAdvisor30 implements VersionConvertorAdvisor30 {
public class NullVersionConverterAdvisor10_30 extends BaseAdvisor_10_30 {
@Nullable

View File

@ -20,8 +20,7 @@ package org.hl7.fhir.converter;
* #L%
*/
import org.hl7.fhir.convertors.advisors.VersionConvertorAdvisor40;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_40;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.CodeSystem;
@ -31,7 +30,7 @@ import org.hl7.fhir.r5.model.FhirPublication;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class NullVersionConverterAdvisor40 implements VersionConvertorAdvisor40 {
public class NullVersionConverterAdvisor10_40 extends BaseAdvisor_10_40 {
@Nullable

View File

@ -20,8 +20,8 @@ package org.hl7.fhir.converter;
* #L%
*/
import org.hl7.fhir.convertors.advisors.VersionConvertorAdvisor50;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_50;
import org.hl7.fhir.convertors.conv10_50.VersionConvertor_10_50;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.CodeSystem;
@ -32,7 +32,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.IdentityHashMap;
public class NullVersionConverterAdvisor50 implements VersionConvertorAdvisor50 {
public class NullVersionConverterAdvisor10_50 extends BaseAdvisor_10_50 {
private IdentityHashMap<ValueSet, CodeSystem> myCodeSystems = new IdentityHashMap<>();

View File

@ -2,7 +2,7 @@ package org.hl7.fhir.converter;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.hl7.fhir.convertors.VersionConvertor_10_30;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_30;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.dstu2.model.Resource;
@ -19,7 +19,7 @@ public class VersionConvertor_10_30Test {
org.hl7.fhir.dstu2.model.Observation input = new org.hl7.fhir.dstu2.model.Observation();
input.setEncounter(new org.hl7.fhir.dstu2.model.Reference("Encounter/123"));
org.hl7.fhir.dstu3.model.Observation output = (Observation) VersionConvertor_10_30.convertResource(input);
org.hl7.fhir.dstu3.model.Observation output = (Observation) VersionConvertorFactory_10_30.convertResource(input);
String context = output.getContext().getReference();
assertEquals("Encounter/123", context);
@ -52,7 +52,7 @@ public class VersionConvertor_10_30Test {
Specimen.SpecimenContainerComponent specimenContainerComponent = new Specimen.SpecimenContainerComponent();
specimenContainerComponent.getExtension().add(new Extension().setUrl("some_url").setValue(new StringType("some_value")));
spec.setContainer(Collections.singletonList(specimenContainerComponent));
Resource resource = VersionConvertor_10_30.convertResource(spec);
Resource resource = VersionConvertorFactory_10_30.convertResource(spec);
}

View File

@ -2,7 +2,7 @@ package org.hl7.fhir.converter;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.hl7.fhir.convertors.VersionConvertor_14_30;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_30;
import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.exceptions.FHIRException;
import org.junit.jupiter.api.Test;
@ -15,7 +15,7 @@ public class VersionConvertor_14_30Test {
org.hl7.fhir.dstu2016may.model.Questionnaire input = new org.hl7.fhir.dstu2016may.model.Questionnaire();
input.setTitle("My title");
org.hl7.fhir.dstu3.model.Questionnaire output = (Questionnaire) VersionConvertor_14_30.convertResource(input);
org.hl7.fhir.dstu3.model.Questionnaire output = (Questionnaire) VersionConvertorFactory_14_30.convertResource(input);
String context = output.getTitle();
assertEquals("My title", context);

View File

@ -20,36 +20,38 @@ package ca.uhn.hapi.fhir.docs;
* #L%
*/
import org.hl7.fhir.convertors.conv10_30.Observation10_30;
import org.hl7.fhir.convertors.conv14_30.Questionnaire14_30;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_30;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_30;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.exceptions.FHIRException;
public class ConverterExamples {
@SuppressWarnings("unused")
public void c1020() throws FHIRException {
//START SNIPPET: 1020
//START SNIPPET: 1020
// Create an input resource to convert
org.hl7.fhir.dstu2.model.Observation input = new org.hl7.fhir.dstu2.model.Observation();
input.setEncounter(new org.hl7.fhir.dstu2.model.Reference("Encounter/123"));
// Convert the resource
org.hl7.fhir.dstu3.model.Observation output = Observation10_30.convertObservation(input);
org.hl7.fhir.dstu3.model.Observation output = (Observation) VersionConvertorFactory_10_30.convertResource(input);
String context = output.getContext().getReference();
//END SNIPPET: 1020
//END SNIPPET: 1020
}
@SuppressWarnings("unused")
public void c1420() throws FHIRException {
//START SNIPPET: 1420
//START SNIPPET: 1420
// Create a resource to convert
org.hl7.fhir.dstu2016may.model.Questionnaire input = new org.hl7.fhir.dstu2016may.model.Questionnaire();
input.setTitle("My title");
// Convert the resource
org.hl7.fhir.dstu3.model.Questionnaire output = Questionnaire14_30.convertQuestionnaire(input);
org.hl7.fhir.dstu3.model.Questionnaire output = (Questionnaire) VersionConvertorFactory_14_30.convertResource(input);
String context = output.getTitle();
//END SNIPPET: 1420
//END SNIPPET: 1420
}
}

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 2868
jira: SMILE-1153
title: "Fixed a bug in transaction bundle processing, specifically for bundles which contained both a conditional create, and a resource which relied on this conditional create as a reference.
This would cause the referring resource to generate a contained resource instead of appropriately referencing the existing patient."

View File

@ -0,0 +1,5 @@
---
type: add
issue: 2871
title: "Modified the behaviour of the `:mdm` param qualifier. Previously, it used to only resolve IDs if the resource ID was a source resource.
Now, MDM expansion will work if you pass it the ID of a golden resource instead."

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 2887
jira: SMILE-2896
title: "Fixed a bug where the search results cache was ignoring the value of `_contained` parameter when assigning a cache key.
This was causing queries run in a short period of time to return wrong cached results if one query used `_contained=true` and the other did not."

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.cache;
* #L%
*/
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
@ -28,6 +29,7 @@ import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.QueryChunker;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -36,12 +38,15 @@ import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static org.slf4j.LoggerFactory.getLogger;
/**
* This service builds a map of resource ids to versions based on a SearchParameterMap.
* It is used by the in-memory resource-version cache to detect when resource versions have been changed by remote processes.
*/
@Service
public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc {
private static final Logger ourLog = getLogger(ResourceVersionSvcDaoImpl.class);
@Autowired
DaoRegistry myDaoRegistry;
@ -53,7 +58,11 @@ public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc {
public ResourceVersionMap getVersionMap(String theResourceName, SearchParameterMap theSearchParamMap) {
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceName);
List<Long> matchingIds = dao.searchForIds(theSearchParamMap, new SystemRequestDetails()).stream()
if (ourLog.isDebugEnabled()) {
ourLog.debug("About to retrieve version map for resource type: {}", theResourceName);
}
List<Long> matchingIds = dao.searchForIds(theSearchParamMap, new SystemRequestDetails().setRequestPartitionId(RequestPartitionId.allPartitions())).stream()
.map(ResourcePersistentId::getIdAsLong)
.collect(Collectors.toList());

View File

@ -94,6 +94,7 @@ import com.google.common.collect.Sets;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBase;
@ -1162,10 +1163,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
validateResourceForStorage((T) theResource, entity);
}
}
String resourceType = myContext.getResourceType(theResource);
if (isNotBlank(entity.getResourceType()) && !entity.getResourceType().equals(resourceType)) {
throw new UnprocessableEntityException(
"Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
if (!StringUtils.isBlank(entity.getResourceType())) {
validateIncomingResourceTypeMatchesExisting(theResource, entity);
}
}
@ -1206,6 +1205,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
if (thePerformIndexing || ((ResourceTable) theEntity).getVersion() == 1) {
newParams = new ResourceIndexedSearchParams();
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, theTransactionDetails, entity, theResource, existingParams, theRequest, thePerformIndexing);
changed = populateResourceIntoEntity(theTransactionDetails, theRequest, theResource, entity, true);
@ -1415,6 +1415,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
return entity;
}
private void validateIncomingResourceTypeMatchesExisting(IBaseResource theResource, ResourceTable entity) {
String resourceType = myContext.getResourceType(theResource);
if (!resourceType.equals(entity.getResourceType())) {
throw new UnprocessableEntityException(
"Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
}
}
@Override
public ResourceTable updateInternal(RequestDetails theRequestDetails, T theResource, boolean thePerformIndexing, boolean theForceUpdateVersion,
IBasePersistedResource theEntity, IIdType theResourceId, IBaseResource theOldResource, TransactionDetails theTransactionDetails) {

View File

@ -90,6 +90,7 @@ import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -803,6 +804,7 @@ public abstract class BaseTransactionProcessor {
String matchUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextReqEntry);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
outcome = resourceDao.create(res, matchUrl, false, theTransactionDetails, theRequest);
res.setId(outcome.getId());
if (nextResourceId != null) {
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequest);
}
@ -1023,13 +1025,9 @@ public abstract class BaseTransactionProcessor {
for (IIdType next : theAllIds) {
IIdType replacement = theIdSubstitutions.get(next);
if (replacement == null) {
continue;
if (replacement != null && !replacement.equals(next)) {
ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
}
if (replacement.equals(next)) {
continue;
}
ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
}
ListMultimap<Pointcut, HookParams> deferredBroadcastEvents = theTransactionDetails.endAcceptingDeferredInterceptorBroadcasts();
@ -1112,7 +1110,6 @@ public abstract class BaseTransactionProcessor {
}
deferredIndexesForAutoVersioning.put(nextOutcome, referencesToAutoVersion);
}
}
// If we have any resources we'll be auto-versioning, index these next

View File

@ -22,22 +22,14 @@ package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.model.dstu2.resource.SearchParameter;
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.SearchParamTypeEnum;
import ca.uhn.fhir.model.primitive.BoundCodeDt;
import org.hl7.fhir.convertors.conv10_40.SearchParameter10_40;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_40;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@ -79,7 +71,7 @@ public class FhirResourceDaoSearchParameterDstu2 extends BaseHapiFhirResourceDao
String encoded = getContext().newJsonParser().encodeResourceToString(theResource);
org.hl7.fhir.dstu2.model.SearchParameter hl7Org = myDstu2Hl7OrgContext.newJsonParser().parseResource(org.hl7.fhir.dstu2.model.SearchParameter.class, encoded);
org.hl7.fhir.r4.model.SearchParameter convertedSp = SearchParameter10_40.convertSearchParameter(hl7Org);
org.hl7.fhir.r4.model.SearchParameter convertedSp = (org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_10_40.convertResource(hl7Org, new BaseAdvisor_10_40(false));
if (isBlank(convertedSp.getExpression()) && isNotBlank(hl7Org.getXpath())) {
convertedSp.setExpression(hl7Org.getXpath());
}

View File

@ -46,6 +46,7 @@ import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -61,10 +62,12 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -218,18 +221,9 @@ public class TransactionProcessor extends BaseTransactionProcessor {
IQueryParameterType param = andList.get(0).get(0);
if (param instanceof TokenParam) {
TokenParam tokenParam = (TokenParam) param;
Predicate hashPredicate = null;
if (isNotBlank(tokenParam.getValue()) && isNotBlank(tokenParam.getSystem())) {
next.myHashSystemAndValue = ResourceIndexedSearchParamToken.calculateHashSystemAndValue(myPartitionSettings, requestPartitionId, next.myResourceDefinition.getName(), next.myMatchUrlSearchMap.keySet().iterator().next(), tokenParam.getSystem(), tokenParam.getValue());
hashPredicate = cb.equal(from.get("myHashSystemAndValue").as(Long.class), next.myHashSystemAndValue);
} else if (isNotBlank(tokenParam.getValue())) {
next.myHashValue = ResourceIndexedSearchParamToken.calculateHashValue(myPartitionSettings, requestPartitionId, next.myResourceDefinition.getName(), next.myMatchUrlSearchMap.keySet().iterator().next(), tokenParam.getValue());
hashPredicate = cb.equal(from.get("myHashValue").as(Long.class), next.myHashValue);
}
Predicate hashPredicate = buildHashPredicateFromTokenParam((TokenParam)param, requestPartitionId, cb, from, next);
if (hashPredicate != null) {
if (myPartitionSettings.isPartitioningEnabled() && !myPartitionSettings.isIncludePartitionInSearchHashes()) {
if (requestPartitionId.isDefaultPartition()) {
Predicate partitionIdCriteria = cb.isNull(from.get("myPartitionIdValue").as(Integer.class));
@ -250,35 +244,26 @@ public class TransactionProcessor extends BaseTransactionProcessor {
if (orPredicates.size() > 1) {
cq.where(cb.or(orPredicates.toArray(EMPTY_PREDICATE_ARRAY)));
Map<Long, MatchUrlToResolve> hashToSearchMap = buildHashToSearchMap(searchParameterMapsToResolve);
TypedQuery<ResourceIndexedSearchParamToken> query = myEntityManager.createQuery(cq);
List<ResourceIndexedSearchParamToken> results = query.getResultList();
for (ResourceIndexedSearchParamToken nextResult : results) {
for (MatchUrlToResolve nextSearchParameterMap : searchParameterMapsToResolve) {
if (nextSearchParameterMap.myHashSystemAndValue != null && nextSearchParameterMap.myHashSystemAndValue.equals(nextResult.getHashSystemAndValue())) {
idsToPreFetch.add(nextResult.getResourcePid());
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, nextSearchParameterMap.myResourceDefinition.getName(), nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
nextSearchParameterMap.myResolved = true;
}
if (nextSearchParameterMap.myHashValue != null && nextSearchParameterMap.myHashValue.equals(nextResult.getHashValue())) {
idsToPreFetch.add(nextResult.getResourcePid());
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, nextSearchParameterMap.myResourceDefinition.getName(), nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
nextSearchParameterMap.myResolved = true;
}
Optional<MatchUrlToResolve> matchedSearch = Optional.ofNullable(hashToSearchMap.get(nextResult.getHashSystemAndValue()));
if (!matchedSearch.isPresent()) {
matchedSearch = Optional.ofNullable(hashToSearchMap.get(nextResult.getHashValue()));
}
matchedSearch.ifPresent(matchUrlToResolve -> setSearchToResolvedAndPrefetchFoundResourcePid(theTransactionDetails, idsToPreFetch, nextResult, matchUrlToResolve));
}
for (MatchUrlToResolve nextSearchParameterMap : searchParameterMapsToResolve) {
//For each SP Map which did not return a result, tag it as not found.
searchParameterMapsToResolve.stream()
// No matches
if (!nextSearchParameterMap.myResolved) {
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, TransactionDetails.NOT_FOUND);
}
}
.filter(match -> !match.myResolved)
.forEach(match -> {
ourLog.warn("Was unable to match url {} from database", match.myRequestUrl);
theTransactionDetails.addResolvedMatchUrl(match.myRequestUrl, TransactionDetails.NOT_FOUND);
});
}
}
@ -320,6 +305,45 @@ public class TransactionProcessor extends BaseTransactionProcessor {
return super.doTransactionWriteOperations(theRequest, theActionName, theTransactionDetails, theAllIds, theIdSubstitutions, theIdToPersistedOutcome, theResponse, theOriginalRequestOrder, theEntries, theTransactionStopWatch);
}
/**
* Given a token parameter, build the query predicate based on its hash. Uses system and value if both are available, otherwise just value.
* If neither are available, it returns null.
*/
@Nullable
private Predicate buildHashPredicateFromTokenParam(TokenParam theTokenParam, RequestPartitionId theRequestPartitionId, CriteriaBuilder cb, Root<ResourceIndexedSearchParamToken> from, MatchUrlToResolve theMatchUrl) {
Predicate hashPredicate = null;
if (isNotBlank(theTokenParam.getValue()) && isNotBlank(theTokenParam.getSystem())) {
theMatchUrl.myHashSystemAndValue = ResourceIndexedSearchParamToken.calculateHashSystemAndValue(myPartitionSettings, theRequestPartitionId, theMatchUrl.myResourceDefinition.getName(), theMatchUrl.myMatchUrlSearchMap.keySet().iterator().next(), theTokenParam.getSystem(), theTokenParam.getValue());
hashPredicate = cb.equal(from.get("myHashSystemAndValue").as(Long.class), theMatchUrl.myHashSystemAndValue);
} else if (isNotBlank(theTokenParam.getValue())) {
theMatchUrl.myHashValue = ResourceIndexedSearchParamToken.calculateHashValue(myPartitionSettings, theRequestPartitionId, theMatchUrl.myResourceDefinition.getName(), theMatchUrl.myMatchUrlSearchMap.keySet().iterator().next(), theTokenParam.getValue());
hashPredicate = cb.equal(from.get("myHashValue").as(Long.class), theMatchUrl.myHashValue);
}
return hashPredicate;
}
private Map<Long, MatchUrlToResolve> buildHashToSearchMap(List<MatchUrlToResolve> searchParameterMapsToResolve) {
Map<Long, MatchUrlToResolve> hashToSearch = new HashMap<>();
//Build a lookup map so we don't have to iterate over the searches repeatedly.
for (MatchUrlToResolve nextSearchParameterMap : searchParameterMapsToResolve) {
if (nextSearchParameterMap.myHashSystemAndValue != null) {
hashToSearch.put(nextSearchParameterMap.myHashSystemAndValue, nextSearchParameterMap);
}
if (nextSearchParameterMap.myHashValue!= null) {
hashToSearch.put(nextSearchParameterMap.myHashValue, nextSearchParameterMap);
}
}
return hashToSearch;
}
private void setSearchToResolvedAndPrefetchFoundResourcePid(TransactionDetails theTransactionDetails, List<Long> idsToPreFetch, ResourceIndexedSearchParamToken nextResult, MatchUrlToResolve nextSearchParameterMap) {
ourLog.warn("Matched url {} from database", nextSearchParameterMap.myRequestUrl);
idsToPreFetch.add(nextResult.getResourcePid());
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, nextSearchParameterMap.myResourceDefinition.getName(), nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
nextSearchParameterMap.setResolved(true);
}
private List<ResourceTable> preFetchIndexes(List<Long> ids, String typeDesc, String fieldName) {
TypedQuery<ResourceTable> query = myEntityManager.createQuery("FROM ResourceTable r LEFT JOIN FETCH r." + fieldName + " WHERE r.myId IN ( :IDS )", ResourceTable.class);
query.setParameter("IDS", ids);
@ -379,5 +403,8 @@ public class TransactionProcessor extends BaseTransactionProcessor {
myMatchUrlSearchMap = theMatchUrlSearchMap;
myResourceDefinition = theResourceDefinition;
}
public void setResolved(boolean theResolved) {
myResolved = theResolved;
}
}
}

View File

@ -67,4 +67,7 @@ public interface IMdmLinkDao extends JpaRepository<MdmLink, Long> {
"AND ml.myMatchResult=:matchResult")
List<MdmPidTuple> expandPidsBySourcePidAndMatchResult(@Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
@Query("SELECT ml.myGoldenResourcePid as goldenPid, ml.mySourcePid as sourcePid FROM MdmLink ml WHERE ml.myGoldenResourcePid = :goldenPid and ml.myMatchResult = :matchResult")
List<MdmPidTuple> expandPidsByGoldenResourcePidAndMatchResult(@Param("goldenPid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
}

View File

@ -27,16 +27,18 @@ import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.util.LogicUtil;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
@ -53,7 +55,6 @@ import java.util.List;
import java.util.Set;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
@Transactional
public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
@ -146,7 +147,7 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
CodeSystem csDstu3 = (CodeSystem) theResource;
org.hl7.fhir.r4.model.CodeSystem cs = convertCodeSystem(csDstu3);
org.hl7.fhir.r4.model.CodeSystem cs = (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_30_40.convertResource(csDstu3, new BaseAdvisor_30_40(false));
addPidToResource(theEntity, cs);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, (ResourceTable) theEntity);
@ -157,9 +158,9 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
}
@Override
public CodeValidationResult validateCode(IIdType theCodeSystemId, IPrimitiveType<String> theCodeSystemUrl, IPrimitiveType<String> theVersion, IPrimitiveType<String> theCode,
IPrimitiveType<String> theDisplay, Coding theCoding, CodeableConcept theCodeableConcept, RequestDetails theRequestDetails) {
public CodeValidationResult validateCode(IIdType theCodeSystemId, IPrimitiveType<String> theCodeSystemUrl, IPrimitiveType<String> theVersion, IPrimitiveType<String> theCode,
IPrimitiveType<String> theDisplay, Coding theCoding, CodeableConcept theCodeableConcept, RequestDetails theRequestDetails) {
throw new UnsupportedOperationException();
}
}

View File

@ -20,9 +20,9 @@ package ca.uhn.fhir.jpa.dao.dstu3;
* #L%
*/
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
@ -30,6 +30,8 @@ import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -37,8 +39,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao<ConceptMap> implements IFhirResourceDaoConceptMap<ConceptMap> {
@Autowired
private ITermConceptMappingSvc myTermConceptMappingSvc;
@ -53,7 +53,6 @@ public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao<Conc
}
@Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
@ -63,7 +62,7 @@ public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao<Conc
if (retVal.getDeleted() == null) {
try {
ConceptMap conceptMap = (ConceptMap) theResource;
org.hl7.fhir.r4.model.ConceptMap converted = convertConceptMap(conceptMap);
org.hl7.fhir.r4.model.ConceptMap converted = (org.hl7.fhir.r4.model.ConceptMap) VersionConvertorFactory_30_40.convertResource(conceptMap, new BaseAdvisor_30_40(false));
myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, converted);
} catch (FHIRException fe) {
throw new InternalErrorException(fe);

View File

@ -1,20 +1,15 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import org.hl7.fhir.convertors.conv10_40.SearchParameter10_40;
import org.hl7.fhir.convertors.conv30_40.SearchParameter30_40;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Enumerations;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.SearchParameter;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/*
* #%L
* HAPI FHIR JPA Server
@ -69,7 +64,9 @@ public class FhirResourceDaoSearchParameterDstu3 extends BaseHapiFhirResourceDao
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave);
FhirResourceDaoSearchParameterR4.validateSearchParam(SearchParameter30_40.convertSearchParameter(theResource), getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
FhirResourceDaoSearchParameterR4.validateSearchParam(
(org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_30_40.convertResource(theResource, new BaseAdvisor_30_40(false)),
getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
}
}

View File

@ -30,7 +30,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.convertors.conv30_40.ValueSet30_40;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.ValueSet;
@ -42,7 +43,6 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
import java.util.Date;
import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull;
import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSet;
public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao<ValueSet> implements IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> {
@ -54,15 +54,15 @@ public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao<ValueS
@Override
public org.hl7.fhir.dstu3.model.ValueSet expand(org.hl7.fhir.dstu3.model.ValueSet theSource, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalInput = ValueSet30_40.convertValueSet(theSource);
org.hl7.fhir.r4.model.ValueSet canonicalInput = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource(theSource, new BaseAdvisor_30_40(false));
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, canonicalInput);
return ValueSet30_40.convertValueSet(canonicalOutput);
return (ValueSet) VersionConvertorFactory_30_40.convertResource(canonicalOutput, new BaseAdvisor_30_40(false));
}
@Override
public org.hl7.fhir.dstu3.model.ValueSet expandByIdentifier(String theUri, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, theUri);
return ValueSet30_40.convertValueSet(canonicalOutput);
return (ValueSet) VersionConvertorFactory_30_40.convertResource(canonicalOutput, new BaseAdvisor_30_40(false));
}
@Override
@ -86,7 +86,7 @@ public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao<ValueS
if (retVal.getDeleted() == null) {
try {
ValueSet valueSet = (ValueSet) theResource;
org.hl7.fhir.r4.model.ValueSet converted = convertValueSet(valueSet);
org.hl7.fhir.r4.model.ValueSet converted = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource(valueSet, new BaseAdvisor_30_40(false));
myTerminologySvc.storeTermValueSet(retVal, converted);
} catch (FHIRException fe) {
throw new InternalErrorException(fe);

View File

@ -55,7 +55,7 @@ import com.google.common.annotations.VisibleForTesting;
import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

View File

@ -25,15 +25,13 @@ import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -82,14 +80,50 @@ public class MdmLinkExpandSvc {
public Set<String> expandMdmBySourceResourcePid(Long theSourceResourcePid) {
ourLog.debug("About to expand source resource with PID {}", theSourceResourcePid);
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH);
return flattenPidTuplesToSet(theSourceResourcePid, goldenPidSourcePidTuples);
}
/**
* Given a PID of a golden resource, perform MDM expansion and return all the resource IDs of all resources that are
* MDM-Matched to this golden resource.
*
* @param theGoldenResourcePid The PID of the golden resource to MDM-Expand.
* @return A set of strings representing the FHIR ids of the expanded resources.
*/
public Set<String> expandMdmByGoldenResourceId(Long theGoldenResourcePid) {
ourLog.debug("About to expand golden resource with PID {}", theGoldenResourcePid);
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsByGoldenResourcePidAndMatchResult(theGoldenResourcePid, MdmMatchResultEnum.MATCH);
return flattenPidTuplesToSet(theGoldenResourcePid, goldenPidSourcePidTuples);
}
/**
* Given a resource ID of a golden resource, perform MDM expansion and return all the resource IDs of all resources that are
* MDM-Matched to this golden resource.
*
* @param theGoldenResourcePid The resource ID of the golden resource to MDM-Expand.
* @return A set of strings representing the FHIR ids of the expanded resources.
*/
public Set<String> expandMdmByGoldenResourcePid(Long theGoldenResourcePid) {
ourLog.debug("About to expand golden resource with PID {}", theGoldenResourcePid);
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsByGoldenResourcePidAndMatchResult(theGoldenResourcePid, MdmMatchResultEnum.MATCH);
return flattenPidTuplesToSet(theGoldenResourcePid, goldenPidSourcePidTuples);
}
public Set<String> expandMdmByGoldenResourceId(IdDt theId) {
ourLog.debug("About to expand golden resource with golden resource id {}", theId);
Long pidOrThrowException = myIdHelperService.getPidOrThrowException(theId);
return expandMdmByGoldenResourcePid(pidOrThrowException);
}
@Nonnull
private Set<String> flattenPidTuplesToSet(Long initialPid, List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples) {
Set<Long> flattenedPids = new HashSet<>();
goldenPidSourcePidTuples.forEach(tuple -> {
flattenedPids.add(tuple.getSourcePid());
flattenedPids.add(tuple.getGoldenPid());
});
Set<String> resourceIds = myIdHelperService.translatePidsToFhirResourceIds(flattenedPids);
ourLog.debug("Pid {} has been expanded to [{}]", theSourceResourcePid, String.join(",", resourceIds));
ourLog.debug("Pid {} has been expanded to [{}]", initialPid, String.join(",", resourceIds));
return resourceIds;
}
}

View File

@ -38,6 +38,8 @@ import ca.uhn.fhir.jpa.util.LogicUtil;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
@ -149,7 +151,7 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
CodeSystem cs = (CodeSystem) theResource;
addPidToResource(theEntity, theResource);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(cs), (ResourceTable) theEntity);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded((org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_40_50.convertResource(cs, new BaseAdvisor_40_50(false)), (ResourceTable) theEntity);
}
return retVal;

View File

@ -29,6 +29,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.ConceptMap;
import org.springframework.beans.factory.annotation.Autowired;
@ -56,7 +58,8 @@ public class FhirResourceDaoConceptMapR5 extends BaseHapiFhirResourceDao<Concept
if (retVal.getDeleted() == null) {
ConceptMap conceptMap = (ConceptMap) theResource;
myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, org.hl7.fhir.convertors.conv40_50.ConceptMap40_50.convertConceptMap(conceptMap));
myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal,
(org.hl7.fhir.r4.model.ConceptMap) VersionConvertorFactory_40_50.convertResource(conceptMap, new BaseAdvisor_40_50(false)));
} else {
myTermConceptMappingSvc.deleteConceptMapAndChildren(retVal);
}

View File

@ -1,19 +1,15 @@
package ca.uhn.fhir.jpa.dao.r5;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import org.hl7.fhir.convertors.conv30_40.SearchParameter30_40;
import org.hl7.fhir.convertors.conv40_50.SearchParameter40_50;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.r5.model.SearchParameter;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/*
* #%L
* HAPI FHIR JPA Server
@ -68,7 +64,9 @@ public class FhirResourceDaoSearchParameterR5 extends BaseHapiFhirResourceDao<Se
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave);
FhirResourceDaoSearchParameterR4.validateSearchParam(SearchParameter40_50.convertSearchParameter(theResource), getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
FhirResourceDaoSearchParameterR4.validateSearchParam(
(org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_40_50.convertResource(theResource, new BaseAdvisor_40_50(false)),
getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
}

View File

@ -28,7 +28,8 @@ import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.convertors.conv40_50.ValueSet40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
@ -52,14 +53,14 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao<ValueSet>
@Override
public ValueSet expandByIdentifier(String theUri, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, theUri);
return ValueSet40_50.convertValueSet(canonicalOutput);
return (ValueSet) VersionConvertorFactory_40_50.convertResource(canonicalOutput, new BaseAdvisor_40_50(false));
}
@Override
public ValueSet expand(ValueSet theSource, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalInput = ValueSet40_50.convertValueSet(theSource);
org.hl7.fhir.r4.model.ValueSet canonicalInput = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(theSource, new BaseAdvisor_40_50(false));
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, canonicalInput);
return ValueSet40_50.convertValueSet(canonicalOutput);
return (ValueSet) VersionConvertorFactory_40_50.convertResource(canonicalOutput, new BaseAdvisor_40_50(false));
}
@Override
@ -82,7 +83,7 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao<ValueSet>
if (getConfig().isPreExpandValueSets() && !retVal.isUnchangedInCurrentOperation()) {
if (retVal.getDeleted() == null) {
ValueSet valueSet = (ValueSet) theResource;
myTerminologySvc.storeTermValueSet(retVal, org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSet));
myTerminologySvc.storeTermValueSet(retVal, (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSet, new BaseAdvisor_40_50(false)));
} else {
myTerminologySvc.deleteValueSetAndChildren(retVal);
}

View File

@ -76,8 +76,16 @@ public class MdmSearchExpandingInterceptor {
if (iQueryParameterType instanceof ReferenceParam) {
ReferenceParam refParam = (ReferenceParam) iQueryParameterType;
if (refParam.isMdmExpand()) {
ourLog.debug("Found a reference parameter to expand: {}", refParam.toString());
ourLog.debug("Found a reference parameter to expand: {}", refParam);
//First, attempt to expand as a source resource.
Set<String> expandedResourceIds = myMdmLinkExpandSvc.expandMdmBySourceResourceId(new IdDt(refParam.getValue()));
// If we failed, attempt to expand as a golden resource
if (expandedResourceIds.isEmpty()) {
expandedResourceIds = myMdmLinkExpandSvc.expandMdmByGoldenResourceId(new IdDt(refParam.getValue()));
}
//Rebuild the search param list.
if (!expandedResourceIds.isEmpty()) {
ourLog.debug("Parameter has been expanded to: {}", String.join(", ", expandedResourceIds));
toRemove.add(refParam);

View File

@ -40,6 +40,10 @@ import ca.uhn.fhir.util.ValidateUtil;
import com.google.common.base.Charsets;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.ICompositeType;
@ -58,10 +62,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
import static org.apache.commons.lang3.StringUtils.*;
public class TerminologyUploaderProvider extends BaseJpaProvider {
@ -308,10 +309,10 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
CodeSystem nextCodeSystem;
switch (getContext().getVersion().getVersion()) {
case DSTU3:
nextCodeSystem = convertCodeSystem((org.hl7.fhir.dstu3.model.CodeSystem) theCodeSystem);
nextCodeSystem = (CodeSystem) VersionConvertorFactory_30_40.convertResource((org.hl7.fhir.dstu3.model.CodeSystem) theCodeSystem, new BaseAdvisor_30_40(false));
break;
case R5:
nextCodeSystem = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem((org.hl7.fhir.r5.model.CodeSystem) theCodeSystem);
nextCodeSystem = (CodeSystem) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r5.model.CodeSystem) theCodeSystem, new BaseAdvisor_40_50(false));
break;
default:
nextCodeSystem = (CodeSystem) theCodeSystem;

View File

@ -20,9 +20,9 @@ package ca.uhn.fhir.jpa.provider.dstu3;
* #L%
*/
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
import ca.uhn.fhir.rest.annotation.IdParam;
@ -31,7 +31,8 @@ import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.CodeableConcept;
@ -45,8 +46,6 @@ import org.hl7.fhir.exceptions.FHIRException;
import javax.servlet.http.HttpServletRequest;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderDstu3<ConceptMap> {
@Operation(name = JpaConstants.OPERATION_TRANSLATE, idempotent = true, returnParameters = {
@OperationParam(name = "result", type = BooleanType.class, min = 1, max = 1),
@ -82,7 +81,7 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
&& theSourceValueSet.hasValue();
boolean haveSourceCoding = theSourceCoding != null
&& theSourceCoding.hasCode();
boolean haveSourceCodeableConcept= theSourceCodeableConcept != null
boolean haveSourceCodeableConcept = theSourceCodeableConcept != null
&& theSourceCodeableConcept.hasCoding()
&& theSourceCodeableConcept.getCodingFirstRep().hasCode();
boolean haveTargetValueSet = theTargetValueSet != null
@ -100,46 +99,46 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
TranslationRequest translationRequest = new TranslationRequest();
try {
if (haveUrl) {
translationRequest.setUrl(VersionConvertor_30_40.convertUri(theUrl));
translationRequest.setUrl((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theUrl, new BaseAdvisor_30_40(false)));
}
if (haveConceptMapVersion) {
translationRequest.setConceptMapVersion(VersionConvertor_30_40.convertString(theConceptMapVersion));
translationRequest.setConceptMapVersion((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_30_40.convertType(theConceptMapVersion, new BaseAdvisor_30_40(false)));
}
// Convert from DSTU3 to R4
if (haveSourceCode) {
translationRequest.getCodeableConcept().addCoding().setCodeElement(VersionConvertor_30_40.convertCode(theSourceCode));
translationRequest.getCodeableConcept().addCoding().setCodeElement((org.hl7.fhir.r4.model.CodeType) VersionConvertorFactory_30_40.convertType(theSourceCode, new BaseAdvisor_30_40(false)));
if (haveSourceCodeSystem) {
translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement(VersionConvertor_30_40.convertUri(theSourceCodeSystem));
translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theSourceCodeSystem, new BaseAdvisor_30_40(false)));
}
if (haveSourceCodeSystemVersion) {
translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement(VersionConvertor_30_40.convertString(theSourceCodeSystemVersion));
translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_30_40.convertType(theSourceCodeSystemVersion, new BaseAdvisor_30_40(false)));
}
} else if (haveSourceCoding) {
translationRequest.getCodeableConcept().addCoding(VersionConvertor_30_40.convertCoding(theSourceCoding));
translationRequest.getCodeableConcept().addCoding((org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_30_40.convertType(theSourceCoding, new BaseAdvisor_30_40(false)));
} else {
translationRequest.setCodeableConcept(VersionConvertor_30_40.convertCodeableConcept(theSourceCodeableConcept));
translationRequest.setCodeableConcept((org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_30_40.convertType(theSourceCodeableConcept, new BaseAdvisor_30_40(false)));
}
if (haveSourceValueSet) {
translationRequest.setSource(VersionConvertor_30_40.convertUri(theSourceValueSet));
translationRequest.setSource((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theSourceValueSet, new BaseAdvisor_30_40(false)));
}
if (haveTargetValueSet) {
translationRequest.setTarget(VersionConvertor_30_40.convertUri(theTargetValueSet));
translationRequest.setTarget((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theTargetValueSet, new BaseAdvisor_30_40(false)));
}
if (haveTargetCodeSystem) {
translationRequest.setTargetSystem(VersionConvertor_30_40.convertUri(theTargetCodeSystem));
translationRequest.setTargetSystem((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theTargetCodeSystem, new BaseAdvisor_30_40(false)));
}
if (haveReverse) {
translationRequest.setReverse(VersionConvertor_30_40.convertBoolean(theReverse));
translationRequest.setReverse((org.hl7.fhir.r4.model.BooleanType) VersionConvertorFactory_30_40.convertType(theReverse, new BaseAdvisor_30_40(false)));
}
if (haveId) {
@ -155,7 +154,7 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
TranslateConceptResults result = dao.translate(translationRequest, theRequestDetails);
// Convert from R4 to DSTU3
return convertParameters(TermConceptMappingSvcImpl.toParameters(result));
return (Parameters) VersionConvertorFactory_30_40.convertResource(TermConceptMappingSvcImpl.toParameters(result), new BaseAdvisor_30_40(false));
} catch (FHIRException fe) {
throw new InternalErrorException(fe);
} finally {

View File

@ -24,8 +24,6 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import org.hl7.fhir.instance.model.api.IAnyResource;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> {
public JpaResourceProviderDstu3() {

View File

@ -24,7 +24,6 @@ import java.util.Map.Entry;
import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
/*
* #%L

View File

@ -20,9 +20,9 @@ package ca.uhn.fhir.jpa.provider.r5;
* #L%
*/
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
import ca.uhn.fhir.rest.annotation.IdParam;
@ -30,7 +30,8 @@ import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.CodeableConcept;
@ -52,7 +53,7 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
HttpServletRequest theServletRequest,
@IdParam(optional = true) IdType theId,
@OperationParam(name = "url", min = 0, max = 1) UriType theUrl,
@OperationParam(name = "conceptMapVersion", min = 0, max = 1) StringType theConceptMapVersion,
@OperationParam(name = "conceptMapVersion", min = 0, max = 1) StringType theConceptMapVersion,
@OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode,
@OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem,
@OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion,
@ -78,7 +79,7 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
&& theSourceValueSet.hasValue();
boolean haveSourceCoding = theSourceCoding != null
&& theSourceCoding.hasCode();
boolean haveSourceCodeableConcept= theSourceCodeableConcept != null
boolean haveSourceCodeableConcept = theSourceCodeableConcept != null
&& theSourceCodeableConcept.hasCoding()
&& theSourceCodeableConcept.getCodingFirstRep().hasCode();
boolean haveTargetValueSet = theTargetValueSet != null
@ -97,43 +98,44 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
TranslationRequest translationRequest = new TranslationRequest();
if (haveUrl) {
translationRequest.setUrl(VersionConvertor_40_50.convertUri(theUrl));
translationRequest.setUrl((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theUrl, new BaseAdvisor_40_50(false)));
}
if (haveConceptMapVersion) {
translationRequest.setConceptMapVersion(VersionConvertor_40_50.convertString(theConceptMapVersion));
translationRequest.setConceptMapVersion((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_40_50.convertType(theConceptMapVersion, new BaseAdvisor_40_50(false)));
}
if (haveSourceCode) {
translationRequest.getCodeableConcept().addCoding().setCodeElement(VersionConvertor_40_50.convertCode(theSourceCode));
translationRequest.getCodeableConcept().addCoding().setCodeElement((org.hl7.fhir.r4.model.CodeType) VersionConvertorFactory_40_50.convertType(theSourceCode, new BaseAdvisor_40_50(false)));
if (haveSourceCodeSystem) {
translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement(VersionConvertor_40_50.convertUri(theSourceCodeSystem));
translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theSourceCodeSystem, new BaseAdvisor_40_50(false)));
}
if (haveSourceCodeSystemVersion) {
translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement(VersionConvertor_40_50.convertString(theSourceCodeSystemVersion));
translationRequest.getCodeableConcept().getCodingFirstRep()
.setVersionElement((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_40_50.convertType(theSourceCodeSystemVersion, new BaseAdvisor_40_50(false)));
}
} else if (haveSourceCoding) {
translationRequest.getCodeableConcept().addCoding(VersionConvertor_40_50.convertCoding(theSourceCoding));
translationRequest.getCodeableConcept().addCoding((org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_40_50.convertType(theSourceCoding, new BaseAdvisor_40_50(false)));
} else {
translationRequest.setCodeableConcept(VersionConvertor_40_50.convertCodeableConcept(theSourceCodeableConcept));
translationRequest.setCodeableConcept((org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_40_50.convertType(theSourceCodeableConcept, new BaseAdvisor_40_50(false)));
}
if (haveSourceValueSet) {
translationRequest.setSource(VersionConvertor_40_50.convertUri(theSourceValueSet));
translationRequest.setSource((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theSourceValueSet, new BaseAdvisor_40_50(false)));
}
if (haveTargetValueSet) {
translationRequest.setTarget(VersionConvertor_40_50.convertUri(theTargetValueSet));
translationRequest.setTarget((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theTargetValueSet, new BaseAdvisor_40_50(false)));
}
if (haveTargetCodeSystem) {
translationRequest.setTargetSystem(VersionConvertor_40_50.convertUri(theTargetCodeSystem));
translationRequest.setTargetSystem((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theTargetCodeSystem, new BaseAdvisor_40_50(false)));
}
if (haveReverse) {
translationRequest.setReverse(VersionConvertor_40_50.convertBoolean(theReverse));
translationRequest.setReverse((org.hl7.fhir.r4.model.BooleanType) VersionConvertorFactory_40_50.convertType(theReverse, new BaseAdvisor_40_50(false)));
}
if (haveId) {
@ -145,7 +147,7 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
IFhirResourceDaoConceptMap<ConceptMap> dao = (IFhirResourceDaoConceptMap<ConceptMap>) getDao();
TranslateConceptResults result = dao.translate(translationRequest, theRequestDetails);
org.hl7.fhir.r4.model.Parameters parameters = TermConceptMappingSvcImpl.toParameters(result);
return org.hl7.fhir.convertors.conv40_50.Parameters40_50.convertParameters(parameters);
return (Parameters) VersionConvertorFactory_40_50.convertResource(parameters, new BaseAdvisor_40_50(false));
} finally {
endRequest(theServletRequest);
}

View File

@ -42,7 +42,7 @@ import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.r4.model.InstantType;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -9,8 +9,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.ValidateUtil;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.convertors.conv30_40.CodeSystem30_40;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
@ -25,8 +25,6 @@ import org.springframework.transaction.PlatformTransactionManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSet;
/*
* #%L
* HAPI FHIR JPA Server
@ -67,7 +65,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = toCanonicalValueSet(theValueSetToExpand);
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions, valueSetToExpandR4);
return new ValueSetExpansionOutcome(convertValueSet(expandedR4), null);
return new ValueSetExpansionOutcome(VersionConvertorFactory_30_40.convertResource(expandedR4, new BaseAdvisor_30_40(false)), null);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@ -81,7 +79,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = toCanonicalValueSet(valueSetToExpand);
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions, valueSetToExpandR4);
return convertValueSet(expandedR4);
return VersionConvertorFactory_30_40.convertResource(expandedR4, new BaseAdvisor_30_40(false));
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@ -90,31 +88,31 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
@Override
protected org.hl7.fhir.r4.model.ValueSet toCanonicalValueSet(IBaseResource theValueSet) throws FHIRException {
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = convertValueSet((ValueSet) theValueSet);
valueSetToExpandR4 = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource((ValueSet) theValueSet, new BaseAdvisor_30_40(false));
return valueSetToExpandR4;
}
@Override
protected org.hl7.fhir.r4.model.CodeSystem toCanonicalCodeSystem(IBaseResource theCodeSystem) {
return CodeSystem30_40.convertCodeSystem((CodeSystem)theCodeSystem);
return (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_30_40.convertResource((CodeSystem)theCodeSystem, new BaseAdvisor_30_40(false));
}
@Override
@Nullable
protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseDatatype theCoding) {
return VersionConvertor_30_40.convertCoding((org.hl7.fhir.dstu3.model.Coding) theCoding);
return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_30_40.convertType((Coding) theCoding, new BaseAdvisor_30_40(false));
}
@Override
@Nullable
protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseCoding theCoding) {
return VersionConvertor_30_40.convertCoding((org.hl7.fhir.dstu3.model.Coding) theCoding);
return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_30_40.convertType((org.hl7.fhir.dstu3.model.Coding) theCoding, new BaseAdvisor_30_40(false));
}
@Override
@Nullable
protected org.hl7.fhir.r4.model.CodeableConcept toCanonicalCodeableConcept(IBaseDatatype theCoding) {
return VersionConvertor_30_40.convertCodeableConcept((org.hl7.fhir.dstu3.model.CodeableConcept) theCoding);
return (org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_30_40.convertType((CodeableConcept) theCoding, new BaseAdvisor_30_40(false));
}
@ -160,7 +158,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
public IValidationSupport.CodeValidationResult validateCodeIsInPreExpandedValueSet(ConceptValidationOptions theOptions, IBaseResource theValueSet, String theSystem, String theCode, String theDisplay, IBaseDatatype theCoding, IBaseDatatype theCodeableConcept) {
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet, "ValueSet must not be null");
ValueSet valueSet = (ValueSet) theValueSet;
org.hl7.fhir.r4.model.ValueSet valueSetR4 = convertValueSet(valueSet);
org.hl7.fhir.r4.model.ValueSet valueSetR4 = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource(valueSet, new BaseAdvisor_30_40(false));
Coding coding = (Coding) theCoding;
org.hl7.fhir.r4.model.Coding codingR4 = null;
@ -184,7 +182,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
public boolean isValueSetPreExpandedForCodeValidation(IBaseResource theValueSet) {
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet, "ValueSet must not be null");
ValueSet valueSet = (ValueSet) theValueSet;
org.hl7.fhir.r4.model.ValueSet valueSetR4 = convertValueSet(valueSet);
org.hl7.fhir.r4.model.ValueSet valueSetR4 = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource(valueSet, new BaseAdvisor_30_40(false));
return super.isValueSetPreExpandedForCodeValidation(valueSetR4);
}
}

View File

@ -10,8 +10,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR5;
import ca.uhn.fhir.jpa.term.ex.ExpansionTooCostlyException;
import ca.uhn.fhir.util.ValidateUtil;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.convertors.conv40_50.CodeSystem40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -19,8 +19,6 @@ import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.utilities.TerminologyServiceOptions;
import org.hl7.fhir.utilities.validation.ValidationOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
@ -59,15 +57,16 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
@Transactional(dontRollbackOn = {ExpansionTooCostlyException.class})
public ValueSetExpansionOutcome expandValueSet(ValidationSupportContext theValidationSupportContext, ValueSetExpansionOptions theExpansionOptions, @Nonnull IBaseResource theValueSetToExpand) {
ValueSet valueSetToExpand = (ValueSet) theValueSetToExpand;
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions, org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetToExpand));
return new ValueSetExpansionOutcome(org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(expandedR4));
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions,
(org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSetToExpand, new BaseAdvisor_40_50(false)));
return new ValueSetExpansionOutcome(VersionConvertorFactory_40_50.convertResource(expandedR4, new BaseAdvisor_40_50(false)));
}
@Override
public IBaseResource expandValueSet(ValueSetExpansionOptions theExpansionOptions, IBaseResource theInput) {
org.hl7.fhir.r4.model.ValueSet valueSetToExpand = toCanonicalValueSet(theInput);
org.hl7.fhir.r4.model.ValueSet valueSetR4 = super.expandValueSet(theExpansionOptions, valueSetToExpand);
return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetR4);
return VersionConvertorFactory_40_50.convertResource(valueSetR4, new BaseAdvisor_40_50(false));
}
@Override
@ -79,7 +78,7 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
@Override
protected org.hl7.fhir.r4.model.ValueSet getValueSetFromResourceTable(ResourceTable theResourceTable) {
ValueSet valueSetR5 = myDaoRegistry.getResourceDao("ValueSet").toResource(ValueSet.class, theResourceTable, null, false);
return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetR5);
return (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSetR5, new BaseAdvisor_40_50(false));
}
@Override
@ -110,30 +109,30 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
@Override
@Nullable
protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseDatatype theCoding) {
return VersionConvertor_40_50.convertCoding((Coding) theCoding);
return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_40_50.convertType((Coding) theCoding, new BaseAdvisor_40_50(false));
}
@Override
@Nullable
protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseCoding theCoding) {
return VersionConvertor_40_50.convertCoding((Coding) theCoding);
return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_40_50.convertType((Coding) theCoding, new BaseAdvisor_40_50(false));
}
@Override
@Nullable
protected org.hl7.fhir.r4.model.CodeableConcept toCanonicalCodeableConcept(IBaseDatatype theCoding) {
return VersionConvertor_40_50.convertCodeableConcept((CodeableConcept) theCoding);
return (org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_40_50.convertType((CodeableConcept) theCoding, new BaseAdvisor_40_50(false));
}
@Override
protected org.hl7.fhir.r4.model.ValueSet toCanonicalValueSet(IBaseResource theValueSet) throws org.hl7.fhir.exceptions.FHIRException {
return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet((ValueSet) theValueSet);
return (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource((ValueSet) theValueSet, new BaseAdvisor_40_50(false));
}
@Override
protected org.hl7.fhir.r4.model.CodeSystem toCanonicalCodeSystem(IBaseResource theCodeSystem) {
return CodeSystem40_50.convertCodeSystem((CodeSystem) theCodeSystem);
return (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_40_50.convertResource((CodeSystem) theCodeSystem, new BaseAdvisor_40_50(false));
}
@Override

View File

@ -25,6 +25,8 @@ import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.UrlUtil;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.dstu3.model.ValueSet;
@ -36,9 +38,6 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSet;
public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
@ -56,7 +55,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
/**
* Initialize the beans that are used by this service.
*
* <p>
* Note: There is a circular dependency here where the CodeSystem DAO
* needs terminology services, and the term services need the CodeSystem DAO.
* So we look these up in a refresh event instead of just autowiring them
@ -70,11 +69,11 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
myConceptMapResourceDao = (IFhirResourceDao<ConceptMap>) myAppCtx.getBean("myConceptMapDaoDstu3");
}
@Override
@Override
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
CodeSystem resourceToStore;
try {
resourceToStore = convertCodeSystem(theCodeSystemResource);
resourceToStore = (CodeSystem) VersionConvertorFactory_30_40.convertResource(theCodeSystemResource, new BaseAdvisor_30_40(false));
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@ -91,7 +90,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) {
ConceptMap resourceToStore;
try {
resourceToStore = convertConceptMap(theConceptMap);
resourceToStore = (ConceptMap) VersionConvertorFactory_30_40.convertResource(theConceptMap, new BaseAdvisor_30_40(false));
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@ -107,7 +106,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
ValueSet valueSetDstu3;
try {
valueSetDstu3 = convertValueSet(theValueSet);
valueSetDstu3 = (ValueSet) VersionConvertorFactory_30_40.convertResource(theValueSet, new BaseAdvisor_30_40(false));
} catch (FHIRException e) {
throw new InternalErrorException(e);
}

View File

@ -24,6 +24,8 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.util.UrlUtil;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.ConceptMap;
@ -63,7 +65,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
validateCodeSystemForStorage(theCodeSystemResource);
CodeSystem codeSystemR4 = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(theCodeSystemResource);
CodeSystem codeSystemR4 = (CodeSystem) VersionConvertorFactory_40_50.convertResource(theCodeSystemResource, new BaseAdvisor_40_50(false));
if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) {
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
return myCodeSystemResourceDao.update(codeSystemR4, matchUrl, theRequestDetails).getId();
@ -75,7 +77,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
@Override
public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) {
ConceptMap conceptMapR4 = org.hl7.fhir.convertors.conv40_50.ConceptMap40_50.convertConceptMap(theConceptMap);
ConceptMap conceptMapR4 = (ConceptMap) VersionConvertorFactory_40_50.convertResource(theConceptMap, new BaseAdvisor_40_50(false));
if (isBlank(theConceptMap.getIdElement().getIdPart())) {
String matchUrl = "ConceptMap?url=" + UrlUtil.escapeUrlParam(theConceptMap.getUrl());
@ -88,7 +90,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
@Override
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
ValueSet valueSetR4 = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(theValueSet);
ValueSet valueSetR4 = (ValueSet) VersionConvertorFactory_40_50.convertResource(theValueSet, new BaseAdvisor_40_50(false));
if (isBlank(theValueSet.getIdElement().getIdPart())) {
String matchUrl = "ValueSet?url=" + UrlUtil.escapeUrlParam(theValueSet.getUrl());

View File

@ -27,7 +27,9 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import org.hl7.fhir.common.hapi.validation.validator.VersionSpecificWorkerContextWrapper;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r5.elementmodel.Element;
@ -39,6 +41,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Locale;
public class ValidatorResourceFetcher implements IResourceValidator.IValidatorResourceFetcher {
@ -60,10 +65,8 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
myVersionSpecificCOntextWrapper = VersionSpecificWorkerContextWrapper.newVersionSpecificWorkerContextWrapper(myValidationSupport);
}
@Override
public Element fetch(Object appContext, String theUrl) throws FHIRException {
public Element fetch(IResourceValidator iResourceValidator, Object appContext, String theUrl) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
IdType id = new IdType(theUrl);
String resourceType = id.getResourceType();
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(resourceType);
@ -83,7 +86,8 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
}
@Override
public IResourceValidator.ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url) {
public IResourceValidator.ReferenceValidationPolicy validationPolicy(IResourceValidator iResourceValidator,
Object appContext, String path, String url) {
int slashIdx = url.indexOf("/");
if (slashIdx > 0 && myFhirContext.getResourceTypes().contains(url.substring(0, slashIdx))) {
return myValidationSettings.getLocalReferenceValidationDefaultPolicy();
@ -93,12 +97,12 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
}
@Override
public boolean resolveURL(Object appContext, String path, String url, String type) throws FHIRException {
public boolean resolveURL(IResourceValidator iResourceValidator, Object o, String s, String s1, String s2) throws IOException, FHIRException {
return true;
}
@Override
public byte[] fetchRaw(String url) {
public byte[] fetchRaw(IResourceValidator iResourceValidator, String s) throws MalformedURLException, IOException {
throw new UnsupportedOperationException();
}
@ -109,13 +113,12 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
}
@Override
public CanonicalResource fetchCanonicalResource(String url) {
throw new UnsupportedOperationException();
public CanonicalResource fetchCanonicalResource(IResourceValidator iResourceValidator, String s) throws URISyntaxException {
return null;
}
@Override
public boolean fetchesCanonicalResource(String url) {
public boolean fetchesCanonicalResource(IResourceValidator iResourceValidator, String s) {
return false;
}
}

View File

@ -78,7 +78,8 @@ public class FhirResourceDaoValueSetDstu2Test extends BaseJpaDstu2Test {
CodingDt coding = null;
CodeableConceptDt codeableConcept = null;
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd);
assertFalse(result.isOk());
//TODO JA, from what I read, this _should_ pass, but this was flipped to false in a previous commit.
assertTrue(result.isOk());
}
@Test

View File

@ -38,7 +38,6 @@ import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
@ -53,10 +52,13 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.io.IOUtils;
import org.hibernate.search.mapper.orm.Search;
import org.hibernate.search.mapper.orm.session.SearchSession;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.AllergyIntolerance;
import org.hl7.fhir.dstu3.model.Appointment;
import org.hl7.fhir.dstu3.model.AuditEvent;
@ -125,7 +127,6 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
import static org.junit.jupiter.api.Assertions.fail;
@ExtendWith(SpringExtension.class)
@ -378,7 +379,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@BeforeEach
public void beforeFlushFT() {
runInTransaction(() -> {
SearchSession searchSession = Search.session(myEntityManager);
SearchSession searchSession = Search.session(myEntityManager);
searchSession.workspace(ResourceTable.class).purge();
// searchSession.workspace(ResourceIndexedSearchParamString.class).purge();
searchSession.indexingPlan().execute();
@ -462,7 +463,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
*/
public static ConceptMap createConceptMap() {
try {
return convertConceptMap(BaseJpaR4Test.createConceptMap());
return (ConceptMap) VersionConvertorFactory_30_40.convertResource(BaseJpaR4Test.createConceptMap(), new BaseAdvisor_30_40(false));
} catch (FHIRException fe) {
throw new InternalErrorException(fe);
}

View File

@ -779,7 +779,5 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test {
assertEquals(observationId.getValue(), resources.get(0).getIdElement().getValue());
assertEquals(patientId.withVersion("2").getValue(), resources.get(1).getIdElement().getValue());
}
}
}

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
@ -63,6 +64,7 @@ import org.hl7.fhir.r4.model.Practitioner;
import org.hl7.fhir.r4.model.Quantity;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.Task;
import org.hl7.fhir.r4.model.ValueSet;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@ -1002,6 +1004,23 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
}
@Test
public void testTransactionNoContainedRedux() throws IOException {
//Pre-create the patient, which will cause the ifNoneExist to prevent a new creation during bundle transaction
Patient patient = loadResourceFromClasspath(Patient.class, "/r4/preexisting-patient.json");
myPatientDao.create(patient);
//Post the Bundle containing a conditional POST with an identical patient from the above resource.
Bundle request = loadResourceFromClasspath(Bundle.class, "/r4/transaction-no-contained-2.json");
Bundle outcome = mySystemDao.transaction(mySrd, request);
IdType taskId = new IdType(outcome.getEntry().get(0).getResponse().getLocation());
Task task = myTaskDao.read(taskId, mySrd);
assertThat(task.getBasedOn().get(0).getReference(), matchesPattern("Patient/[0-9]+"));
}
@Test
public void testTransactionNoContained() throws IOException {

View File

@ -10,10 +10,8 @@ import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl;
import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.lang3.time.DateUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -40,7 +38,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test {
private ISearchCoordinatorSvc mySearchCoordinator;
@Autowired
private ISearchCacheSvc myDataaseCacheSvc;
private ISearchCacheSvc myDatabaseCacheSvc;
@AfterEach
public void after() {
@ -92,7 +90,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test {
assertEquals(30, mySearchResultDao.count());
});
myDataaseCacheSvc.pollForStaleSearchesAndDeleteThem();
myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem();
runInTransaction(()->{
// We should delete up to 10, but 3 don't get deleted since they have too many results to delete in one pass
assertEquals(13, mySearchDao.count());
@ -101,7 +99,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test {
assertEquals(15, mySearchResultDao.count());
});
myDataaseCacheSvc.pollForStaleSearchesAndDeleteThem();
myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem();
runInTransaction(()->{
// Once again we attempt to delete 10, but the first 3 don't get deleted and still remain
// (total is 6 because 3 weren't deleted, and they blocked another 3 that might have been)
@ -110,7 +108,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test {
assertEquals(0, mySearchResultDao.count());
});
myDataaseCacheSvc.pollForStaleSearchesAndDeleteThem();
myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem();
runInTransaction(()->{
assertEquals(0, mySearchDao.count());
assertEquals(0, mySearchDao.countDeleted());

View File

@ -1,8 +1,10 @@
package ca.uhn.fhir.jpa.provider;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.rest.api.SearchContainedModeEnum;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
@ -41,6 +43,24 @@ public class SearchParameterMapTest {
assertEquals("?birthdate=ge2001&birthdate=lt2002&name=bouvier,simpson&name=homer,jay&name:exact=ZZZ?", UrlUtil.unescape(queryString));
}
@Test
public void testContainedParameterIsIncludedInNormalizedString() {
SearchParameterMap map = new SearchParameterMap();
map.add("name", new StringParam("Smith"));
map.setSearchContainedMode(SearchContainedModeEnum.TRUE);
String containedQueryString = map.toNormalizedQueryString(ourCtx);
SearchParameterMap uncontainedMap = new SearchParameterMap();
uncontainedMap.add("name", new StringParam("Smith"));
uncontainedMap.setSearchContainedMode(SearchContainedModeEnum.FALSE);
String uncontainedQueryString = uncontainedMap.toNormalizedQueryString(ourCtx);
ourLog.info(containedQueryString);
ourLog.info(uncontainedQueryString);
assertNotEquals(containedQueryString, uncontainedQueryString);
}
@Test
public void testToQueryStringEmpty() {
SearchParameterMap map = new SearchParameterMap();

View File

@ -284,7 +284,6 @@ public class ResourceProviderR4SearchContainedTest extends BaseResourceProviderR
assertEquals(0L, oids.size());
}
@Test
public void testContainedSearchByNumber() throws Exception {
@ -975,6 +974,11 @@ public class ResourceProviderR4SearchContainedTest extends BaseResourceProviderR
assertEquals(1L, oids.size());
assertThat(oids, contains(oid1.getValue()));
}
//See https://github.com/hapifhir/hapi-fhir/issues/2887
@Test
public void testContainedResourceParameterIsUsedInCache() {
}

View File

@ -0,0 +1,13 @@
{
"resourceType": "Patient",
"identifier": [
{
"system": "https://example.org/fhir/memberidentifier",
"value": "12345670"
},
{
"system": "https://example.org/fhir/memberuniqueidentifier",
"value": "12345670TT"
}
]
}

View File

@ -0,0 +1,49 @@
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"fullUrl": "urn:uuid:1f3b9e25-fd45-4342-a82b-7ca5755923bb",
"resource": {
"resourceType": "Task",
"language": "en-US",
"identifier": [
{
"system": "https://example.org/fhir/taskidentifier",
"value": "101019"
}
],
"basedOn": [
{
"reference": "urn:uuid:47c6d106-3441-41c0-8a2c-054ad9897ced"
}
]
},
"request": {
"method": "PUT",
"url": "/Task?identifier\u003dhttps%3A%2F%2Fexample.org%2Ffhir%2Ftaskidentifier|101019"
}
},
{
"fullUrl": "urn:uuid:47c6d106-3441-41c0-8a2c-054ad9897ced",
"resource": {
"resourceType": "Patient",
"identifier": [
{
"system": "https://example.org/fhir/memberidentifier",
"value": "12345670"
},
{
"system": "https://example.org/fhir/memberuniqueidentifier",
"value": "12345670TT"
}
]
},
"request": {
"method": "POST",
"url": "/Patient",
"ifNoneExist": "Patient?identifier\u003dhttps%3A%2F%2Fexample.org%2Ffhir%2Fmemberuniqueidentifier|12345670TT"
}
}
]
}

View File

@ -62,7 +62,7 @@ import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Practitioner;
import org.hl7.fhir.r4.model.Reference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;

View File

@ -2,14 +2,18 @@ package ca.uhn.fhir.jpa.mdm.interceptor;
import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.mdm.api.MdmConstants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import org.elasticsearch.common.collect.Set;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Patient;
@ -21,6 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@ -73,6 +79,19 @@ public class MdmSearchExpandingInterceptorIT extends BaseMdmR4Test {
myDaoConfig.setAllowMdmExpansion(true);
search = myObservationDao.search(searchParameterMap);
assertThat(search.size(), is(equalTo(4)));
List<MdmLink> all = myMdmLinkDao.findAll();
Long goldenPid = all.get(0).getGoldenResourcePid();
IIdType goldenId = myIdHelperService.translatePidIdToForcedId(myFhirContext, "Patient", new ResourcePersistentId(goldenPid));
//Verify that expansion by the golden resource id resolves down to everything its links have.
SearchParameterMap goldenSpMap = new SearchParameterMap();
goldenSpMap.setLoadSynchronous(true);
ReferenceOrListParam goldenReferenceOrListParam = new ReferenceOrListParam();
goldenReferenceOrListParam.addOr(new ReferenceParam(goldenId).setMdmExpand(true));
goldenSpMap.add(Observation.SP_SUBJECT, goldenReferenceOrListParam);
search = myObservationDao.search(goldenSpMap);
assertThat(search.size(), is(equalTo(4)));
}
@Test

View File

@ -511,6 +511,15 @@ public class SearchParameterMap implements Serializable {
b.append(getSearchTotalMode().getCode());
}
//Contained mode
//For some reason, instead of null here, we default to false. That said, ommitting it is identical to setting it to false.
if (getSearchContainedMode() != SearchContainedModeEnum.FALSE) {
addUrlParamSeparator(b);
b.append(Constants.PARAM_CONTAINED);
b.append("=");
b.append(getSearchContainedMode().getCode());
}
if (b.length() == 0) {
b.append('?');
}

View File

@ -78,6 +78,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
@ -964,6 +965,18 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
return retVal;
}
/**
* Helper function to determine if a set of SPs for a resource uses a resolve as part of its fhir path.
*/
private boolean anySearchParameterUsesResolve(Collection<RuntimeSearchParam> searchParams, RestSearchParameterTypeEnum theSearchParamType) {
return searchParams.stream()
.filter(param -> param.getParamType() != theSearchParamType)
.map(RuntimeSearchParam::getPath)
.filter(Objects::nonNull)
.anyMatch(path-> path.contains("resolve"));
}
/**
* HAPI FHIR Reference objects (e.g. {@link org.hl7.fhir.r4.model.Reference}) can hold references either by text
* (e.g. "#3") or by resource (e.g. "new Reference(patientInstance)"). The FHIRPath evaluator only understands the
@ -974,17 +987,12 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
* if we think there's actually a chance
*/
private void cleanUpContainedResourceReferences(IBaseResource theResource, RestSearchParameterTypeEnum theSearchParamType, Collection<RuntimeSearchParam> searchParams) {
boolean havePathWithResolveExpression = myModelConfig.isIndexOnContainedResources();
for (RuntimeSearchParam nextSpDef : searchParams) {
if (nextSpDef.getParamType() != theSearchParamType) {
continue;
}
if (defaultString(nextSpDef.getPath()).contains("resolve")) {
havePathWithResolveExpression = true;
break;
}
}
boolean havePathWithResolveExpression =
myModelConfig.isIndexOnContainedResources()
|| anySearchParameterUsesResolve(searchParams, theSearchParamType);
if (havePathWithResolveExpression) {
//TODO GGG/JA: At this point, if the Task.basedOn.reference.resource does _not_ have an ID, we will attempt to contain it internally. Wild
myContext.newTerser().containResources(theResource, FhirTerser.OptionsEnum.MODIFY_RESOURCE, FhirTerser.OptionsEnum.STORE_AND_REUSE_RESULTS);
}
}

View File

@ -57,8 +57,8 @@ import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.oas.models.tags.Tag;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
@ -78,7 +78,6 @@ import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.cache.AlwaysValidCacheEntryValidity;
import org.thymeleaf.cache.ICacheEntryValidity;
import org.thymeleaf.cache.NonCacheableCacheEntryValidity;
import org.thymeleaf.context.IExpressionContext;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.linkbuilder.AbstractLinkBuilder;
@ -909,9 +908,9 @@ public class OpenApiInterceptor {
private static <T extends Resource> T toCanonicalVersion(IBaseResource theNonCanonical) {
IBaseResource canonical;
if (theNonCanonical instanceof org.hl7.fhir.dstu3.model.Resource) {
canonical = VersionConvertor_30_40.convertResource((org.hl7.fhir.dstu3.model.Resource) theNonCanonical, true);
canonical = VersionConvertorFactory_30_40.convertResource((org.hl7.fhir.dstu3.model.Resource) theNonCanonical);
} else if (theNonCanonical instanceof org.hl7.fhir.r5.model.Resource) {
canonical = VersionConvertor_40_50.convertResource((org.hl7.fhir.r5.model.Resource) theNonCanonical);
canonical = VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r5.model.Resource) theNonCanonical);
} else {
canonical = theNonCanonical;
}

View File

@ -27,10 +27,10 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.ParametersUtil;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.jetbrains.annotations.Nullable;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersInvalidException;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.List;

View File

@ -29,10 +29,10 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.ParametersUtil;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.jetbrains.annotations.Nullable;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersInvalidException;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

View File

@ -398,8 +398,8 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
}
@Override
public void cachePackage(PackageVersion packageDetails, List<PackageVersion> dependencies) {
throw new UnsupportedOperationException();
public void cachePackage(PackageDetails packageDetails, List<PackageVersion> list) {
}
@Override
@ -442,6 +442,16 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
throw new UnsupportedOperationException();
}
@Override
public boolean hasPackage(PackageVersion packageVersion) {
return false;
}
@Override
public PackageDetails getPackage(PackageVersion packageVersion) {
return null;
}
@Override
public int getClientRetryCount() {
throw new UnsupportedOperationException();
@ -457,6 +467,11 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
return null;
}
@Override
public PackageVersion getPackageForUrl(String s) {
return null;
}
public static ConceptValidationOptions convertConceptValidationOptions(ValidationOptions theOptions) {
ConceptValidationOptions retVal = new ConceptValidationOptions();
if (theOptions.isGuessSystem()) {

View File

@ -15,8 +15,10 @@ import org.apache.commons.lang3.Validate;
import org.fhir.ucum.UcumEssenceService;
import org.fhir.ucum.UcumException;
import org.hl7.fhir.common.hapi.validation.validator.VersionSpecificWorkerContextWrapper;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.dstu2.model.ValueSet;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CodeSystem;
@ -381,13 +383,13 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
case DSTU2_1:
return null;
case DSTU3:
normalized = VersionConvertor_30_40.convertResource(retVal, false);
normalized = VersionConvertorFactory_30_40.convertResource(retVal, new BaseAdvisor_30_40(false));
break;
case R4:
normalized = retVal;
break;
case R5:
normalized = VersionConvertor_40_50.convertResource(retVal);
normalized = VersionConvertorFactory_40_50.convertResource(retVal, new BaseAdvisor_40_50(false));
break;
}

View File

@ -9,11 +9,12 @@ import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.util.FhirVersionIndependentConcept;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.convertors.conv10_50.ValueSet10_50;
import org.hl7.fhir.convertors.conv30_50.CodeSystem30_50;
import org.hl7.fhir.convertors.conv30_50.ValueSet30_50;
import org.hl7.fhir.convertors.conv40_50.CodeSystem40_50;
import org.hl7.fhir.convertors.conv40_50.ValueSet40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.dstu2.model.ValueSet;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
@ -67,15 +68,15 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
IBaseResource expansion;
switch (myCtx.getVersion().getVersion()) {
case DSTU2_HL7ORG: {
expansion = ValueSet10_50.convertValueSet(expansionR5);
expansion = VersionConvertorFactory_10_50.convertResource(expansionR5, new BaseAdvisor_10_50(false));
break;
}
case DSTU3: {
expansion = ValueSet30_50.convertValueSet(expansionR5);
expansion = VersionConvertorFactory_30_50.convertResource(expansionR5, new BaseAdvisor_30_50(false));
break;
}
case R4: {
expansion = ValueSet40_50.convertValueSet(expansionR5);
expansion = VersionConvertorFactory_40_50.convertResource(expansionR5, new BaseAdvisor_40_50(false));
break;
}
case R5: {
@ -358,10 +359,10 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
};
Function<String, org.hl7.fhir.r5.model.ValueSet> valueSetLoader = t -> {
org.hl7.fhir.dstu2.model.ValueSet valueSet = (org.hl7.fhir.dstu2.model.ValueSet) theValidationSupportContext.getRootValidationSupport().fetchValueSet(t);
return ValueSet10_50.convertValueSet(valueSet);
return (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_10_50.convertResource(valueSet, new BaseAdvisor_10_50(false));
};
org.hl7.fhir.r5.model.ValueSet input = ValueSet10_50.convertValueSet(theInput);
org.hl7.fhir.r5.model.ValueSet input = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_10_50.convertResource(theInput, new BaseAdvisor_10_50(false));
org.hl7.fhir.r5.model.ValueSet output = expandValueSetR5(theValidationSupportContext, input, codeSystemLoader, valueSetLoader, theWantSystemUrlAndVersion, theWantCode);
return (output);
}
@ -372,7 +373,6 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
IParser parserHapi = FhirContext.forCached(FhirVersionEnum.DSTU2).newJsonParser();
Function<String, CodeSystem> codeSystemLoader = t -> {
// ca.uhn.fhir.model.dstu2.resource.ValueSet codeSystem = (ca.uhn.fhir.model.dstu2.resource.ValueSet) theValidationSupportContext.getRootValidationSupport().fetchCodeSystem(t);
ca.uhn.fhir.model.dstu2.resource.ValueSet codeSystem = theInput;
CodeSystem retVal = null;
if (codeSystem != null) {
@ -385,11 +385,11 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
Function<String, org.hl7.fhir.r5.model.ValueSet> valueSetLoader = t -> {
ca.uhn.fhir.model.dstu2.resource.ValueSet valueSet = (ca.uhn.fhir.model.dstu2.resource.ValueSet) theValidationSupportContext.getRootValidationSupport().fetchValueSet(t);
org.hl7.fhir.dstu2.model.ValueSet valueSetRi = parserRi.parseResource(org.hl7.fhir.dstu2.model.ValueSet.class, parserHapi.encodeResourceToString(valueSet));
return ValueSet10_50.convertValueSet(valueSetRi);
return (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_10_50.convertResource(valueSetRi, new BaseAdvisor_10_50(false));
};
org.hl7.fhir.dstu2.model.ValueSet valueSetRi = parserRi.parseResource(org.hl7.fhir.dstu2.model.ValueSet.class, parserHapi.encodeResourceToString(theInput));
org.hl7.fhir.r5.model.ValueSet input = ValueSet10_50.convertValueSet(valueSetRi);
org.hl7.fhir.r5.model.ValueSet input = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_10_50.convertResource(valueSetRi, new BaseAdvisor_10_50(false));
org.hl7.fhir.r5.model.ValueSet output = expandValueSetR5(theValidationSupportContext, input, codeSystemLoader, valueSetLoader, theWantSystemUrlAndVersion, theWantCode);
return (output);
}
@ -442,14 +442,14 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
private org.hl7.fhir.r5.model.ValueSet expandValueSetDstu3(ValidationSupportContext theValidationSupportContext, org.hl7.fhir.dstu3.model.ValueSet theInput, @Nullable String theWantSystemUrlAndVersion, @Nullable String theWantCode) {
Function<String, org.hl7.fhir.r5.model.CodeSystem> codeSystemLoader = t -> {
org.hl7.fhir.dstu3.model.CodeSystem codeSystem = (org.hl7.fhir.dstu3.model.CodeSystem) theValidationSupportContext.getRootValidationSupport().fetchCodeSystem(t);
return CodeSystem30_50.convertCodeSystem(codeSystem);
return (CodeSystem) VersionConvertorFactory_30_50.convertResource(codeSystem, new BaseAdvisor_30_50(false));
};
Function<String, org.hl7.fhir.r5.model.ValueSet> valueSetLoader = t -> {
org.hl7.fhir.dstu3.model.ValueSet valueSet = (org.hl7.fhir.dstu3.model.ValueSet) theValidationSupportContext.getRootValidationSupport().fetchValueSet(t);
return ValueSet30_50.convertValueSet(valueSet);
return (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_30_50.convertResource(valueSet, new BaseAdvisor_30_50(false));
};
org.hl7.fhir.r5.model.ValueSet input = ValueSet30_50.convertValueSet(theInput);
org.hl7.fhir.r5.model.ValueSet input = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_30_50.convertResource(theInput, new BaseAdvisor_30_50(false));
org.hl7.fhir.r5.model.ValueSet output = expandValueSetR5(theValidationSupportContext, input, codeSystemLoader, valueSetLoader, theWantSystemUrlAndVersion, theWantCode);
return (output);
}
@ -458,14 +458,14 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
private org.hl7.fhir.r5.model.ValueSet expandValueSetR4(ValidationSupportContext theValidationSupportContext, org.hl7.fhir.r4.model.ValueSet theInput, @Nullable String theWantSystemUrlAndVersion, @Nullable String theWantCode) {
Function<String, org.hl7.fhir.r5.model.CodeSystem> codeSystemLoader = t -> {
org.hl7.fhir.r4.model.CodeSystem codeSystem = (org.hl7.fhir.r4.model.CodeSystem) theValidationSupportContext.getRootValidationSupport().fetchCodeSystem(t);
return CodeSystem40_50.convertCodeSystem(codeSystem);
return (CodeSystem) VersionConvertorFactory_40_50.convertResource(codeSystem, new BaseAdvisor_40_50(false));
};
Function<String, org.hl7.fhir.r5.model.ValueSet> valueSetLoader = t -> {
org.hl7.fhir.r4.model.ValueSet valueSet = (org.hl7.fhir.r4.model.ValueSet) theValidationSupportContext.getRootValidationSupport().fetchValueSet(t);
return ValueSet40_50.convertValueSet(valueSet);
return (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSet, new BaseAdvisor_40_50(false));
};
org.hl7.fhir.r5.model.ValueSet input = ValueSet40_50.convertValueSet(theInput);
org.hl7.fhir.r5.model.ValueSet input = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_40_50.convertResource(theInput, new BaseAdvisor_40_50(false));
org.hl7.fhir.r5.model.ValueSet output = expandValueSetR5(theValidationSupportContext, input, codeSystemLoader, valueSetLoader, theWantSystemUrlAndVersion, theWantCode);
return (output);
}

View File

@ -15,7 +15,8 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.time.DateUtils;
import org.fhir.ucum.UcumService;
import org.hl7.fhir.convertors.VersionConvertor_10_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -144,6 +145,16 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
throw new UnsupportedOperationException();
}
@Override
public boolean hasPackage(PackageVersion packageVersion) {
return false;
}
@Override
public PackageDetails getPackage(PackageVersion packageVersion) {
return null;
}
@Override
public int getClientRetryCount() {
throw new UnsupportedOperationException();
@ -159,6 +170,11 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
return null;
}
@Override
public PackageVersion getPackageForUrl(String s) {
return null;
}
@Override
public void generateSnapshot(StructureDefinition input) throws FHIRException {
if (input.hasSnapshot()) {
@ -226,7 +242,7 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
}
@Override
public void cachePackage(PackageVersion packageDetails, List<PackageVersion> dependencies) {
public void cachePackage(PackageDetails packageDetails, List<PackageVersion> list) {
}
@ -676,7 +692,7 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
converter = new IVersionTypeConverter() {
@Override
public Resource toCanonical(IBaseResource theNonCanonical) {
Resource retVal = VersionConvertor_10_50.convertResource((org.hl7.fhir.dstu2.model.Resource) theNonCanonical);
Resource retVal = VersionConvertorFactory_10_50.convertResource((org.hl7.fhir.dstu2.model.Resource) theNonCanonical, new BaseAdvisor_10_50(false));
if (theNonCanonical instanceof org.hl7.fhir.dstu2.model.ValueSet) {
org.hl7.fhir.dstu2.model.ValueSet valueSet = (org.hl7.fhir.dstu2.model.ValueSet) theNonCanonical;
if (valueSet.hasCodeSystem() && valueSet.getCodeSystem().hasSystem()) {
@ -691,7 +707,7 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
@Override
public IBaseResource fromCanonical(Resource theCanonical) {
return VersionConvertor_10_50.convertResource(theCanonical);
return VersionConvertorFactory_10_50.convertResource(theCanonical, new BaseAdvisor_10_50(false));
}
};
break;

View File

@ -1,17 +1,17 @@
package org.hl7.fhir.common.hapi.validation.validator;
import org.hl7.fhir.convertors.VersionConvertor_14_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.Resource;
public class VersionTypeConverterDstu21 implements VersionSpecificWorkerContextWrapper.IVersionTypeConverter {
@Override
public Resource toCanonical(IBaseResource theNonCanonical) {
return VersionConvertor_14_50.convertResource((org.hl7.fhir.dstu2016may.model.Resource) theNonCanonical);
return VersionConvertorFactory_14_50.convertResource((org.hl7.fhir.dstu2016may.model.Resource) theNonCanonical);
}
@Override
public IBaseResource fromCanonical(Resource theCanonical) {
return VersionConvertor_14_50.convertResource(theCanonical);
return VersionConvertorFactory_14_50.convertResource(theCanonical);
}
}

View File

@ -1,17 +1,18 @@
package org.hl7.fhir.common.hapi.validation.validator;
import org.hl7.fhir.convertors.VersionConvertor_30_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.Resource;
public class VersionTypeConverterDstu3 implements VersionSpecificWorkerContextWrapper.IVersionTypeConverter {
@Override
public Resource toCanonical(IBaseResource theNonCanonical) {
return VersionConvertor_30_50.convertResource((org.hl7.fhir.dstu3.model.Resource) theNonCanonical, true);
return VersionConvertorFactory_30_50.convertResource((org.hl7.fhir.dstu3.model.Resource) theNonCanonical, new BaseAdvisor_30_50(false));
}
@Override
public IBaseResource fromCanonical(Resource theCanonical) {
return VersionConvertor_30_50.convertResource(theCanonical, true);
return VersionConvertorFactory_30_50.convertResource(theCanonical, new BaseAdvisor_30_50(false));
}
}

View File

@ -1,17 +1,18 @@
package org.hl7.fhir.common.hapi.validation.validator;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.Resource;
public class VersionTypeConverterR4 implements VersionSpecificWorkerContextWrapper.IVersionTypeConverter {
@Override
public Resource toCanonical(IBaseResource theNonCanonical) {
return VersionConvertor_40_50.convertResource((org.hl7.fhir.r4.model.Resource) theNonCanonical);
return VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r4.model.Resource) theNonCanonical, new BaseAdvisor_40_50(false));
}
@Override
public IBaseResource fromCanonical(Resource theCanonical) {
return VersionConvertor_40_50.convertResource(theCanonical);
return VersionConvertorFactory_40_50.convertResource(theCanonical, new BaseAdvisor_40_50(false));
}
}

View File

@ -1312,13 +1312,13 @@ public class FhirInstanceValidatorDstu3Test {
String input = IOUtils.toString(FhirInstanceValidatorDstu3Test.class.getResourceAsStream("/dstu3-rick-test.json"), Charsets.UTF_8);
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
when(resourceFetcher.validationPolicy(any(), anyString(), anyString())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
myVal.validateWithResult(input);
verify(resourceFetcher, times(3)).resolveURL(any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(4)).validationPolicy(any(), anyString(), anyString());
verify(resourceFetcher, times(4)).fetch(any(), anyString());
verify(resourceFetcher, times(3)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(4)).validationPolicy(any(), any(), anyString(), anyString());
verify(resourceFetcher, times(4)).fetch(any(), any(), anyString());
}
@Test

View File

@ -995,8 +995,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
List<SingleValidationMessage> messages = logResultsAndReturnNonInformationalOnes(output);
assertEquals(3, messages.size(), output.toString());
assertThat(messages.get(0).getMessage(), containsString("Element must have some content"));
assertThat(messages.get(1).getMessage(), containsString("Primitive types must have a value or must have child extensions"));
assertThat(messages.get(2).getMessage(), containsString("ele-1: 'All FHIR elements must have a @value or children' Rule 'All FHIR elements must have a @value or children' Failed"));
assertThat(messages.get(2).getMessage(), containsString("Primitive types must have a value or must have child extensions"));
}
@Test
@ -1398,13 +1397,13 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
String encoded = loadResource("/r4/r4-caredove-bundle.json");
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
when(resourceFetcher.validationPolicy(any(), anyString(), anyString())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
myVal.validateWithResult(encoded);
verify(resourceFetcher, times(15)).resolveURL(any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(12)).validationPolicy(any(), anyString(), anyString());
verify(resourceFetcher, times(12)).fetch(any(), anyString());
verify(resourceFetcher, times(15)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(12)).validationPolicy(any(), any(), anyString(), anyString());
verify(resourceFetcher, times(12)).fetch(any(), any(), anyString());
}
@Test

View File

@ -428,13 +428,13 @@ public class FhirInstanceValidatorR5Test {
String input = IOUtils.toString(FhirInstanceValidator.class.getResourceAsStream("/vitals.json"), Charsets.UTF_8);
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
when(resourceFetcher.validationPolicy(any(),anyString(), anyString())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
myVal.validateWithResult(input);
verify(resourceFetcher, times(13)).resolveURL(any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(4)).validationPolicy(any(), anyString(), anyString());
verify(resourceFetcher, times(3)).fetch(any(), anyString());
verify(resourceFetcher, times(13)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(4)).validationPolicy(any(), any(), anyString(), anyString());
verify(resourceFetcher, times(3)).fetch(any(), any(), anyString());
}
@Test
@ -614,8 +614,8 @@ public class FhirInstanceValidatorR5Test {
List<SingleValidationMessage> messages = logResultsAndReturnNonInformationalOnes(output);
assertEquals( 3, messages.size(), output.toString());
assertThat(messages.get(0).getMessage(), containsString("Element must have some content"));
assertThat(messages.get(1).getMessage(), containsString("Primitive types must have a value or must have child extensions"));
assertThat(messages.get(2).getMessage(), containsString("ele-1: 'All FHIR elements must have a @value or children' Rule 'All FHIR elements must have a @value or children' Failed"));
assertThat(messages.get(1).getMessage(), containsString("ele-1: 'All FHIR elements must have a @value or children' Rule 'All FHIR elements must have a @value or children' Failed"));
assertThat(messages.get(2).getMessage(), containsString("Primitive types must have a value or must have child extensions"));
}
@Test