Skip to content

Commit

Permalink
merge updates from main
Browse files Browse the repository at this point in the history
  • Loading branch information
timcoffman committed Aug 16, 2024
1 parent 1011886 commit e8dcfea
Show file tree
Hide file tree
Showing 8 changed files with 486 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
@Component
public class SupplementalDataStorePartition {

public static final String HEADER_PARTITION_NAME = "X-Partition-Name";

@Inject
SupplementalDataStoreProperties sdsProperties;

Expand Down Expand Up @@ -80,7 +78,8 @@ public RequestPartitionId partitionIdFromRequest(RequestDetails theRequestDetail
}

protected String partitionNameFromRequest(RequestDetails theRequestDetails) {
final String partitionNameHeaderValue = theRequestDetails.getHeader(HEADER_PARTITION_NAME);
final String httpHeader = sdsProperties.getPartition().getHttpHeader();
final String partitionNameHeaderValue = theRequestDetails.getHeader( httpHeader );
if (StringUtils.isNotBlank(partitionNameHeaderValue)) {
/*
* later we want to recreate the partition name
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
package edu.ohsu.cmp.ecp.sds.dstu3;

import static java.util.stream.Collectors.toList;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;

import javax.inject.Inject;

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.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;
Expand All @@ -27,6 +32,7 @@
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;
Expand All @@ -52,9 +58,114 @@ public class SupplementalDataStoreLinkageDstu3 extends SupplementalDataStoreLink
@Inject
IFhirResourceDao<org.hl7.fhir.dstu3.model.RelatedPerson> daoRelatedPersonDstu3;

private static Predicate<IIdType> 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<Linkage.LinkageItemComponent> 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<Linkage.LinkageItemComponent> refersTo( IIdType ref ) {
Predicate<IIdType> p = sameId( ref ) ;
return i -> i.hasResource() && i.getResource().hasReference() && p.test( referenceFromLinkage( i.getResource() ).getReferenceElement() );
}

private static Predicate<Linkage.LinkageItemComponent> 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<Linkage.LinkageItemComponent> sourceRefersTo( IIdType ref ) {
Predicate<Linkage.LinkageItemComponent> p1 = refersTo( ref ) ;
return i -> i.getType() == Linkage.LinkageType.SOURCE && p1.test(i) ;
}

private Predicate<IBaseResource> linkageItemFilter( List<List<IQueryParameterType>> 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<IBaseResource> linkageSourceFilter( List<List<IQueryParameterType>> 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 ) ) ) ) ;
} ;
}

private IQueryParameterType convertQueryParameter( IQueryParameterType parameter ) {
if ( parameter instanceof ReferenceParam ) {
ReferenceParam refParam = (ReferenceParam)parameter ;
IdType id = new IdType( refParam.getValue() ).toUnqualifiedVersionless() ;
return new ReferenceParam( id ) ;
} else {
return parameter ;
}
}

private List<IQueryParameterType> convertQueryParameters( List<IQueryParameterType> parameters ) {
return parameters.stream().map( this::convertQueryParameter ).collect( toList() ) ;
}

private List<List<IQueryParameterType>> convertQueryParametersList( List<List<IQueryParameterType>> parameters ) {
return parameters.stream().map( this::convertQueryParameters ).collect( toList() ) ;
}

@Override
protected List<IBaseResource> searchLinkageResources( SearchParameterMap linkageSearchParamMap, RequestDetails theRequestDetails ) {
return daoLinkageDstu3.search(linkageSearchParamMap, theRequestDetails).getAllResources();
/*
* server is returning LINKAGE resources while searching on SOURCE that match the id but are not SOURCE
*/
/*
* item and source parameters must be relative (i.e. no baseUrl) in order to find these LINKAGE resources
*/

SearchParameterMap replacementSearchParameterMap = linkageSearchParamMap.clone() ;
List<List<IQueryParameterType>> itemQueryParameter = replacementSearchParameterMap.remove("item");
List<List<IQueryParameterType>> sourceQueryParameter = replacementSearchParameterMap.remove("source");
if ( null != itemQueryParameter ) {
replacementSearchParameterMap.put( "item", convertQueryParametersList( itemQueryParameter ) );
}
if ( null != sourceQueryParameter ) {
replacementSearchParameterMap.put( "source", convertQueryParametersList( sourceQueryParameter ) );
}
return daoLinkageDstu3.search(replacementSearchParameterMap, theRequestDetails).getAllResources()
.stream()
.filter( linkageItemFilter( itemQueryParameter ) )
.filter( linkageSourceFilter( sourceQueryParameter ) )
.collect( java.util.stream.Collectors.toList() )
;
}

@Override
Expand All @@ -64,8 +175,9 @@ protected List<IBaseResource> filterLinkageResourcesHavingAlternateItem( List<IB
if (res instanceof Linkage) {
Linkage linkage = (Linkage) res;
for (Linkage.LinkageItemComponent linkageItem : linkage.getItem()) {
if (linkageItem.getType() == LinkageType.ALTERNATE && linkageItem.hasResource() && linkageItem.getResource().hasReference() && nonLocalPatientId.equals(linkageItem.getResource().getReferenceElement())) {
if (linkageItem.getType() == LinkageType.ALTERNATE && linkageItem.hasResource() && linkageItem.getResource().hasReference() && nonLocalPatientId.equals( referenceFromLinkage( linkageItem.getResource() ).getReferenceElement())) {
linkageResources.add(res);
break; // breaking to prevent re-adding res if there are multiple alternates
}
}
}
Expand All @@ -87,12 +199,37 @@ protected List<Reference> patientsFromLinkageResources(List<IBaseResource> 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
Expand All @@ -104,6 +241,7 @@ protected Set<? extends IBaseReference> 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 ) ;
}
Expand All @@ -117,6 +255,7 @@ protected Set<? extends IBaseReference> 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 ) ;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package edu.ohsu.cmp.ecp.sds.r4;

import static java.util.stream.Collectors.toList;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -31,7 +33,6 @@
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;
Expand Down Expand Up @@ -70,7 +71,7 @@ private static Predicate<IIdType> sameId( IIdType id ) {
return id.getIdPart().equals( i.getIdPart() ) ;
};
}

private static Predicate<Linkage.LinkageItemComponent> refersTo( IQueryParameterType param ) {
if ( param instanceof ReferenceParam ) {
ReferenceParam refParam = (ReferenceParam)param ;
Expand All @@ -79,7 +80,7 @@ private static Predicate<Linkage.LinkageItemComponent> refersTo( IQueryParameter
return (i) -> false ;
}
}

private static Predicate<Linkage.LinkageItemComponent> refersTo( IIdType ref ) {
Predicate<IIdType> p = sameId( ref ) ;
return i -> i.hasResource() && i.getResource().hasReference() && p.test( referenceFromLinkage( i.getResource() ).getReferenceElement() );
Expand All @@ -93,54 +94,78 @@ private static Predicate<Linkage.LinkageItemComponent> sourceRefersTo( IQueryPar
return (i) -> false ;
}
}


private static Predicate<Linkage.LinkageItemComponent> sourceRefersTo( IIdType ref ) {
Predicate<Linkage.LinkageItemComponent> p1 = refersTo( ref ) ;
return i -> i.getType() == Linkage.LinkageType.SOURCE && p1.test(i) ;
}

private Predicate<IBaseResource> linkageItemFilter( List<List<IQueryParameterType>> 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<IBaseResource> linkageSourceFilter( List<List<IQueryParameterType>> 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 ) ) ) ) ;
} ;
}


private IQueryParameterType convertQueryParameter( IQueryParameterType parameter ) {
if ( parameter instanceof ReferenceParam ) {
ReferenceParam refParam = (ReferenceParam)parameter ;
IdType id = new IdType( refParam.getValue() ).toUnqualifiedVersionless() ;
return new ReferenceParam( id ) ;
} else {
return parameter ;
}
}

private List<IQueryParameterType> convertQueryParameters( List<IQueryParameterType> parameters ) {
return parameters.stream().map( this::convertQueryParameter ).collect( toList() ) ;
}

private List<List<IQueryParameterType>> convertQueryParametersList( List<List<IQueryParameterType>> parameters ) {
return parameters.stream().map( this::convertQueryParameters ).collect( toList() ) ;
}

@Override
protected List<IBaseResource> searchLinkageResources( SearchParameterMap linkageSearchParamMap, RequestDetails theRequestDetails ) {
/*
* server is failing to find existing LINKAGE resources while searching on ITEM
*
return daoLinkageR4.search(linkageSearchParamMap, theRequestDetails).getAllResources();
* server is returning LINKAGE resources while searching on SOURCE that match the id but are not SOURCE
*/
/*
* item and source parameters must be relative (i.e. no baseUrl) in order to find these LINKAGE resources
*/

SearchParameterMap replacementSearchParameterMap = linkageSearchParamMap.clone() ;
Predicate<IBaseResource> itemFilter = linkageItemFilter( replacementSearchParameterMap.remove("item") ) ;
Predicate<IBaseResource> sourceFilter = linkageSourceFilter( replacementSearchParameterMap.remove("source") ) ;
List<List<IQueryParameterType>> itemQueryParameter = replacementSearchParameterMap.remove("item");
List<List<IQueryParameterType>> sourceQueryParameter = replacementSearchParameterMap.remove("source");
if ( null != itemQueryParameter ) {
replacementSearchParameterMap.put( "item", convertQueryParametersList( itemQueryParameter ) );
}
if ( null != sourceQueryParameter ) {
replacementSearchParameterMap.put( "source", convertQueryParametersList( sourceQueryParameter ) );
}
return daoLinkageR4.search(replacementSearchParameterMap, theRequestDetails).getAllResources()
.stream()
.filter( itemFilter )
.filter( sourceFilter )
.filter( linkageItemFilter( itemQueryParameter ) )
.filter( linkageSourceFilter( sourceQueryParameter ) )
.collect( java.util.stream.Collectors.toList() )
;

}

@Override
Expand Down
Loading

0 comments on commit e8dcfea

Please sign in to comment.