4153 extend $member match operation to store consent resource if matched (#4165)
* added senstive and regular filter * add UUID to Consent * blah * fix merge with master * fixing merge * blah * fhir tests * use constructor injection * put all tests together * blah * blah * finalize * add consent update patient and performer reference * fixes after code review * blah * refactor to save consent once * blah * fix performer and add validation * code clean up * add changelog * add hrex member match flag * fix PatientMemberMatchOperationR4Test * adding code fixes after code review * move changelog file * bump version Co-authored-by: leif stawnyczy <leifstawnyczy@leifs-mbp.home>
This commit is contained in:
parent
31a193fbd3
commit
1b55f49a60
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -210,8 +210,11 @@ public class Constants {
|
||||||
public static final String PARAM_MEMBER_PATIENT = "MemberPatient";
|
public static final String PARAM_MEMBER_PATIENT = "MemberPatient";
|
||||||
public static final String PARAM_OLD_COVERAGE = "OldCoverage";
|
public static final String PARAM_OLD_COVERAGE = "OldCoverage";
|
||||||
public static final String PARAM_NEW_COVERAGE = "NewCoverage";
|
public static final String PARAM_NEW_COVERAGE = "NewCoverage";
|
||||||
|
public static final String PARAM_CONSENT = "Consent";
|
||||||
public static final String PARAM_MEMBER_PATIENT_NAME = PARAM_MEMBER_PATIENT + " Name";
|
public static final String PARAM_MEMBER_PATIENT_NAME = PARAM_MEMBER_PATIENT + " Name";
|
||||||
public static final String PARAM_MEMBER_PATIENT_BIRTHDATE = PARAM_MEMBER_PATIENT + " Birthdate";
|
public static final String PARAM_MEMBER_PATIENT_BIRTHDATE = PARAM_MEMBER_PATIENT + " Birthdate";
|
||||||
|
public static final String PARAM_CONSENT_PATIENT_REFERENCE = PARAM_CONSENT + "'s Patient Reference";
|
||||||
|
public static final String PARAM_CONSENT_PERFORMER_REFERENCE = PARAM_CONSENT + "'s Performer Reference";
|
||||||
|
|
||||||
public static final String PARAMQUALIFIER_MISSING = ":missing";
|
public static final String PARAMQUALIFIER_MISSING = ":missing";
|
||||||
public static final String PARAMQUALIFIER_MISSING_FALSE = "false";
|
public static final String PARAMQUALIFIER_MISSING_FALSE = "false";
|
||||||
|
|
|
@ -190,4 +190,4 @@ operation.member.match.error.beneficiary.not.found=Could not find beneficiary fo
|
||||||
operation.member.match.error.missing.parameter=Parameter "{0}" is required.
|
operation.member.match.error.missing.parameter=Parameter "{0}" is required.
|
||||||
operation.member.match.error.beneficiary.without.identifier=Coverage beneficiary does not have an identifier.
|
operation.member.match.error.beneficiary.without.identifier=Coverage beneficiary does not have an identifier.
|
||||||
operation.member.match.error.patient.not.found=Could not find matching patient for coverage.
|
operation.member.match.error.patient.not.found=Could not find matching patient for coverage.
|
||||||
|
operation.member.match.error.consent.release.data.mismatch=Consent policy does not match the data release segmentation capabilities.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-bom</artifactId>
|
<artifactId>hapi-fhir-bom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>HAPI FHIR BOM</name>
|
<name>HAPI FHIR BOM</name>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-cli</artifactId>
|
<artifactId>hapi-fhir-cli</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom</relativePath>
|
<relativePath>../../hapi-deployable-pom</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
type: add
|
||||||
|
issue: 4153
|
||||||
|
title: "Extend $member-match to store Consent resource when there is a matching patient."
|
|
@ -11,7 +11,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
||||||
import ca.uhn.fhir.interceptor.executor.InterceptorService;
|
import ca.uhn.fhir.interceptor.executor.InterceptorService;
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
|
import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
|
||||||
|
@ -63,6 +64,7 @@ import ca.uhn.fhir.jpa.provider.DiffProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
|
import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
|
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.ValueSetOperationProvider;
|
import ca.uhn.fhir.jpa.provider.ValueSetOperationProvider;
|
||||||
|
import ca.uhn.fhir.jpa.provider.r4.IConsentExtensionProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
|
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
|
||||||
import ca.uhn.fhir.jpa.sched.AutowiringSpringBeanJobFactory;
|
import ca.uhn.fhir.jpa.sched.AutowiringSpringBeanJobFactory;
|
||||||
import ca.uhn.fhir.jpa.sched.HapiSchedulerServiceImpl;
|
import ca.uhn.fhir.jpa.sched.HapiSchedulerServiceImpl;
|
||||||
|
@ -111,8 +113,8 @@ import ca.uhn.fhir.jpa.searchparam.nickname.NicknameInterceptor;
|
||||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
|
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
|
||||||
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
|
import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
|
||||||
import ca.uhn.fhir.jpa.term.TermReadSvcImpl;
|
|
||||||
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
|
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
|
||||||
|
import ca.uhn.fhir.jpa.term.TermReadSvcImpl;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
||||||
import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig;
|
import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig;
|
||||||
|
@ -129,6 +131,9 @@ import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor;
|
||||||
import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
|
import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
|
||||||
import org.hl7.fhir.common.hapi.validation.support.UnknownCodeSystemWarningValidationSupport;
|
import org.hl7.fhir.common.hapi.validation.support.UnknownCodeSystemWarningValidationSupport;
|
||||||
|
import org.hl7.fhir.r4.model.Consent;
|
||||||
|
import org.hl7.fhir.r4.model.Coverage;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices;
|
import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices;
|
||||||
import org.hl7.fhir.utilities.npm.PackageClient;
|
import org.hl7.fhir.utilities.npm.PackageClient;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -710,6 +715,20 @@ public class JpaConfig {
|
||||||
return new UnknownCodeSystemWarningValidationSupport(theFhirContext);
|
return new UnknownCodeSystemWarningValidationSupport(theFhirContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Bean
|
||||||
|
public MemberMatcherR4Helper memberMatcherR4Helper(
|
||||||
|
@Autowired FhirContext theContext,
|
||||||
|
@Autowired IFhirResourceDao<Coverage> theCoverageDao,
|
||||||
|
@Autowired IFhirResourceDao<Patient> thePatientDao,
|
||||||
|
@Autowired IFhirResourceDao<Consent> theConsentDao,
|
||||||
|
@Autowired(required = false) IConsentExtensionProvider theExtensionProvider
|
||||||
|
) {
|
||||||
|
return new MemberMatcherR4Helper(
|
||||||
|
theContext, theCoverageDao, thePatientDao, theConsentDao, theExtensionProvider
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Bean
|
@Bean
|
||||||
public NicknameInterceptor nicknameInterceptor() throws IOException {
|
public NicknameInterceptor nicknameInterceptor() throws IOException {
|
||||||
|
@ -732,5 +751,4 @@ public class JpaConfig {
|
||||||
return new TermReadSvcImpl();
|
return new TermReadSvcImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.config.r4;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||||
import ca.uhn.fhir.jpa.api.IDaoRegistry;
|
import ca.uhn.fhir.jpa.api.IDaoRegistry;
|
||||||
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
|
||||||
import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR4;
|
import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR4;
|
||||||
import ca.uhn.fhir.jpa.config.JpaConfig;
|
import ca.uhn.fhir.jpa.config.JpaConfig;
|
||||||
|
@ -12,6 +13,7 @@ import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4;
|
||||||
import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
|
import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
|
||||||
import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection;
|
import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
|
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
|
||||||
|
import ca.uhn.fhir.jpa.provider.r4.IConsentExtensionProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.r4.MemberMatchR4ResourceProvider;
|
import ca.uhn.fhir.jpa.provider.r4.MemberMatchR4ResourceProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
|
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
|
||||||
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
|
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
|
||||||
|
@ -23,8 +25,12 @@ import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||||
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
||||||
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
|
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
|
||||||
import org.hl7.fhir.r4.model.Bundle;
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4.model.Consent;
|
||||||
|
import org.hl7.fhir.r4.model.Coverage;
|
||||||
import org.hl7.fhir.r4.model.Meta;
|
import org.hl7.fhir.r4.model.Meta;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices;
|
import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
@ -97,27 +103,24 @@ public class JpaR4Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MemberMatcherR4Helper memberMatcherR4Helper(FhirContext theFhirContext) {
|
public MemberMatcherR4Helper memberMatcherR4Helper(
|
||||||
return new MemberMatcherR4Helper(theFhirContext);
|
@Autowired FhirContext theContext,
|
||||||
|
@Autowired IFhirResourceDao<Coverage> theCoverageDao,
|
||||||
|
@Autowired IFhirResourceDao<Patient> thePatientDao,
|
||||||
|
@Autowired IFhirResourceDao<Consent> theConsentDao,
|
||||||
|
@Autowired(required = false) IConsentExtensionProvider theExtensionProvider
|
||||||
|
) {
|
||||||
|
return new MemberMatcherR4Helper(
|
||||||
|
theContext,
|
||||||
|
theCoverageDao,
|
||||||
|
thePatientDao,
|
||||||
|
theConsentDao,
|
||||||
|
theExtensionProvider
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MemberMatchR4ResourceProvider memberMatchR4ResourceProvider(FhirContext theFhirContext, MemberMatcherR4Helper theMemberMatchR4Helper) {
|
public MemberMatchR4ResourceProvider memberMatchR4ResourceProvider(FhirContext theFhirContext, MemberMatcherR4Helper theMemberMatchR4Helper) {
|
||||||
return new MemberMatchR4ResourceProvider(theFhirContext, theMemberMatchR4Helper);
|
return new MemberMatchR4ResourceProvider(theFhirContext, theMemberMatchR4Helper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ProviderLoader r4ProviderLoader(ResourceProviderFactory theResourceProviderFactory, MemberMatchR4ResourceProvider theMemberMatchR4ResourceProvider) {
|
|
||||||
return new ProviderLoader(theResourceProviderFactory, theMemberMatchR4ResourceProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ProviderLoader {
|
|
||||||
|
|
||||||
public ProviderLoader(ResourceProviderFactory theResourceProviderFactory, MemberMatchR4ResourceProvider theMemberMatchR4ResourceProvider) {
|
|
||||||
theResourceProviderFactory.addSupplier(()->theMemberMatchR4ResourceProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package ca.uhn.fhir.jpa.provider.r4;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public interface IConsentExtensionProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a Consent resource and returns a collection of Extensions that will
|
||||||
|
* be added to the base resource.
|
||||||
|
*
|
||||||
|
* @param theConsentResource - the consent resource
|
||||||
|
* @return - a collection of resources (or an empty collection if none).
|
||||||
|
*/
|
||||||
|
default Collection<IBaseExtension> getConsentExtension(IBaseResource theConsentResource) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
};
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
||||||
import org.hl7.fhir.r4.model.Coverage;
|
import org.hl7.fhir.r4.model.Coverage;
|
||||||
import org.hl7.fhir.r4.model.Parameters;
|
import org.hl7.fhir.r4.model.Parameters;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.Consent;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -69,16 +70,20 @@ public class MemberMatchR4ResourceProvider {
|
||||||
@OperationParam(name = Constants.PARAM_NEW_COVERAGE, min = 1, max = 1)
|
@OperationParam(name = Constants.PARAM_NEW_COVERAGE, min = 1, max = 1)
|
||||||
Coverage newCoverage,
|
Coverage newCoverage,
|
||||||
|
|
||||||
|
@Description(shortDefinition = "Consent information. Consent held by the system seeking the match that grants permission to access the patient information.")
|
||||||
|
@OperationParam(name = Constants.PARAM_CONSENT, min = 1, max = 1)
|
||||||
|
Consent theConsent,
|
||||||
|
|
||||||
RequestDetails theRequestDetails
|
RequestDetails theRequestDetails
|
||||||
) {
|
) {
|
||||||
return doMemberMatchOperation(theServletRequest, theMemberPatient, oldCoverage, newCoverage, theRequestDetails);
|
return doMemberMatchOperation(theServletRequest, theMemberPatient, oldCoverage, newCoverage, theConsent, theRequestDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Parameters doMemberMatchOperation(HttpServletRequest theServletRequest, Patient theMemberPatient,
|
private Parameters doMemberMatchOperation(HttpServletRequest theServletRequest, Patient theMemberPatient,
|
||||||
Coverage theCoverageToMatch, Coverage theCoverageToLink, RequestDetails theRequestDetails) {
|
Coverage theCoverageToMatch, Coverage theCoverageToLink, Consent theConsent, RequestDetails theRequestDetails) {
|
||||||
|
|
||||||
validateParams(theMemberPatient, theCoverageToMatch, theCoverageToLink);
|
validateParams(theMemberPatient, theCoverageToMatch, theCoverageToLink, theConsent);
|
||||||
|
|
||||||
Optional<Coverage> coverageOpt = myMemberMatcherR4Helper.findMatchingCoverage(theCoverageToMatch);
|
Optional<Coverage> coverageOpt = myMemberMatcherR4Helper.findMatchingCoverage(theCoverageToMatch);
|
||||||
if ( ! coverageOpt.isPresent()) {
|
if ( ! coverageOpt.isPresent()) {
|
||||||
|
@ -108,16 +113,24 @@ public class MemberMatchR4ResourceProvider {
|
||||||
throw new UnprocessableEntityException(Msg.code(1157) + i18nMessage);
|
throw new UnprocessableEntityException(Msg.code(1157) + i18nMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
myMemberMatcherR4Helper.addMemberIdentifierToMemberPatient(theMemberPatient, patient.getIdentifierFirstRep());
|
if (!myMemberMatcherR4Helper.validConsentDataAccess(theConsent)) {
|
||||||
|
String i18nMessage = myFhirContext.getLocalizer().getMessage(
|
||||||
|
"operation.member.match.error.consent.release.data.mismatch");
|
||||||
|
throw new UnprocessableEntityException(Msg.code(2147) + i18nMessage);
|
||||||
|
}
|
||||||
|
|
||||||
return myMemberMatcherR4Helper.buildSuccessReturnParameters(theMemberPatient, theCoverageToLink);
|
myMemberMatcherR4Helper.addMemberIdentifierToMemberPatient(theMemberPatient, patient.getIdentifierFirstRep());
|
||||||
|
myMemberMatcherR4Helper.updateConsentForMemberMatch(theConsent, patient);
|
||||||
|
return myMemberMatcherR4Helper.buildSuccessReturnParameters(theMemberPatient, theCoverageToLink, theConsent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateParams(Patient theMemberPatient, Coverage theOldCoverage, Coverage theNewCoverage) {
|
private void validateParams(Patient theMemberPatient, Coverage theOldCoverage, Coverage theNewCoverage, Consent theConsent) {
|
||||||
validateParam(theMemberPatient, Constants.PARAM_MEMBER_PATIENT);
|
validateParam(theMemberPatient, Constants.PARAM_MEMBER_PATIENT);
|
||||||
validateParam(theOldCoverage, Constants.PARAM_OLD_COVERAGE);
|
validateParam(theOldCoverage, Constants.PARAM_OLD_COVERAGE);
|
||||||
validateParam(theNewCoverage, Constants.PARAM_NEW_COVERAGE);
|
validateParam(theNewCoverage, Constants.PARAM_NEW_COVERAGE);
|
||||||
|
validateParam(theConsent, Constants.PARAM_CONSENT);
|
||||||
validateMemberPatientParam(theMemberPatient);
|
validateMemberPatientParam(theMemberPatient);
|
||||||
|
validateConsentParam(theConsent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateParam(Object theParam, String theParamName) {
|
private void validateParam(Object theParam, String theParamName) {
|
||||||
|
@ -136,4 +149,13 @@ public class MemberMatchR4ResourceProvider {
|
||||||
validateParam(theMemberPatient.getName().get(0).getFamily(), Constants.PARAM_MEMBER_PATIENT_NAME);
|
validateParam(theMemberPatient.getName().get(0).getFamily(), Constants.PARAM_MEMBER_PATIENT_NAME);
|
||||||
validateParam(theMemberPatient.getBirthDate(), Constants.PARAM_MEMBER_PATIENT_BIRTHDATE);
|
validateParam(theMemberPatient.getBirthDate(), Constants.PARAM_MEMBER_PATIENT_BIRTHDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateConsentParam(Consent theConsent) {
|
||||||
|
if (theConsent.getPatient().isEmpty()) {
|
||||||
|
validateParam(null, Constants.PARAM_CONSENT_PATIENT_REFERENCE);
|
||||||
|
}
|
||||||
|
if (theConsent.getPerformer().isEmpty()) {
|
||||||
|
validateParam(null, Constants.PARAM_CONSENT_PERFORMER_REFERENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.provider.r4;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.param.DateParam;
|
import ca.uhn.fhir.rest.param.DateParam;
|
||||||
|
@ -10,22 +11,31 @@ import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||||
import ca.uhn.fhir.util.ParametersUtil;
|
import ca.uhn.fhir.util.ParametersUtil;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
import org.hl7.fhir.r4.model.Coding;
|
||||||
|
import org.hl7.fhir.r4.model.Consent;
|
||||||
import org.hl7.fhir.r4.model.Coverage;
|
import org.hl7.fhir.r4.model.Coverage;
|
||||||
|
import org.hl7.fhir.r4.model.Extension;
|
||||||
import org.hl7.fhir.r4.model.HumanName;
|
import org.hl7.fhir.r4.model.HumanName;
|
||||||
import org.hl7.fhir.r4.model.Identifier;
|
import org.hl7.fhir.r4.model.Identifier;
|
||||||
import org.hl7.fhir.r4.model.Parameters;
|
import org.hl7.fhir.r4.model.Parameters;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
import org.hl7.fhir.r4.model.Reference;
|
||||||
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_CONSENT;
|
||||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
||||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
||||||
|
|
||||||
|
@ -50,23 +60,39 @@ import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class MemberMatcherR4Helper {
|
public class MemberMatcherR4Helper {
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MemberMatcherR4Helper.class);
|
||||||
|
|
||||||
private static final String OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0203";
|
private static final String OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0203";
|
||||||
private static final String OUT_COVERAGE_IDENTIFIER_CODE = "MB";
|
private static final String OUT_COVERAGE_IDENTIFIER_CODE = "MB";
|
||||||
private static final String OUT_COVERAGE_IDENTIFIER_TEXT = "Member Number";
|
private static final String OUT_COVERAGE_IDENTIFIER_TEXT = "Member Number";
|
||||||
private static final String COVERAGE_TYPE = "Coverage";
|
private static final String COVERAGE_TYPE = "Coverage";
|
||||||
|
private static final String CONSENT_POLICY_REGULAR_TYPE = "regular";
|
||||||
|
private static final String CONSENT_POLICY_SENSITIVE_TYPE = "sensitive";
|
||||||
|
public static final String CONSENT_IDENTIFIER_CODE_SYSTEM = "https://smilecdr.com/fhir/ns/member-match-fixme";
|
||||||
|
|
||||||
private final FhirContext myFhirContext;
|
private final FhirContext myFhirContext;
|
||||||
|
private final IFhirResourceDao<Coverage> myCoverageDao;
|
||||||
|
private final IFhirResourceDao<Patient> myPatientDao;
|
||||||
|
private final IFhirResourceDao<Consent> myConsentDao;
|
||||||
|
// by default, not provided
|
||||||
|
// but if it is, extensions can be added to Consent on $member-match
|
||||||
|
@Nullable
|
||||||
|
private final IConsentExtensionProvider myIConsentExtensionProvider;
|
||||||
|
|
||||||
@Autowired
|
private boolean myRegularFilterSupported = false;
|
||||||
private IFhirResourceDao<Coverage> myCoverageDao;
|
|
||||||
|
|
||||||
@Autowired
|
public MemberMatcherR4Helper(
|
||||||
private IFhirResourceDao<Patient> myPatientDao;
|
FhirContext theContext,
|
||||||
|
IFhirResourceDao<Coverage> theCoverageDao,
|
||||||
|
IFhirResourceDao<Patient> thePatientDao,
|
||||||
public MemberMatcherR4Helper(FhirContext theContext) {
|
IFhirResourceDao<Consent> theConsentDao,
|
||||||
|
@Nullable IConsentExtensionProvider theExtensionProvider
|
||||||
|
) {
|
||||||
myFhirContext = theContext;
|
myFhirContext = theContext;
|
||||||
|
myConsentDao = theConsentDao;
|
||||||
|
myPatientDao = thePatientDao;
|
||||||
|
myCoverageDao = theCoverageDao;
|
||||||
|
myIConsentExtensionProvider = theExtensionProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,15 +142,23 @@ public class MemberMatcherR4Helper {
|
||||||
return retVal.getAllResources();
|
return retVal.getAllResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateConsentForMemberMatch(Consent theConsent, Patient thePatient) {
|
||||||
|
addClientIdAsExtensionToConsentIfAvailable(theConsent);
|
||||||
|
addIdentifierToConsent(theConsent);
|
||||||
|
updateConsentPatientAndPerformer(theConsent, thePatient);
|
||||||
|
|
||||||
public Parameters buildSuccessReturnParameters(Patient theMemberPatient, Coverage theCoverage) {
|
// save the resource
|
||||||
|
myConsentDao.create(theConsent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Parameters buildSuccessReturnParameters(Patient theMemberPatient, Coverage theCoverage, Consent theConsent) {
|
||||||
IBaseParameters parameters = ParametersUtil.newInstance(myFhirContext);
|
IBaseParameters parameters = ParametersUtil.newInstance(myFhirContext);
|
||||||
ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_MEMBER_PATIENT, theMemberPatient);
|
ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_MEMBER_PATIENT, theMemberPatient);
|
||||||
ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_NEW_COVERAGE, theCoverage);
|
ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_NEW_COVERAGE, theCoverage);
|
||||||
|
ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_CONSENT, theConsent);
|
||||||
return (Parameters) parameters;
|
return (Parameters) parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addMemberIdentifierToMemberPatient(Patient theMemberPatient, Identifier theNewIdentifier) {
|
public void addMemberIdentifierToMemberPatient(Patient theMemberPatient, Identifier theNewIdentifier) {
|
||||||
Coding coding = new Coding()
|
Coding coding = new Coding()
|
||||||
.setSystem(OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM)
|
.setSystem(OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM)
|
||||||
|
@ -145,6 +179,28 @@ public class MemberMatcherR4Helper {
|
||||||
theMemberPatient.addIdentifier(newIdentifier);
|
theMemberPatient.addIdentifier(newIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is a client id
|
||||||
|
* @param theConsent - the consent to modify
|
||||||
|
*/
|
||||||
|
private void addClientIdAsExtensionToConsentIfAvailable(Consent theConsent) {
|
||||||
|
if (myIConsentExtensionProvider != null) {
|
||||||
|
Collection<IBaseExtension> extensions = myIConsentExtensionProvider.getConsentExtension(theConsent);
|
||||||
|
|
||||||
|
for (IBaseExtension ext : extensions) {
|
||||||
|
if (ext instanceof Extension) {
|
||||||
|
theConsent.addExtension((Extension) ext);
|
||||||
|
} else {
|
||||||
|
Extension extR4 = new Extension();
|
||||||
|
extR4.setUrl(ext.getUrl());
|
||||||
|
extR4.setValue(ext.getValue());
|
||||||
|
theConsent.addExtension(extR4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ourLog.trace("{} extension(s) added to Consent", extensions.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<Patient> getBeneficiaryPatient(Coverage theCoverage) {
|
public Optional<Patient> getBeneficiaryPatient(Coverage theCoverage) {
|
||||||
if (theCoverage.getBeneficiaryTarget() == null && theCoverage.getBeneficiary() == null) {
|
if (theCoverage.getBeneficiaryTarget() == null && theCoverage.getBeneficiary() == null) {
|
||||||
|
@ -181,19 +237,62 @@ public class MemberMatcherR4Helper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
StringOrListParam familyName = new StringOrListParam();
|
StringOrListParam familyName = new StringOrListParam();
|
||||||
for (HumanName name: thePatientToMatch.getName()) {
|
for (HumanName name : thePatientToMatch.getName()) {
|
||||||
familyName.addOr(new StringParam(name.getFamily()));
|
familyName.addOr(new StringParam(name.getFamily()));
|
||||||
}
|
}
|
||||||
SearchParameterMap map = new SearchParameterMap()
|
SearchParameterMap map = new SearchParameterMap()
|
||||||
.add("family", familyName)
|
.add("family", familyName)
|
||||||
.add("birthdate", new DateParam(thePatientToMatch.getBirthDateElement().getValueAsString()));
|
.add("birthdate", new DateParam(thePatientToMatch.getBirthDateElement().getValueAsString()));
|
||||||
ca.uhn.fhir.rest.api.server.IBundleProvider bundle = myPatientDao.search(map);
|
ca.uhn.fhir.rest.api.server.IBundleProvider bundle = myPatientDao.search(map);
|
||||||
for (IBaseResource patientResource: bundle.getAllResources()) {
|
for (IBaseResource patientResource : bundle.getAllResources()) {
|
||||||
IIdType patientId = patientResource.getIdElement().toUnqualifiedVersionless();
|
IIdType patientId = patientResource.getIdElement().toUnqualifiedVersionless();
|
||||||
if ( patientId.getValue().equals(thePatientFromContract.getIdElement().toUnqualifiedVersionless().getValue())) {
|
if (patientId.getValue().equals(thePatientFromContract.getIdElement().toUnqualifiedVersionless().getValue())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean validConsentDataAccess(Consent theConsent) {
|
||||||
|
if (theConsent.getPolicy().isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (Consent.ConsentPolicyComponent policyComponent: theConsent.getPolicy()) {
|
||||||
|
if (policyComponent.getUri() == null || !validConsentPolicy(policyComponent.getUri())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is filtering the Consent policy data. The rule is specified in
|
||||||
|
* https://build.fhir.org/ig/HL7/davinci-ehrx/StructureDefinition-hrex-consent.html#notes
|
||||||
|
*/
|
||||||
|
private boolean validConsentPolicy(String thePolicyUri) {
|
||||||
|
String policyTypes = StringUtils.substringAfterLast(thePolicyUri, "#");
|
||||||
|
if (policyTypes.equals(CONSENT_POLICY_SENSITIVE_TYPE)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (policyTypes.equals(CONSENT_POLICY_REGULAR_TYPE) && myRegularFilterSupported) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addIdentifierToConsent(Consent theConsent) {
|
||||||
|
String consentId = UUID.randomUUID().toString();
|
||||||
|
Identifier consentIdentifier = new Identifier().setSystem(CONSENT_IDENTIFIER_CODE_SYSTEM).setValue(consentId);
|
||||||
|
theConsent.addIdentifier(consentIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegularFilterSupported(boolean theRegularFilterSupported) {
|
||||||
|
myRegularFilterSupported = theRegularFilterSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateConsentPatientAndPerformer(Consent theConsent, Patient thePatient) {
|
||||||
|
String patientRef = thePatient.getIdElement().toUnqualifiedVersionless().getValue();
|
||||||
|
theConsent.getPatient().setReference(patientRef);
|
||||||
|
theConsent.getPerformer().set(0, new Reference(patientRef));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,597 @@
|
||||||
|
package ca.uhn.fhir.jpa.provider;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
|
import ca.uhn.fhir.jpa.provider.r4.IConsentExtensionProvider;
|
||||||
|
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
|
||||||
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
||||||
|
import ch.qos.logback.classic.Level;
|
||||||
|
import ch.qos.logback.classic.Logger;
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.core.read.ListAppender;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.r4.model.Consent;
|
||||||
|
import org.hl7.fhir.r4.model.Coverage;
|
||||||
|
import org.hl7.fhir.r4.model.DateType;
|
||||||
|
import org.hl7.fhir.r4.model.Extension;
|
||||||
|
import org.hl7.fhir.r4.model.HumanName;
|
||||||
|
import org.hl7.fhir.r4.model.Identifier;
|
||||||
|
import org.hl7.fhir.r4.model.Parameters;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.Reference;
|
||||||
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Answers;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper.CONSENT_IDENTIFIER_CODE_SYSTEM;
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_CONSENT;
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.isA;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class MemberMatcherR4HelperTest {
|
||||||
|
|
||||||
|
private static final Logger ourLog = (Logger) LoggerFactory.getLogger(MemberMatcherR4Helper.class);
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ListAppender<ILoggingEvent> myAppender;
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
private final FhirContext myFhirContext = FhirContext.forR4();
|
||||||
|
@Mock
|
||||||
|
private IFhirResourceDao<Coverage> myCoverageDao;
|
||||||
|
@Mock
|
||||||
|
private IFhirResourceDao<Patient> myPatientDao;
|
||||||
|
@Mock
|
||||||
|
private IFhirResourceDao<Consent> myConsentDao;
|
||||||
|
|
||||||
|
private MemberMatcherR4Helper myHelper;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void before() {
|
||||||
|
myHelper = new MemberMatcherR4Helper(
|
||||||
|
myFhirContext,
|
||||||
|
myCoverageDao,
|
||||||
|
myPatientDao,
|
||||||
|
myConsentDao,
|
||||||
|
null // extension provider
|
||||||
|
);
|
||||||
|
|
||||||
|
ourLog.addAppender(myAppender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void after() {
|
||||||
|
ourLog.detachAppender(myAppender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mock private Coverage myCoverageToMatch;
|
||||||
|
@Mock private IBundleProvider myBundleProvider;
|
||||||
|
|
||||||
|
private final Coverage myMatchedCoverage = new Coverage()
|
||||||
|
.setBeneficiary(new Reference("Patient/123"));
|
||||||
|
private final Identifier myMatchingIdentifier = new Identifier()
|
||||||
|
.setSystem("identifier-system").setValue("identifier-value");
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
ArgumentCaptor<SearchParameterMap> mySearchParameterMapCaptor;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findMatchingCoverageMatchByIdReturnsMatched() {
|
||||||
|
when(myCoverageToMatch.getId()).thenReturn("cvg-to-match-id");
|
||||||
|
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
||||||
|
when(myBundleProvider.getAllResources()).thenReturn(Collections.singletonList(myMatchedCoverage));
|
||||||
|
|
||||||
|
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch);
|
||||||
|
|
||||||
|
assertEquals(Optional.of(myMatchedCoverage), result);
|
||||||
|
verify(myCoverageDao).search(mySearchParameterMapCaptor.capture());
|
||||||
|
SearchParameterMap spMap = mySearchParameterMapCaptor.getValue();
|
||||||
|
assertTrue(spMap.containsKey("_id"));
|
||||||
|
List<List<IQueryParameterType>> listListParams = spMap.get("_id");
|
||||||
|
assertEquals(1, listListParams.size());
|
||||||
|
assertEquals(1, listListParams.get(0).size());
|
||||||
|
IQueryParameterType param = listListParams.get(0).get(0);
|
||||||
|
assertEquals("cvg-to-match-id", param.getValueAsQueryToken(myFhirContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findMatchingCoverageMatchByIdentifierReturnsMatched() {
|
||||||
|
when(myCoverageToMatch.getId()).thenReturn("non-matching-id");
|
||||||
|
when(myCoverageToMatch.getIdentifier()).thenReturn(Collections.singletonList(myMatchingIdentifier));
|
||||||
|
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
||||||
|
when(myBundleProvider.getAllResources()).thenReturn(
|
||||||
|
Collections.emptyList(), Collections.singletonList(myMatchedCoverage));
|
||||||
|
|
||||||
|
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch);
|
||||||
|
|
||||||
|
assertEquals(Optional.of(myMatchedCoverage), result);
|
||||||
|
verify(myCoverageDao, times(2)).search(mySearchParameterMapCaptor.capture());
|
||||||
|
List<SearchParameterMap> spMap = mySearchParameterMapCaptor.getAllValues();
|
||||||
|
assertTrue(spMap.get(0).containsKey("_id"));
|
||||||
|
assertTrue(spMap.get(1).containsKey("identifier"));
|
||||||
|
List<List<IQueryParameterType>> listListParams = spMap.get(1).get("identifier");
|
||||||
|
assertEquals(1, listListParams.size());
|
||||||
|
assertEquals(1, listListParams.get(0).size());
|
||||||
|
IQueryParameterType param = listListParams.get(0).get(0);
|
||||||
|
assertEquals(myMatchingIdentifier.getSystem() + "|" + myMatchingIdentifier.getValue(),
|
||||||
|
param.getValueAsQueryToken(myFhirContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findMatchingCoverageNoMatchReturnsEmpty() {
|
||||||
|
when(myCoverageToMatch.getId()).thenReturn("non-matching-id");
|
||||||
|
when(myCoverageToMatch.getIdentifier()).thenReturn(Collections.singletonList(myMatchingIdentifier));
|
||||||
|
when(myCoverageDao.search(any(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
||||||
|
when(myBundleProvider.getAllResources()).thenReturn(Collections.emptyList(), Collections.emptyList());
|
||||||
|
|
||||||
|
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch);
|
||||||
|
|
||||||
|
assertFalse(result.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void buildSuccessReturnParameters() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
Coverage coverage = new Coverage();
|
||||||
|
Consent consent = new Consent();
|
||||||
|
|
||||||
|
Parameters result = myHelper.buildSuccessReturnParameters(patient, coverage, consent);
|
||||||
|
|
||||||
|
assertEquals(PARAM_MEMBER_PATIENT, result.getParameter().get(0).getName());
|
||||||
|
assertEquals(patient, result.getParameter().get(0).getResource());
|
||||||
|
|
||||||
|
assertEquals(PARAM_NEW_COVERAGE, result.getParameter().get(1).getName());
|
||||||
|
assertEquals(coverage, result.getParameter().get(1).getResource());
|
||||||
|
|
||||||
|
assertEquals(PARAM_CONSENT, result.getParameter().get(2).getName());
|
||||||
|
assertEquals(consent, result.getParameter().get(2).getResource());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void addMemberIdentifierToMemberPatient() {
|
||||||
|
Identifier originalIdentifier = new Identifier()
|
||||||
|
.setSystem("original-identifier-system").setValue("original-identifier-value");
|
||||||
|
|
||||||
|
Identifier newIdentifier = new Identifier()
|
||||||
|
.setSystem("new-identifier-system").setValue("new-identifier-value");
|
||||||
|
|
||||||
|
Patient patient = new Patient().setIdentifier(Lists.newArrayList(originalIdentifier));
|
||||||
|
|
||||||
|
myHelper.addMemberIdentifierToMemberPatient(patient, newIdentifier);
|
||||||
|
|
||||||
|
assertEquals(2, patient.getIdentifier().size());
|
||||||
|
|
||||||
|
assertEquals("original-identifier-system", patient.getIdentifier().get(0).getSystem());
|
||||||
|
assertEquals("original-identifier-value", patient.getIdentifier().get(0).getValue());
|
||||||
|
|
||||||
|
assertEquals("new-identifier-system", patient.getIdentifier().get(1).getSystem());
|
||||||
|
assertEquals("new-identifier-value", patient.getIdentifier().get(1).getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing multiple scenarios for getting patient resource from coverage's plan beneficiary
|
||||||
|
*/
|
||||||
|
@Nested
|
||||||
|
public class TestGetBeneficiaryPatient {
|
||||||
|
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private Coverage coverage;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noBeneficiaryOrBeneficiaryTargetReturnsEmpty() {
|
||||||
|
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||||
|
when(coverage.getBeneficiary()).thenReturn(null);
|
||||||
|
|
||||||
|
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||||
|
|
||||||
|
assertFalse(result.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void beneficiaryTargetWithNoIdentifierReturnsEmpty() {
|
||||||
|
when(coverage.getBeneficiary()).thenReturn(null);
|
||||||
|
when(coverage.getBeneficiaryTarget()).thenReturn(new Patient());
|
||||||
|
|
||||||
|
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||||
|
|
||||||
|
assertFalse(result.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void beneficiaryTargetWithIdentifierReturnsBeneficiary() {
|
||||||
|
Patient patient = new Patient().setIdentifier(Collections.singletonList(new Identifier()));
|
||||||
|
when(coverage.getBeneficiaryTarget()).thenReturn(patient);
|
||||||
|
|
||||||
|
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||||
|
|
||||||
|
assertTrue(result.isPresent());
|
||||||
|
assertEquals(patient, result.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void beneficiaryReferenceResourceReturnsBeneficiary() {
|
||||||
|
Patient patient = new Patient().setIdentifier(Collections.singletonList(new Identifier()));
|
||||||
|
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||||
|
when(coverage.getBeneficiary().getResource()).thenReturn(patient);
|
||||||
|
|
||||||
|
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||||
|
|
||||||
|
assertTrue(result.isPresent());
|
||||||
|
assertEquals(patient, result.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void beneficiaryReferenceNoResourceOrReferenceReturnsEmpty() {
|
||||||
|
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||||
|
when(coverage.getBeneficiary()).thenReturn(new Reference());
|
||||||
|
|
||||||
|
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||||
|
|
||||||
|
assertFalse(result.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void beneficiaryReferenceReferenceReturnsReadPatient() {
|
||||||
|
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||||
|
when(coverage.getBeneficiary().getResource()).thenReturn(null);
|
||||||
|
when(coverage.getBeneficiary().getReference()).thenReturn("patient-id");
|
||||||
|
|
||||||
|
myHelper.getBeneficiaryPatient(coverage);
|
||||||
|
|
||||||
|
verify(myPatientDao).read(new IdDt("patient-id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing multiple scenarios for validity of Patient Member parameter
|
||||||
|
*/
|
||||||
|
@Nested
|
||||||
|
public class TestValidPatientMember {
|
||||||
|
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private Coverage coverage;
|
||||||
|
private Patient patient;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noPatientFoundFromContractReturnsFalse() {
|
||||||
|
boolean result = myHelper.validPatientMember(null, patient);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noPatientFoundFromPatientMemberReturnsFalse() {
|
||||||
|
boolean result = myHelper.validPatientMember(patient, null);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noMatchingFamilyNameReturnsFalse() {
|
||||||
|
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "2020-01-01");
|
||||||
|
Patient patientFromContractFound = getPatientWithIDParm("A123", "Smith", "2020-01-01");
|
||||||
|
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
||||||
|
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
||||||
|
return provider;
|
||||||
|
});
|
||||||
|
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noMatchingBirthdayReturnsFalse() {
|
||||||
|
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "1990-01-01");
|
||||||
|
Patient patientFromContractFound = getPatientWithIDParm("A123", "Person", "2020-01-01");
|
||||||
|
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
||||||
|
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
||||||
|
return provider;
|
||||||
|
});
|
||||||
|
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noMatchingFieldsReturnsFalse() {
|
||||||
|
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "1990-01-01");
|
||||||
|
Patient patientFromContractFound = getPatientWithIDParm("A123", "Smith", "2020-01-01");
|
||||||
|
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
||||||
|
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
||||||
|
return provider;
|
||||||
|
});
|
||||||
|
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void patientMatchingReturnTrue() {
|
||||||
|
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "2020-01-01");
|
||||||
|
Patient patientFromContractFound = getPatientWithIDParm("A123", "Person", "2020-01-01");
|
||||||
|
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
||||||
|
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(patientFromContractFound));
|
||||||
|
return provider;
|
||||||
|
});
|
||||||
|
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Patient getPatientWithNoIDParm(String familyName, String birthdate) {
|
||||||
|
Patient patient = new Patient().setName(Lists.newArrayList(new HumanName()
|
||||||
|
.setUse(HumanName.NameUse.OFFICIAL).setFamily(familyName)))
|
||||||
|
.setBirthDateElement(new DateType(birthdate));
|
||||||
|
return patient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Patient getPatientWithIDParm(String id, String familyName, String birthdate) {
|
||||||
|
Patient patient = getPatientWithNoIDParm(familyName, birthdate);
|
||||||
|
patient.setId(id);
|
||||||
|
return patient;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing multiple scenarios for consent's policy data that is defined in
|
||||||
|
* https://build.fhir.org/ig/HL7/davinci-ehrx/StructureDefinition-hrex-consent.html#notes
|
||||||
|
*/
|
||||||
|
@Nested
|
||||||
|
public class TestValidvalidConsentDataAccess {
|
||||||
|
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private Coverage coverage;
|
||||||
|
private Patient patient;
|
||||||
|
private Consent consent;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noConsentProfileFoundReturnsFalse() {
|
||||||
|
consent = new Consent();
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void noDataAccessValueProvidedReturnsFalse() {
|
||||||
|
consent = getConsent();
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void wrongDataAccessValueProvidedReturnsFalse() {
|
||||||
|
consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#access_data"));
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void regularDataAccessWithRegularNotAllowedReturnsFalse() {
|
||||||
|
consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#regular"));
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void regularDataAccessWithRegularAllowedReturnsTrue() {
|
||||||
|
myHelper.setRegularFilterSupported(true);
|
||||||
|
consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#regular"));
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sensitiveDataAccessAllowedReturnsTrue() {
|
||||||
|
consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#sensitive"));
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void multipleSensitivePolicyDataAccessAllowedReturnsTrue() {
|
||||||
|
consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#sensitive"));
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#sensitive"));
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void multipleRegularPolicyDataAccessWithRegularAllowedReturnsTrue() {
|
||||||
|
myHelper.setRegularFilterSupported(true);
|
||||||
|
consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#regular"));
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#regular"));
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void multipleMixedPolicyDataAccessWithRegularNotAllowedReturnsFalse() {
|
||||||
|
consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#regular"));
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#sensitive"));
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void multipleMixedPolicyDataAccessWithRegularAllowedReturnsTrue() {
|
||||||
|
myHelper.setRegularFilterSupported(true);
|
||||||
|
consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#regular"));
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#sensitive"));
|
||||||
|
boolean result = myHelper.validConsentDataAccess(consent);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Consent getConsent() {
|
||||||
|
Consent consent = new Consent();
|
||||||
|
consent.getPerformer().add(new Reference("Patient/1"));
|
||||||
|
return consent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Consent.ConsentPolicyComponent constructConsentPolicyComponent(String uriAccess) {
|
||||||
|
String uri = "http://hl7.org/fhir/us/davinci-hrex/StructureDefinition-hrex-consent.html";
|
||||||
|
return new Consent.ConsentPolicyComponent().setUri(uri + uriAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Patient createPatientForMemberMatchUpdate() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("Patient/RED");
|
||||||
|
|
||||||
|
return patient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyConsentUpdatedAfterMemberMatch(
|
||||||
|
Consent theConsent,
|
||||||
|
Patient thePatient,
|
||||||
|
List<Extension> theSavedExtensions
|
||||||
|
) {
|
||||||
|
// check consent identifier
|
||||||
|
assertEquals(1, theConsent.getIdentifier().size());
|
||||||
|
assertEquals(CONSENT_IDENTIFIER_CODE_SYSTEM, theConsent.getIdentifier().get(0).getSystem());
|
||||||
|
assertNotNull(theConsent.getIdentifier().get(0).getValue());
|
||||||
|
|
||||||
|
// check consent patient info
|
||||||
|
String patientRef = thePatient.getIdElement().toUnqualifiedVersionless().getValue();
|
||||||
|
assertEquals(patientRef, theConsent.getPatient().getReference());
|
||||||
|
assertEquals(patientRef, theConsent.getPerformer().get(0).getReference());
|
||||||
|
|
||||||
|
if (!theSavedExtensions.isEmpty()) {
|
||||||
|
// check consent extensions
|
||||||
|
assertNotNull(theConsent.getExtension());
|
||||||
|
assertEquals(theSavedExtensions.size(), theConsent.getExtension().size());
|
||||||
|
for (Extension ext : theSavedExtensions) {
|
||||||
|
boolean found = false;
|
||||||
|
for (Extension consentExt : theConsent.getExtension()) {
|
||||||
|
if (consentExt.getUrl().equals(ext.getUrl())
|
||||||
|
&& consentExt.getValue().equals(ext.getValue())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(found,
|
||||||
|
"Extension " + ext.getUrl() + "|" + ext.getValue().toString() + " not found"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
public class MemberMatchWithoutConsentProvider {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateConsentForMemberMatch_noProvider_addsIdentifierUpdatePatientButNotExtensionAndSaves() {
|
||||||
|
// setup
|
||||||
|
Consent consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#sensitive"));
|
||||||
|
Patient patient = createPatientForMemberMatchUpdate();
|
||||||
|
|
||||||
|
ourLog.setLevel(Level.TRACE);
|
||||||
|
|
||||||
|
// test
|
||||||
|
myHelper.updateConsentForMemberMatch(consent, patient);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
verify(myAppender, never())
|
||||||
|
.doAppend(any(ILoggingEvent.class));
|
||||||
|
|
||||||
|
ArgumentCaptor<Consent> consentCaptor = ArgumentCaptor.forClass(Consent.class);
|
||||||
|
verify(myConsentDao).create(consentCaptor.capture());
|
||||||
|
Consent saved = consentCaptor.getValue();
|
||||||
|
verifyConsentUpdatedAfterMemberMatch(saved, patient, Collections.emptyList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
public class MemberMatchWithConsentProvider {
|
||||||
|
@Mock
|
||||||
|
private IConsentExtensionProvider myExtensionProvider;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void before() {
|
||||||
|
myHelper = new MemberMatcherR4Helper(
|
||||||
|
myFhirContext,
|
||||||
|
myCoverageDao,
|
||||||
|
myPatientDao,
|
||||||
|
myConsentDao,
|
||||||
|
myExtensionProvider
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addClientIdAsExtensionToConsentIfAvailable_withProvider_addsExtensionAndSaves() {
|
||||||
|
// setup
|
||||||
|
Consent consent = getConsent();
|
||||||
|
consent.addPolicy(constructConsentPolicyComponent("#sensitive"));
|
||||||
|
consent.setId("Consent/RED");
|
||||||
|
Extension ext = new Extension();
|
||||||
|
ext.setUrl("http://example.com");
|
||||||
|
ext.setValue(new StringType("value"));
|
||||||
|
Patient patient = createPatientForMemberMatchUpdate();
|
||||||
|
|
||||||
|
ourLog.setLevel(Level.TRACE);
|
||||||
|
|
||||||
|
// when
|
||||||
|
when(myExtensionProvider.getConsentExtension(any(IBaseResource.class)))
|
||||||
|
.thenReturn(Collections.singleton(ext));
|
||||||
|
|
||||||
|
// test
|
||||||
|
myHelper.updateConsentForMemberMatch(consent, patient);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
ArgumentCaptor<Consent> consentCaptor = ArgumentCaptor.forClass(Consent.class);
|
||||||
|
verify(myConsentDao).create(consentCaptor.capture());
|
||||||
|
Consent saved = consentCaptor.getValue();
|
||||||
|
verifyConsentUpdatedAfterMemberMatch(saved, patient, Collections.emptyList());
|
||||||
|
|
||||||
|
ArgumentCaptor<ILoggingEvent> eventCaptor = ArgumentCaptor.forClass(ILoggingEvent.class);
|
||||||
|
verify(myAppender).doAppend(eventCaptor.capture());
|
||||||
|
ILoggingEvent event = eventCaptor.getValue();
|
||||||
|
assertEquals("1 extension(s) added to Consent", event.getFormattedMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,11 @@ public class JpaConstants {
|
||||||
*/
|
*/
|
||||||
public static final String OPERATION_LASTN = "$lastn";
|
public static final String OPERATION_LASTN = "$lastn";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation name for the $member-match operation
|
||||||
|
*/
|
||||||
|
public static final String OPERATION_MEMBER_MATCH = "$member-match";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameter for the $export operation
|
* Parameter for the $export operation
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -1,327 +0,0 @@
|
||||||
package ca.uhn.fhir.jpa.provider.r4;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
|
||||||
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import org.hl7.fhir.r4.model.Coverage;
|
|
||||||
import org.hl7.fhir.r4.model.DateType;
|
|
||||||
import org.hl7.fhir.r4.model.HumanName;
|
|
||||||
import org.hl7.fhir.r4.model.Identifier;
|
|
||||||
import org.hl7.fhir.r4.model.Parameters;
|
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Nested;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Answers;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Captor;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
|
||||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.isA;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
class MemberMatcherR4HelperTest {
|
|
||||||
|
|
||||||
private final FhirContext myFhirContext = FhirContext.forR4();
|
|
||||||
@Mock private IFhirResourceDao<Coverage> myCoverageDao;
|
|
||||||
@Mock private IFhirResourceDao<Patient> myPatientDao;
|
|
||||||
|
|
||||||
private MemberMatcherR4Helper myTestedHelper;
|
|
||||||
|
|
||||||
@Mock private Coverage myCoverageToMatch;
|
|
||||||
@Mock private IBundleProvider myBundleProvider;
|
|
||||||
|
|
||||||
private final Coverage myMatchedCoverage = new Coverage()
|
|
||||||
.setBeneficiary(new Reference("Patient/123"));
|
|
||||||
private final Identifier myMatchingIdentifier = new Identifier()
|
|
||||||
.setSystem("identifier-system").setValue("identifier-value");
|
|
||||||
|
|
||||||
@Captor ArgumentCaptor<SearchParameterMap> mySearchParameterMapCaptor;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void beforeEach() {
|
|
||||||
myTestedHelper = new MemberMatcherR4Helper(myFhirContext);
|
|
||||||
|
|
||||||
// @InjectMocks didn't work
|
|
||||||
ReflectionTestUtils.setField(myTestedHelper, "myCoverageDao", myCoverageDao);
|
|
||||||
ReflectionTestUtils.setField(myTestedHelper, "myPatientDao", myPatientDao);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void findMatchingCoverageMatchByIdReturnsMatched() {
|
|
||||||
when(myCoverageToMatch.getId()).thenReturn("cvg-to-match-id");
|
|
||||||
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
|
||||||
when(myBundleProvider.getAllResources()).thenReturn(Collections.singletonList(myMatchedCoverage));
|
|
||||||
|
|
||||||
Optional<Coverage> result = myTestedHelper.findMatchingCoverage(myCoverageToMatch);
|
|
||||||
|
|
||||||
assertEquals(Optional.of(myMatchedCoverage), result);
|
|
||||||
verify(myCoverageDao).search(mySearchParameterMapCaptor.capture());
|
|
||||||
SearchParameterMap spMap = mySearchParameterMapCaptor.getValue();
|
|
||||||
assertTrue(spMap.containsKey("_id"));
|
|
||||||
List<List<IQueryParameterType>> listListParams = spMap.get("_id");
|
|
||||||
assertEquals(1, listListParams.size());
|
|
||||||
assertEquals(1, listListParams.get(0).size());
|
|
||||||
IQueryParameterType param = listListParams.get(0).get(0);
|
|
||||||
assertEquals("cvg-to-match-id", param.getValueAsQueryToken(myFhirContext));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void findMatchingCoverageMatchByIdentifierReturnsMatched() {
|
|
||||||
when(myCoverageToMatch.getId()).thenReturn("non-matching-id");
|
|
||||||
when(myCoverageToMatch.getIdentifier()).thenReturn(Collections.singletonList(myMatchingIdentifier));
|
|
||||||
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
|
||||||
when(myBundleProvider.getAllResources()).thenReturn(
|
|
||||||
Collections.emptyList(), Collections.singletonList(myMatchedCoverage));
|
|
||||||
|
|
||||||
Optional<Coverage> result = myTestedHelper.findMatchingCoverage(myCoverageToMatch);
|
|
||||||
|
|
||||||
assertEquals(Optional.of(myMatchedCoverage), result);
|
|
||||||
verify(myCoverageDao, times(2)).search(mySearchParameterMapCaptor.capture());
|
|
||||||
List<SearchParameterMap> spMap = mySearchParameterMapCaptor.getAllValues();
|
|
||||||
assertTrue(spMap.get(0).containsKey("_id"));
|
|
||||||
assertTrue(spMap.get(1).containsKey("identifier"));
|
|
||||||
List<List<IQueryParameterType>> listListParams = spMap.get(1).get("identifier");
|
|
||||||
assertEquals(1, listListParams.size());
|
|
||||||
assertEquals(1, listListParams.get(0).size());
|
|
||||||
IQueryParameterType param = listListParams.get(0).get(0);
|
|
||||||
assertEquals(myMatchingIdentifier.getSystem() + "|" + myMatchingIdentifier.getValue(),
|
|
||||||
param.getValueAsQueryToken(myFhirContext));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void findMatchingCoverageNoMatchReturnsEmpty() {
|
|
||||||
when(myCoverageToMatch.getId()).thenReturn("non-matching-id");
|
|
||||||
when(myCoverageToMatch.getIdentifier()).thenReturn(Collections.singletonList(myMatchingIdentifier));
|
|
||||||
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
|
||||||
when(myBundleProvider.getAllResources()).thenReturn(Collections.emptyList(), Collections.emptyList());
|
|
||||||
|
|
||||||
Optional<Coverage> result = myTestedHelper.findMatchingCoverage(myCoverageToMatch);
|
|
||||||
|
|
||||||
assertFalse(result.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void buildSuccessReturnParameters() {
|
|
||||||
Patient patient = new Patient();
|
|
||||||
Coverage coverage = new Coverage();
|
|
||||||
|
|
||||||
Parameters result = myTestedHelper.buildSuccessReturnParameters(patient, coverage);
|
|
||||||
|
|
||||||
assertEquals(PARAM_MEMBER_PATIENT, result.getParameter().get(0).getName());
|
|
||||||
assertEquals(patient, result.getParameter().get(0).getResource());
|
|
||||||
|
|
||||||
assertEquals(PARAM_NEW_COVERAGE, result.getParameter().get(1).getName());
|
|
||||||
assertEquals(coverage, result.getParameter().get(1).getResource());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void addMemberIdentifierToMemberPatient() {
|
|
||||||
Identifier originalIdentifier = new Identifier()
|
|
||||||
.setSystem("original-identifier-system").setValue("original-identifier-value");
|
|
||||||
|
|
||||||
Identifier newIdentifier = new Identifier()
|
|
||||||
.setSystem("new-identifier-system").setValue("new-identifier-value");
|
|
||||||
|
|
||||||
Patient patient = new Patient().setIdentifier(Lists.newArrayList(originalIdentifier));
|
|
||||||
|
|
||||||
myTestedHelper.addMemberIdentifierToMemberPatient(patient, newIdentifier);
|
|
||||||
|
|
||||||
assertEquals(2, patient.getIdentifier().size());
|
|
||||||
|
|
||||||
assertEquals("original-identifier-system", patient.getIdentifier().get(0).getSystem());
|
|
||||||
assertEquals("original-identifier-value", patient.getIdentifier().get(0).getValue());
|
|
||||||
|
|
||||||
assertEquals("new-identifier-system", patient.getIdentifier().get(1).getSystem());
|
|
||||||
assertEquals("new-identifier-value", patient.getIdentifier().get(1).getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
public class TestGetBeneficiaryPatient {
|
|
||||||
|
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
|
||||||
private Coverage coverage;
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void noBeneficiaryOrBeneficiaryTargetReturnsEmpty() {
|
|
||||||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
|
||||||
when(coverage.getBeneficiary()).thenReturn(null);
|
|
||||||
|
|
||||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
|
||||||
|
|
||||||
assertFalse(result.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void beneficiaryTargetWithNoIdentifierReturnsEmpty() {
|
|
||||||
when(coverage.getBeneficiary()).thenReturn(null);
|
|
||||||
when(coverage.getBeneficiaryTarget()).thenReturn(new Patient());
|
|
||||||
|
|
||||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
|
||||||
|
|
||||||
assertFalse(result.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void beneficiaryTargetWithIdentifierReturnsBeneficiary() {
|
|
||||||
Patient patient = new Patient().setIdentifier(Collections.singletonList(new Identifier()));
|
|
||||||
when(coverage.getBeneficiaryTarget()).thenReturn(patient);
|
|
||||||
|
|
||||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
|
||||||
|
|
||||||
assertTrue(result.isPresent());
|
|
||||||
assertEquals(patient, result.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void beneficiaryReferenceResourceReturnsBeneficiary() {
|
|
||||||
Patient patient = new Patient().setIdentifier(Collections.singletonList(new Identifier()));
|
|
||||||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
|
||||||
when(coverage.getBeneficiary().getResource()).thenReturn(patient);
|
|
||||||
|
|
||||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
|
||||||
|
|
||||||
assertTrue(result.isPresent());
|
|
||||||
assertEquals(patient, result.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void beneficiaryReferenceNoResourceOrReferenceReturnsEmpty() {
|
|
||||||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
|
||||||
when(coverage.getBeneficiary()).thenReturn(new Reference());
|
|
||||||
|
|
||||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
|
||||||
|
|
||||||
assertFalse(result.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void beneficiaryReferenceReferenceReturnsReadPatient() {
|
|
||||||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
|
||||||
when(coverage.getBeneficiary().getResource()).thenReturn(null);
|
|
||||||
when(coverage.getBeneficiary().getReference()).thenReturn("patient-id");
|
|
||||||
|
|
||||||
myTestedHelper.getBeneficiaryPatient(coverage);
|
|
||||||
|
|
||||||
verify(myPatientDao).read(new IdDt("patient-id"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
public class TestValidPatientMember {
|
|
||||||
|
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
|
||||||
private Coverage coverage;
|
|
||||||
private Patient patient;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void noPatientFoundFromContractReturnsFalse() {
|
|
||||||
boolean result = myTestedHelper.validPatientMember(null, patient);
|
|
||||||
assertFalse(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void noPatientFoundFromPatientMemberReturnsFalse() {
|
|
||||||
boolean result = myTestedHelper.validPatientMember(patient, null);
|
|
||||||
assertFalse(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void noMatchingFamilyNameReturnsFalse() {
|
|
||||||
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "2020-01-01");
|
|
||||||
Patient patientFromContractFound = getPatientWithIDParm("A123", "Smith", "2020-01-01");
|
|
||||||
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
|
||||||
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
|
||||||
return provider;
|
|
||||||
});
|
|
||||||
boolean result = myTestedHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
|
||||||
assertFalse(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void noMatchingBirthdayReturnsFalse() {
|
|
||||||
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "1990-01-01");
|
|
||||||
Patient patientFromContractFound = getPatientWithIDParm("A123", "Person", "2020-01-01");
|
|
||||||
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
|
||||||
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
|
||||||
return provider;
|
|
||||||
});
|
|
||||||
boolean result = myTestedHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
|
||||||
assertFalse(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void noMatchingFieldsReturnsFalse() {
|
|
||||||
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "1990-01-01");
|
|
||||||
Patient patientFromContractFound = getPatientWithIDParm("A123", "Smith", "2020-01-01");
|
|
||||||
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
|
||||||
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
|
||||||
return provider;
|
|
||||||
});
|
|
||||||
boolean result = myTestedHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
|
||||||
assertFalse(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void patientMatchingReturnTrue() {
|
|
||||||
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "2020-01-01");
|
|
||||||
Patient patientFromContractFound = getPatientWithIDParm("A123", "Person", "2020-01-01");
|
|
||||||
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
|
||||||
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(patientFromContractFound));
|
|
||||||
return provider;
|
|
||||||
});
|
|
||||||
boolean result = myTestedHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
|
||||||
assertTrue(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Patient getPatientWithNoIDParm(String familyName, String birthdate) {
|
|
||||||
Patient patient = new Patient().setName(Lists.newArrayList(new HumanName()
|
|
||||||
.setUse(HumanName.NameUse.OFFICIAL).setFamily(familyName)))
|
|
||||||
.setBirthDateElement(new DateType(birthdate));
|
|
||||||
return patient;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Patient getPatientWithIDParm(String id, String familyName, String birthdate) {
|
|
||||||
Patient patient = getPatientWithNoIDParm(familyName, birthdate);
|
|
||||||
patient.setId(id);
|
|
||||||
return patient;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ import ca.uhn.fhir.parser.StrictErrorHandler;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.client.apache.ResourceEntity;
|
import ca.uhn.fhir.rest.client.apache.ResourceEntity;
|
||||||
import ca.uhn.fhir.rest.param.DateParam;
|
|
||||||
import ca.uhn.fhir.util.ParametersUtil;
|
import ca.uhn.fhir.util.ParametersUtil;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
@ -14,12 +13,12 @@ import org.apache.http.client.methods.HttpPost;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
import org.hl7.fhir.r4.model.Coding;
|
||||||
|
import org.hl7.fhir.r4.model.Consent;
|
||||||
import org.hl7.fhir.r4.model.Coverage;
|
import org.hl7.fhir.r4.model.Coverage;
|
||||||
import org.hl7.fhir.r4.model.DateType;
|
import org.hl7.fhir.r4.model.DateType;
|
||||||
import org.hl7.fhir.r4.model.Enumerations;
|
import org.hl7.fhir.r4.model.Enumerations;
|
||||||
import org.hl7.fhir.r4.model.HumanName;
|
import org.hl7.fhir.r4.model.HumanName;
|
||||||
import org.hl7.fhir.r4.model.Identifier;
|
import org.hl7.fhir.r4.model.Identifier;
|
||||||
import org.hl7.fhir.r4.model.Organization;
|
|
||||||
import org.hl7.fhir.r4.model.Parameters;
|
import org.hl7.fhir.r4.model.Parameters;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
import org.hl7.fhir.r4.model.Reference;
|
||||||
|
@ -27,14 +26,20 @@ import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_CONSENT_PATIENT_REFERENCE;
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_CONSENT_PERFORMER_REFERENCE;
|
||||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT_BIRTHDATE;
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT_NAME;
|
||||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
||||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_OLD_COVERAGE;
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_OLD_COVERAGE;
|
||||||
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_CONSENT;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
@ -51,11 +56,20 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
private static final String EXISTING_COVERAGE_IDENT_VALUE = "U1234567890";
|
private static final String EXISTING_COVERAGE_IDENT_VALUE = "U1234567890";
|
||||||
private static final String EXISTING_COVERAGE_PATIENT_IDENT_SYSTEM = "http://oldhealthplan.example.com";
|
private static final String EXISTING_COVERAGE_PATIENT_IDENT_SYSTEM = "http://oldhealthplan.example.com";
|
||||||
private static final String EXISTING_COVERAGE_PATIENT_IDENT_VALUE = "DHU-55678";
|
private static final String EXISTING_COVERAGE_PATIENT_IDENT_VALUE = "DHU-55678";
|
||||||
|
private static final String CONSENT_POLICY_SENSITIVE_DATA_URI = "http://hl7.org/fhir/us/davinci-hrex/StructureDefinition-hrex-consent.html#sensitive";
|
||||||
|
private static final String CONSENT_POLICY_REGULAR_DATA_URI = "http://hl7.org/fhir/us/davinci-hrex/StructureDefinition-hrex-consent.html#regular";
|
||||||
|
|
||||||
private Identifier ourExistingCoverageIdentifier;
|
private Identifier ourExistingCoverageIdentifier;
|
||||||
private Patient myPatient;
|
private Patient myPatient;
|
||||||
private Coverage oldCoverage; // Old Coverage (must match field)
|
private Coverage oldCoverage; // Old Coverage (must match field)
|
||||||
private Coverage newCoverage; // New Coverage (must return unchanged)
|
private Coverage newCoverage; // New Coverage (must return unchanged)
|
||||||
|
private Consent myConsent;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MemberMatcherR4Helper myMemberMatcherR4Helper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MemberMatchR4ResourceProvider theMemberMatchR4ResourceProvider;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void beforeDisableResultReuse() {
|
public void beforeDisableResultReuse() {
|
||||||
|
@ -70,6 +84,7 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
myDaoConfig.setEverythingIncludesFetchPageSize(new DaoConfig().getEverythingIncludesFetchPageSize());
|
myDaoConfig.setEverythingIncludesFetchPageSize(new DaoConfig().getEverythingIncludesFetchPageSize());
|
||||||
myDaoConfig.setSearchPreFetchThresholds(new DaoConfig().getSearchPreFetchThresholds());
|
myDaoConfig.setSearchPreFetchThresholds(new DaoConfig().getSearchPreFetchThresholds());
|
||||||
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
||||||
|
ourRestServer.unregisterProvider(theMemberMatchR4ResourceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -90,6 +105,15 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
newCoverage = (Coverage) new Coverage()
|
newCoverage = (Coverage) new Coverage()
|
||||||
.setIdentifier(Lists.newArrayList(new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")))
|
.setIdentifier(Lists.newArrayList(new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")))
|
||||||
.setId("AA87654");
|
.setId("AA87654");
|
||||||
|
|
||||||
|
myConsent = new Consent()
|
||||||
|
.setStatus(Consent.ConsentState.ACTIVE)
|
||||||
|
.setScope(new CodeableConcept().addCoding(new Coding("http://terminology.hl7.org/CodeSystem/consentscope", "patient-privacy", null)))
|
||||||
|
.addPolicy(new Consent.ConsentPolicyComponent().setUri(CONSENT_POLICY_SENSITIVE_DATA_URI))
|
||||||
|
.setPatient(new Reference("Patient/A123"))
|
||||||
|
.addPerformer(new Reference("Patient/A123"));
|
||||||
|
ourRestServer.registerProvider(theMemberMatchR4ResourceProvider);
|
||||||
|
myMemberMatcherR4Helper.setRegularFilterSupported(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createCoverageWithBeneficiary(
|
private void createCoverageWithBeneficiary(
|
||||||
|
@ -125,12 +149,11 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
myClient.create().resource(ourExistingCoverage).execute().getId().toUnqualifiedVersionless().getValue();
|
myClient.create().resource(ourExistingCoverage).execute().getId().toUnqualifiedVersionless().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMemberMatchByCoverageId() throws Exception {
|
public void testMemberMatchByCoverageId() throws Exception {
|
||||||
createCoverageWithBeneficiary(true, true);
|
createCoverageWithBeneficiary(true, true);
|
||||||
|
|
||||||
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage);
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
Parameters parametersResponse = performOperation(ourServerBase + ourQuery,
|
Parameters parametersResponse = performOperation(ourServerBase + ourQuery,
|
||||||
EncodingEnum.JSON, inputParameters);
|
EncodingEnum.JSON, inputParameters);
|
||||||
|
|
||||||
|
@ -143,7 +166,7 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
public void testCoverageNoBeneficiaryReturns422() throws Exception {
|
public void testCoverageNoBeneficiaryReturns422() throws Exception {
|
||||||
createCoverageWithBeneficiary(false, false);
|
createCoverageWithBeneficiary(false, false);
|
||||||
|
|
||||||
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage);
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
"Could not find beneficiary for coverage.");
|
"Could not find beneficiary for coverage.");
|
||||||
}
|
}
|
||||||
|
@ -152,7 +175,7 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
public void testCoverageBeneficiaryNoIdentifierReturns422() throws Exception {
|
public void testCoverageBeneficiaryNoIdentifierReturns422() throws Exception {
|
||||||
createCoverageWithBeneficiary(true, false);
|
createCoverageWithBeneficiary(true, false);
|
||||||
|
|
||||||
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage);
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
"Coverage beneficiary does not have an identifier.");
|
"Coverage beneficiary does not have an identifier.");
|
||||||
}
|
}
|
||||||
|
@ -162,7 +185,7 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
createCoverageWithBeneficiary(true, true);
|
createCoverageWithBeneficiary(true, true);
|
||||||
|
|
||||||
myPatient.setName(Lists.newArrayList(new HumanName().setUse(HumanName.NameUse.OFFICIAL).setFamily("Smith")));
|
myPatient.setName(Lists.newArrayList(new HumanName().setUse(HumanName.NameUse.OFFICIAL).setFamily("Smith")));
|
||||||
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage);
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
"Could not find matching patient for coverage.");
|
"Could not find matching patient for coverage.");
|
||||||
}
|
}
|
||||||
|
@ -172,16 +195,64 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
createCoverageWithBeneficiary(true, false);
|
createCoverageWithBeneficiary(true, false);
|
||||||
|
|
||||||
myPatient.setBirthDateElement(new DateType("2000-01-01"));
|
myPatient.setBirthDateElement(new DateType("2000-01-01"));
|
||||||
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage);
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
"Could not find matching patient for coverage.");
|
"Could not find matching patient for coverage.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegularContentProfileAccessWithRegularNotAllowedReturns422() throws Exception {
|
||||||
|
createCoverageWithBeneficiary(true, true);
|
||||||
|
myConsent.getPolicy().get(0).setUri(CONSENT_POLICY_REGULAR_DATA_URI);
|
||||||
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
|
"Consent policy does not match the data release segmentation capabilities.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSensitiveContentProfileAccessWithRegularNotAllowed() throws Exception {
|
||||||
|
createCoverageWithBeneficiary(true, true);
|
||||||
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
|
Parameters parametersResponse = performOperation(ourServerBase + ourQuery,
|
||||||
|
EncodingEnum.JSON, inputParameters);
|
||||||
|
|
||||||
|
validateMemberPatient(parametersResponse);
|
||||||
|
validateNewCoverage(parametersResponse, newCoverage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegularContentProfileAccessWithRegularAllowed() throws Exception {
|
||||||
|
createCoverageWithBeneficiary(true, true);
|
||||||
|
myConsent.getPolicy().get(0).setUri(CONSENT_POLICY_REGULAR_DATA_URI);
|
||||||
|
myMemberMatcherR4Helper.setRegularFilterSupported(true);
|
||||||
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
|
Parameters parametersResponse = performOperation(ourServerBase + ourQuery,
|
||||||
|
EncodingEnum.JSON, inputParameters);
|
||||||
|
|
||||||
|
validateMemberPatient(parametersResponse);
|
||||||
|
validateNewCoverage(parametersResponse, newCoverage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConsentReturns() throws Exception {
|
||||||
|
createCoverageWithBeneficiary(true, true);
|
||||||
|
myConsent.getPolicy().get(0).setUri(CONSENT_POLICY_REGULAR_DATA_URI);
|
||||||
|
myMemberMatcherR4Helper.setRegularFilterSupported(true);
|
||||||
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
|
Parameters parametersResponse = performOperation(ourServerBase + ourQuery,
|
||||||
|
EncodingEnum.JSON, inputParameters);
|
||||||
|
|
||||||
|
validateMemberPatient(parametersResponse);
|
||||||
|
validateNewCoverage(parametersResponse, newCoverage);
|
||||||
|
validateResponseConsent(parametersResponse, myConsent);
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
public class ValidateParameterErrors {
|
public class ValidateParameterErrors {
|
||||||
private Patient ourPatient;
|
private Patient ourPatient;
|
||||||
private Coverage ourOldCoverage;
|
private Coverage ourOldCoverage;
|
||||||
private Coverage ourNewCoverage;
|
private Coverage ourNewCoverage;
|
||||||
|
private Consent ourConsent;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void beforeValidateParameterErrors() {
|
public void beforeValidateParameterErrors() {
|
||||||
|
@ -194,28 +265,77 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
ourNewCoverage.setId("AA87654");
|
ourNewCoverage.setId("AA87654");
|
||||||
ourNewCoverage.setIdentifier(Lists.newArrayList(
|
ourNewCoverage.setIdentifier(Lists.newArrayList(
|
||||||
new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")));
|
new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")));
|
||||||
|
|
||||||
|
ourConsent = new Consent();
|
||||||
|
ourConsent.setStatus(Consent.ConsentState.ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidPatient() throws Exception {
|
public void testInvalidPatient() throws Exception {
|
||||||
Parameters inputParameters = buildInputParameters(new Patient(), ourOldCoverage, ourNewCoverage);
|
Parameters inputParameters = buildInputParameters(new Patient(), ourOldCoverage, ourNewCoverage, ourConsent);
|
||||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
"Parameter \\\"" + PARAM_MEMBER_PATIENT + "\\\" is required.");
|
"Parameter \\\"" + PARAM_MEMBER_PATIENT + "\\\" is required.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidOldCoverage() throws Exception {
|
public void testInvalidOldCoverage() throws Exception {
|
||||||
Parameters inputParameters = buildInputParameters(ourPatient, new Coverage(), ourNewCoverage);
|
Parameters inputParameters = buildInputParameters(ourPatient, new Coverage(), ourNewCoverage, ourConsent);
|
||||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
"Parameter \\\"" + PARAM_OLD_COVERAGE + "\\\" is required.");
|
"Parameter \\\"" + PARAM_OLD_COVERAGE + "\\\" is required.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidNewCoverage() throws Exception {
|
public void testInvalidNewCoverage() throws Exception {
|
||||||
Parameters inputParameters = buildInputParameters(ourPatient, ourOldCoverage, new Coverage());
|
Parameters inputParameters = buildInputParameters(ourPatient, ourOldCoverage, new Coverage(), ourConsent);
|
||||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
"Parameter \\\"" + PARAM_NEW_COVERAGE + "\\\" is required.");
|
"Parameter \\\"" + PARAM_NEW_COVERAGE + "\\\" is required.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidConsent() throws Exception {
|
||||||
|
Parameters inputParameters = buildInputParameters(ourPatient, ourOldCoverage, ourNewCoverage, new Consent());
|
||||||
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
|
"Parameter \\\"" + PARAM_CONSENT + "\\\" is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMissingPatientFamilyName() throws Exception {
|
||||||
|
Parameters inputParameters = buildInputParameters(ourPatient, ourOldCoverage, ourNewCoverage, ourConsent);
|
||||||
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
|
"Parameter \\\"" + PARAM_MEMBER_PATIENT_NAME + "\\\" is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMissingPatientBirthdate() throws Exception {
|
||||||
|
ourPatient.setName(Lists.newArrayList(new HumanName()
|
||||||
|
.setUse(HumanName.NameUse.OFFICIAL).setFamily("Person")));
|
||||||
|
Parameters inputParameters = buildInputParameters(ourPatient, ourOldCoverage, ourNewCoverage, ourConsent);
|
||||||
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
|
"Parameter \\\"" + PARAM_MEMBER_PATIENT_BIRTHDATE + "\\\" is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMissingConsentPatientReference() throws Exception {
|
||||||
|
ourPatient.setName(Lists.newArrayList(new HumanName()
|
||||||
|
.setUse(HumanName.NameUse.OFFICIAL).setFamily("Person")))
|
||||||
|
.setBirthDateElement(new DateType("2020-01-01"));
|
||||||
|
|
||||||
|
Parameters inputParameters = buildInputParameters(ourPatient, ourOldCoverage, ourNewCoverage, ourConsent);
|
||||||
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
|
"Parameter \\\"" + PARAM_CONSENT_PATIENT_REFERENCE + "\\\" is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMissingConsentPerformerReference() throws Exception {
|
||||||
|
ourPatient.setName(Lists.newArrayList(new HumanName()
|
||||||
|
.setUse(HumanName.NameUse.OFFICIAL).setFamily("Person")))
|
||||||
|
.setBirthDateElement(new DateType("2020-01-01"));
|
||||||
|
|
||||||
|
ourConsent.setPatient(new Reference("Patient/1"));
|
||||||
|
Parameters inputParameters = buildInputParameters(ourPatient, ourOldCoverage, ourNewCoverage, ourConsent);
|
||||||
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
|
"Parameter \\\"" + PARAM_CONSENT_PERFORMER_REFERENCE + "\\\" is required.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -223,7 +343,7 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
public void testMemberMatchByCoverageIdentifier() throws Exception {
|
public void testMemberMatchByCoverageIdentifier() throws Exception {
|
||||||
createCoverageWithBeneficiary(true, true);
|
createCoverageWithBeneficiary(true, true);
|
||||||
|
|
||||||
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage);
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
Parameters parametersResponse = performOperation(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters);
|
Parameters parametersResponse = performOperation(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters);
|
||||||
|
|
||||||
validateMemberPatient(parametersResponse);
|
validateMemberPatient(parametersResponse);
|
||||||
|
@ -244,6 +364,12 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
assertEquals(theOriginalCoverage.getIdentifierFirstRep().getValue(), respCoverage.getIdentifierFirstRep().getValue());
|
assertEquals(theOriginalCoverage.getIdentifierFirstRep().getValue(), respCoverage.getIdentifierFirstRep().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateConsentPatientAndPerformerRef(Patient thePatient, Consent theConsent) {
|
||||||
|
String patientRef = thePatient.getIdElement().toUnqualifiedVersionless().getValue();
|
||||||
|
assertEquals(patientRef, theConsent.getPatient().getReference());
|
||||||
|
assertEquals(patientRef, theConsent.getPerformer().get(0).getReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void validateMemberPatient(Parameters response) {
|
private void validateMemberPatient(Parameters response) {
|
||||||
// parameter MemberPatient must have a new identifier with:
|
// parameter MemberPatient must have a new identifier with:
|
||||||
|
@ -279,17 +405,29 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoCoverageMatchFound() throws Exception {
|
public void testNoCoverageMatchFound() throws Exception {
|
||||||
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage);
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||||
"Could not find coverage for member");
|
"Could not find coverage for member");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConsentUpdatePatientAndPerformer() throws Exception {
|
||||||
|
createCoverageWithBeneficiary(true, true);
|
||||||
|
Parameters inputParameters = buildInputParameters(myPatient, oldCoverage, newCoverage, myConsent);
|
||||||
|
Parameters parametersResponse = performOperation(ourServerBase + ourQuery,
|
||||||
|
EncodingEnum.JSON, inputParameters);
|
||||||
|
|
||||||
private Parameters buildInputParameters(Patient thePatient, Coverage theOldCoverage, Coverage theNewCoverage) {
|
Consent respConsent = validateResponseConsent(parametersResponse, myConsent);
|
||||||
|
validateConsentPatientAndPerformerRef(myPatient, respConsent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Parameters buildInputParameters(Patient thePatient, Coverage theOldCoverage, Coverage theNewCoverage, Consent theConsent) {
|
||||||
Parameters p = new Parameters();
|
Parameters p = new Parameters();
|
||||||
ParametersUtil.addParameterToParameters(this.getFhirContext(), p, PARAM_MEMBER_PATIENT, thePatient);
|
ParametersUtil.addParameterToParameters(this.getFhirContext(), p, PARAM_MEMBER_PATIENT, thePatient);
|
||||||
ParametersUtil.addParameterToParameters(this.getFhirContext(), p, PARAM_OLD_COVERAGE, theOldCoverage);
|
ParametersUtil.addParameterToParameters(this.getFhirContext(), p, PARAM_OLD_COVERAGE, theOldCoverage);
|
||||||
ParametersUtil.addParameterToParameters(this.getFhirContext(), p, PARAM_NEW_COVERAGE, theNewCoverage);
|
ParametersUtil.addParameterToParameters(this.getFhirContext(), p, PARAM_NEW_COVERAGE, theNewCoverage);
|
||||||
|
ParametersUtil.addParameterToParameters(this.getFhirContext(), p, PARAM_CONSENT, theConsent);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +483,19 @@ public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Tes
|
||||||
assertFalse(coding.getUserSelected());
|
assertFalse(coding.getUserSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that consent from the response is same as the received consent with additional identifier and extension
|
||||||
|
*/
|
||||||
|
private Consent validateResponseConsent(Parameters theResponse, Consent theOriginalConsent) {
|
||||||
|
List<IBase> consentList = ParametersUtil.getNamedParameters(this.getFhirContext(), theResponse, PARAM_CONSENT);
|
||||||
|
assertEquals(1, consentList.size());
|
||||||
|
Consent respConsent= (Consent) theResponse.getParameter().get(2).getResource();
|
||||||
|
|
||||||
|
assertEquals(theOriginalConsent.getScope().getCodingFirstRep().getSystem(), respConsent.getScope().getCodingFirstRep().getSystem());
|
||||||
|
assertEquals(theOriginalConsent.getScope().getCodingFirstRep().getCode(), respConsent.getScope().getCodingFirstRep().getCode());
|
||||||
|
assertEquals(myMemberMatcherR4Helper.CONSENT_IDENTIFIER_CODE_SYSTEM, respConsent.getIdentifier().get(0).getSystem());
|
||||||
|
assertNotNull(respConsent.getIdentifier().get(0).getValue());
|
||||||
|
return respConsent;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot</artifactId>
|
<artifactId>hapi-fhir-spring-boot</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package ca.uhn.fhir.to;
|
package ca.uhn.fhir.to;
|
||||||
|
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
|
@ -35,7 +35,11 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static ca.uhn.fhir.util.UrlUtil.sanitizeUrlPart;
|
import static ca.uhn.fhir.util.UrlUtil.sanitizeUrlPart;
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -65,42 +65,42 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-r4b</artifactId>
|
<artifactId>hapi-fhir-structures-r4b</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-r5</artifactId>
|
<artifactId>hapi-fhir-structures-r5</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
4
pom.xml
4
pom.xml
|
@ -6,7 +6,7 @@
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<name>HAPI-FHIR</name>
|
<name>HAPI-FHIR</name>
|
||||||
<description>An open-source implementation of the FHIR specification in Java.</description>
|
<description>An open-source implementation of the FHIR specification in Java.</description>
|
||||||
<url>https://hapifhir.io</url>
|
<url>https://hapifhir.io</url>
|
||||||
|
@ -1998,7 +1998,7 @@
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-checkstyle</artifactId>
|
<artifactId>hapi-fhir-checkstyle</artifactId>
|
||||||
<!-- Remember to bump this when you upgrade the version -->
|
<!-- Remember to bump this when you upgrade the version -->
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.3.0-PRE1-SNAPSHOT</version>
|
<version>6.3.0-PRE2-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue