diff --git a/src/main/java/edu/ohsu/cmp/ecp/sds/dstu3/SupplementalDataStoreLinkageDstu3.java b/src/main/java/edu/ohsu/cmp/ecp/sds/dstu3/SupplementalDataStoreLinkageDstu3.java index a89ca78..1c184f2 100644 --- a/src/main/java/edu/ohsu/cmp/ecp/sds/dstu3/SupplementalDataStoreLinkageDstu3.java +++ b/src/main/java/edu/ohsu/cmp/ecp/sds/dstu3/SupplementalDataStoreLinkageDstu3.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; import javax.inject.Inject; @@ -11,10 +12,12 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.dstu3.model.RelatedPerson; +import org.hl7.fhir.dstu3.model.Type; import org.hl7.fhir.dstu3.model.StringType; import org.hl7.fhir.dstu3.model.BooleanType; import org.hl7.fhir.dstu3.model.DomainResource; import org.hl7.fhir.dstu3.model.Extension; +import org.hl7.fhir.dstu3.model.IdType; import org.hl7.fhir.dstu3.model.Linkage; import org.hl7.fhir.dstu3.model.Linkage.LinkageType; import org.hl7.fhir.dstu3.model.Patient; @@ -27,11 +30,13 @@ import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.starter.annotations.OnDSTU3Condition; +import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.param.ReferenceParam; import edu.ohsu.cmp.ecp.sds.SupplementalDataStoreProperties; import edu.ohsu.cmp.ecp.sds.base.FhirResourceComparison; import edu.ohsu.cmp.ecp.sds.base.SupplementalDataStoreLinkageBase; +import edu.ohsu.cmp.ecp.sds.r4.SupplementalDataStoreLinkageR4; @Component @Conditional(OnDSTU3Condition.class) @@ -64,8 +69,9 @@ protected List filterLinkageResourcesHavingAlternateItem( List patientsFromLinkageResources(List linka return linkedPatients; } + private static Reference referenceFromLinkage( Reference ref ) { + if ( !ref.hasExtension(EXTENSION_URL_SDS_PARTITION_NAME) ) + return ref ; + if ( !ref.hasReferenceElement() ) + return ref ; + Type extValue = ref.getExtensionByUrl(EXTENSION_URL_SDS_PARTITION_NAME).getValue() ; + if ( !(extValue instanceof StringType) ) + return ref ; + IIdType id = new IdType( ((StringType)extValue).getValue(), ref.getReferenceElement().getResourceType(), ref.getReferenceElement().getIdPart(), ref.getReferenceElement().getVersionIdPart() ) ; + return new Reference( id ) ; + } + + private static Reference referenceForLinkage( IIdType id ) { + if ( id.hasBaseUrl() ) { + Reference ref = new Reference( id.toUnqualifiedVersionless() ) ; + ref.addExtension(EXTENSION_URL_SDS_PARTITION_NAME, new StringType( id.getBaseUrl() ) ); + return ref ; + } else { + return new Reference(id) ; + } + } + @Override protected void createLinkage( IIdType sourcePatientId, IIdType alternatePatientId, RequestDetails theRequestDetails ) { Linkage linkage = new Linkage(); - linkage.addItem().setType(LinkageType.SOURCE).setResource(new Reference(sourcePatientId)); - linkage.addItem().setType(LinkageType.ALTERNATE).setResource(new Reference(alternatePatientId)); - daoLinkageDstu3.create(linkage, theRequestDetails); + linkage.addItem().setType(LinkageType.SOURCE).setResource(referenceForLinkage(sourcePatientId)); + linkage.addItem().setType(LinkageType.ALTERNATE).setResource(referenceForLinkage(alternatePatientId)); + DaoMethodOutcome outcome = daoLinkageDstu3.create(linkage, theRequestDetails); + if ( Boolean.TRUE != outcome.getCreated() ) { + throw new RuntimeException( "failed to create linkage between " + sourcePatientId + " and " + alternatePatientId ) ; + } } @Override @@ -104,6 +135,7 @@ protected Set alternatePatientsFromLinkageResources(Li .flatMap(k -> k.getItem().stream()) .filter(i -> i.getType() == LinkageType.ALTERNATE) .map(i -> i.getResource()) + .map( SupplementalDataStoreLinkageDstu3::referenceFromLinkage ) .collect(java.util.stream.Collectors.toList()); return FhirResourceComparison.references().createSet( sourceRefs ) ; } @@ -117,6 +149,7 @@ protected Set sourcePatientsFromLinkageResources(List< .flatMap(k -> k.getItem().stream()) .filter(i -> i.getType() == LinkageType.SOURCE) .map(i -> i.getResource()) + .map( SupplementalDataStoreLinkageDstu3::referenceFromLinkage ) .collect(java.util.stream.Collectors.toList()); return FhirResourceComparison.references().createSet( sourceRefs ) ; } diff --git a/src/main/java/edu/ohsu/cmp/ecp/sds/r4/SupplementalDataStoreLinkageR4.java b/src/main/java/edu/ohsu/cmp/ecp/sds/r4/SupplementalDataStoreLinkageR4.java index b937765..4b6f93c 100644 --- a/src/main/java/edu/ohsu/cmp/ecp/sds/r4/SupplementalDataStoreLinkageR4.java +++ b/src/main/java/edu/ohsu/cmp/ecp/sds/r4/SupplementalDataStoreLinkageR4.java @@ -30,8 +30,6 @@ import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition; -import ca.uhn.fhir.model.api.IQueryParameterType; -import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.param.ReferenceParam; import edu.ohsu.cmp.ecp.sds.SupplementalDataStoreProperties; @@ -57,90 +55,9 @@ public class SupplementalDataStoreLinkageR4 extends SupplementalDataStoreLinkage @Inject IFhirResourceDao daoRelatedPersonR4; - private static Predicate sameId( IIdType id ) { - return (i) -> { - if ( id.hasVersionIdPart() && i.hasVersionIdPart() && !id.getVersionIdPart().equals(i.getVersionIdPart())) - return false ; - if ( id.hasBaseUrl() && i.hasBaseUrl() && !id.getBaseUrl().equals(i.getBaseUrl())) - return false ; - if ( id.hasResourceType() && i.hasResourceType() && !id.getResourceType().equals(i.getResourceType())) - return false ; - if ( !id.hasIdPart() || !i.hasIdPart() ) - return false ; - return id.getIdPart().equals( i.getIdPart() ) ; - }; - } - - private static Predicate refersTo( IQueryParameterType param ) { - if ( param instanceof ReferenceParam ) { - ReferenceParam refParam = (ReferenceParam)param ; - return refersTo( new IdType( refParam.getResourceType(), refParam.getIdPart() ) ) ; - } else { - return (i) -> false ; - } - } - - private static Predicate refersTo( IIdType ref ) { - Predicate p = sameId( ref ) ; - return i -> i.hasResource() && i.getResource().hasReference() && p.test( referenceFromLinkage( i.getResource() ).getReferenceElement() ); - } - - private static Predicate sourceRefersTo( IQueryParameterType param ) { - if ( param instanceof ReferenceParam ) { - ReferenceParam refParam = (ReferenceParam)param ; - return sourceRefersTo( new IdType( refParam.getResourceType(), refParam.getIdPart() ) ) ; - } else { - return (i) -> false ; - } - } - - - private static Predicate sourceRefersTo( IIdType ref ) { - Predicate p1 = refersTo( ref ) ; - return i -> i.getType() == Linkage.LinkageType.SOURCE && p1.test(i) ; - } - - private Predicate linkageItemFilter( List> parameterValue ) { - if ( null == parameterValue ) - return r -> true ; - return r -> { - if ( !(r instanceof Linkage ) ) - return false ; - Linkage linkage = (Linkage)r ; - - return parameterValue.stream().allMatch( v1 -> v1.stream().anyMatch( v -> linkage.getItem().stream().anyMatch( refersTo( v ) ) ) ) ; - } ; - } - - private Predicate linkageSourceFilter( List> parameterValue ) { - if ( null == parameterValue ) - return r -> true ; - return r -> { - if ( !(r instanceof Linkage ) ) - return false ; - Linkage linkage = (Linkage)r ; - - return parameterValue.stream().allMatch( v1 -> v1.stream().anyMatch( v -> linkage.getItem().stream().anyMatch( sourceRefersTo( v ) ) ) ) ; - } ; - } - @Override protected List searchLinkageResources( SearchParameterMap linkageSearchParamMap, RequestDetails theRequestDetails ) { - /* - * server is failing to find existing LINKAGE resources while searching on ITEM - * return daoLinkageR4.search(linkageSearchParamMap, theRequestDetails).getAllResources(); - */ - SearchParameterMap replacementSearchParameterMap = linkageSearchParamMap.clone() ; - Predicate itemFilter = linkageItemFilter( replacementSearchParameterMap.remove("item") ) ; - Predicate sourceFilter = linkageSourceFilter( replacementSearchParameterMap.remove("source") ) ; - return daoLinkageR4.search(replacementSearchParameterMap, theRequestDetails).getAllResources() - .stream() - .filter( itemFilter ) - .filter( sourceFilter ) - .collect( java.util.stream.Collectors.toList() ) - ; - } @Override diff --git a/src/main/java/edu/ohsu/cmp/ecp/sds/r4b/SupplementalDataStoreLinkageR4B.java b/src/main/java/edu/ohsu/cmp/ecp/sds/r4b/SupplementalDataStoreLinkageR4B.java index 413e120..658fcf1 100644 --- a/src/main/java/edu/ohsu/cmp/ecp/sds/r4b/SupplementalDataStoreLinkageR4B.java +++ b/src/main/java/edu/ohsu/cmp/ecp/sds/r4b/SupplementalDataStoreLinkageR4B.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; import javax.inject.Inject; @@ -13,8 +14,10 @@ import org.hl7.fhir.r4b.model.RelatedPerson; import org.hl7.fhir.r4b.model.UrlType; import org.hl7.fhir.r4b.model.BooleanType; +import org.hl7.fhir.r4b.model.DataType; import org.hl7.fhir.r4b.model.DomainResource; import org.hl7.fhir.r4b.model.Extension; +import org.hl7.fhir.r4b.model.IdType; import org.hl7.fhir.r4b.model.Linkage; import org.hl7.fhir.r4b.model.Linkage.LinkageType; import org.hl7.fhir.r4b.model.Patient; @@ -27,11 +30,13 @@ import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.starter.annotations.OnR4BCondition; +import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.param.ReferenceParam; import edu.ohsu.cmp.ecp.sds.SupplementalDataStoreProperties; import edu.ohsu.cmp.ecp.sds.base.FhirResourceComparison; import edu.ohsu.cmp.ecp.sds.base.SupplementalDataStoreLinkageBase; +import edu.ohsu.cmp.ecp.sds.r4.SupplementalDataStoreLinkageR4; @Component @Conditional(OnR4BCondition.class) @@ -64,8 +69,9 @@ protected List filterLinkageResourcesHavingAlternateItem( List patientsFromLinkageResources(List linka return linkedPatients; } + private static Reference referenceFromLinkage( Reference ref ) { + if ( !ref.hasExtension(EXTENSION_URL_SDS_PARTITION_NAME) ) + return ref ; + if ( !ref.hasReferenceElement() ) + return ref ; + DataType extValue = ref.getExtensionByUrl(EXTENSION_URL_SDS_PARTITION_NAME).getValue() ; + if ( !(extValue instanceof UrlType) ) + return ref ; + IIdType id = new IdType( ((UrlType)extValue).getValue(), ref.getReferenceElement().getResourceType(), ref.getReferenceElement().getIdPart(), ref.getReferenceElement().getVersionIdPart() ) ; + return new Reference( id ) ; + } + + private static Reference referenceForLinkage( IIdType id ) { + if ( id.hasBaseUrl() ) { + Reference ref = new Reference( id.toUnqualifiedVersionless() ) ; + ref.addExtension(EXTENSION_URL_SDS_PARTITION_NAME, new UrlType( id.getBaseUrl() ) ); + return ref ; + } else { + return new Reference(id) ; + } + } + @Override protected void createLinkage( IIdType sourcePatientId, IIdType alternatePatientId, RequestDetails theRequestDetails ) { Linkage linkage = new Linkage(); - linkage.addItem().setType(LinkageType.SOURCE).setResource(new Reference(sourcePatientId)); - linkage.addItem().setType(LinkageType.ALTERNATE).setResource(new Reference(alternatePatientId)); - daoLinkageR4B.create(linkage, theRequestDetails); + linkage.addItem().setType(LinkageType.SOURCE).setResource(referenceForLinkage(sourcePatientId)); + linkage.addItem().setType(LinkageType.ALTERNATE).setResource(referenceForLinkage(alternatePatientId)); + DaoMethodOutcome outcome = daoLinkageR4B.create(linkage, theRequestDetails); + if ( Boolean.TRUE != outcome.getCreated() ) { + throw new RuntimeException( "failed to create linkage between " + sourcePatientId + " and " + alternatePatientId ) ; + } } @Override @@ -104,6 +135,7 @@ protected Set alternatePatientsFromLinkageResources(Li .flatMap(k -> k.getItem().stream()) .filter(i -> i.getType() == LinkageType.ALTERNATE) .map(i -> i.getResource()) + .map( SupplementalDataStoreLinkageR4B::referenceFromLinkage ) .collect(java.util.stream.Collectors.toList()); return FhirResourceComparison.references().createSet( sourceRefs ) ; } @@ -117,6 +149,7 @@ protected Set sourcePatientsFromLinkageResources(List< .flatMap(k -> k.getItem().stream()) .filter(i -> i.getType() == LinkageType.SOURCE) .map(i -> i.getResource()) + .map( SupplementalDataStoreLinkageR4B::referenceFromLinkage ) .collect(java.util.stream.Collectors.toList()); return FhirResourceComparison.references().createSet( sourceRefs ) ; } diff --git a/src/main/java/edu/ohsu/cmp/ecp/sds/r5/SupplementalDataStoreLinkageR5.java b/src/main/java/edu/ohsu/cmp/ecp/sds/r5/SupplementalDataStoreLinkageR5.java index 512e238..6cabff7 100644 --- a/src/main/java/edu/ohsu/cmp/ecp/sds/r5/SupplementalDataStoreLinkageR5.java +++ b/src/main/java/edu/ohsu/cmp/ecp/sds/r5/SupplementalDataStoreLinkageR5.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; import javax.inject.Inject; @@ -13,8 +14,10 @@ import org.hl7.fhir.r5.model.RelatedPerson; import org.hl7.fhir.r5.model.UrlType; import org.hl7.fhir.r5.model.BooleanType; +import org.hl7.fhir.r5.model.DataType; import org.hl7.fhir.r5.model.DomainResource; import org.hl7.fhir.r5.model.Extension; +import org.hl7.fhir.r5.model.IdType; import org.hl7.fhir.r5.model.Linkage; import org.hl7.fhir.r5.model.Linkage.LinkageType; import org.hl7.fhir.r5.model.Patient; @@ -27,11 +30,13 @@ import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.starter.annotations.OnR5Condition; +import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.param.ReferenceParam; import edu.ohsu.cmp.ecp.sds.SupplementalDataStoreProperties; import edu.ohsu.cmp.ecp.sds.base.FhirResourceComparison; import edu.ohsu.cmp.ecp.sds.base.SupplementalDataStoreLinkageBase; +import edu.ohsu.cmp.ecp.sds.r4.SupplementalDataStoreLinkageR4; @Component @Conditional(OnR5Condition.class) @@ -64,8 +69,9 @@ protected List filterLinkageResourcesHavingAlternateItem( List patientsFromLinkageResources(List linka return linkedPatients; } + private static Reference referenceFromLinkage( Reference ref ) { + if ( !ref.hasExtension(EXTENSION_URL_SDS_PARTITION_NAME) ) + return ref ; + if ( !ref.hasReferenceElement() ) + return ref ; + DataType extValue = ref.getExtensionByUrl(EXTENSION_URL_SDS_PARTITION_NAME).getValue() ; + if ( !(extValue instanceof UrlType) ) + return ref ; + IIdType id = new IdType( ((UrlType)extValue).getValue(), ref.getReferenceElement().getResourceType(), ref.getReferenceElement().getIdPart(), ref.getReferenceElement().getVersionIdPart() ) ; + return new Reference( id ) ; + } + + private static Reference referenceForLinkage( IIdType id ) { + if ( id.hasBaseUrl() ) { + Reference ref = new Reference( id.toUnqualifiedVersionless() ) ; + ref.addExtension(EXTENSION_URL_SDS_PARTITION_NAME, new UrlType( id.getBaseUrl() ) ); + return ref ; + } else { + return new Reference(id) ; + } + } + @Override protected void createLinkage( IIdType sourcePatientId, IIdType alternatePatientId, RequestDetails theRequestDetails ) { Linkage linkage = new Linkage(); - linkage.addItem().setType(LinkageType.SOURCE).setResource(new Reference(sourcePatientId)); - linkage.addItem().setType(LinkageType.ALTERNATE).setResource(new Reference(alternatePatientId)); - daoLinkageR5.create(linkage, theRequestDetails); + linkage.addItem().setType(LinkageType.SOURCE).setResource(referenceForLinkage(sourcePatientId)); + linkage.addItem().setType(LinkageType.ALTERNATE).setResource(referenceForLinkage(alternatePatientId)); + DaoMethodOutcome outcome = daoLinkageR5.create(linkage, theRequestDetails); + if ( Boolean.TRUE != outcome.getCreated() ) { + throw new RuntimeException( "failed to create linkage between " + sourcePatientId + " and " + alternatePatientId ) ; + } } @Override @@ -104,6 +135,7 @@ protected Set alternatePatientsFromLinkageResources(Li .flatMap(k -> k.getItem().stream()) .filter(i -> i.getType() == LinkageType.ALTERNATE) .map(i -> i.getResource()) + .map( SupplementalDataStoreLinkageR5::referenceFromLinkage ) .collect(java.util.stream.Collectors.toList()); return FhirResourceComparison.references().createSet( sourceRefs ) ; } @@ -117,6 +149,7 @@ protected Set sourcePatientsFromLinkageResources(List< .flatMap(k -> k.getItem().stream()) .filter(i -> i.getType() == LinkageType.SOURCE) .map(i -> i.getResource()) + .map( SupplementalDataStoreLinkageR5::referenceFromLinkage ) .collect(java.util.stream.Collectors.toList()); return FhirResourceComparison.references().createSet( sourceRefs ) ; }