wpi merge operation provider
This commit is contained in:
parent
054f7e6678
commit
7979f037e9
|
@ -19,8 +19,11 @@
|
|||
*/
|
||||
package ca.uhn.fhir.jpa.provider;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
|
||||
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
|
||||
import ca.uhn.fhir.jpa.dao.merge.MergeOperationParameters;
|
||||
import ca.uhn.fhir.jpa.dao.merge.ResourceMergeService;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
@ -39,12 +42,25 @@ import ca.uhn.fhir.rest.param.StringOrListParam;
|
|||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.util.CanonicalIdentifier;
|
||||
import ca.uhn.fhir.util.IdentifierUtil;
|
||||
import ca.uhn.fhir.util.ParametersUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.r4.model.Identifier;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
|
@ -240,6 +256,90 @@ public abstract class BaseJpaResourceProviderPatient<T extends IBaseResource> ex
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* /Patient/$merge
|
||||
*/
|
||||
@Operation(
|
||||
name = ProviderConstants.OPERATION_MERGE,
|
||||
canonicalUrl = "http://hl7.org/fhir/OperationDefinition/Patient-merge")
|
||||
public void patientMerge(
|
||||
HttpServletRequest theServletRequest,
|
||||
HttpServletResponse theServletResponse,
|
||||
ServletRequestDetails theRequestDetails,
|
||||
@OperationParam(name = ProviderConstants.OPERATION_MERGE_SOURCE_PATIENT_IDENTIFIER)
|
||||
List<Identifier> theSourcePatientIdentifier,
|
||||
@OperationParam(name = ProviderConstants.OPERATION_MERGE_TARGET_PATIENT_IDENTIFIER)
|
||||
List<Identifier> theTargetPatientIdentifier,
|
||||
@OperationParam(name = ProviderConstants.OPERATION_MERGE_SOURCE_PATIENT, max = 1)
|
||||
IBaseReference theSourcePatient,
|
||||
@OperationParam(name = ProviderConstants.OPERATION_MERGE_TARGET_PATIENT, max = 1)
|
||||
IBaseReference theTargetPatient,
|
||||
@OperationParam(name = ProviderConstants.OPERATION_MERGE_PREVIEW, typeName = "boolean", max = 1)
|
||||
IPrimitiveType<Boolean> thePreview,
|
||||
@OperationParam(name = ProviderConstants.OPERATION_MERGE_RESULT_PATIENT, max = 1)
|
||||
IBaseResource theResultPatient)
|
||||
throws IOException {
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
MergeOperationParameters mergeOperationParameters = createMergeOperationParameters(
|
||||
theSourcePatientIdentifier,
|
||||
theTargetPatientIdentifier,
|
||||
theSourcePatient,
|
||||
theTargetPatient,
|
||||
thePreview,
|
||||
theResultPatient);
|
||||
|
||||
IFhirResourceDaoPatient<?> dao = (IFhirResourceDaoPatient<?>) getDao();
|
||||
ResourceMergeService resourceMergeService = new ResourceMergeService(dao);
|
||||
|
||||
FhirContext fhirContext = dao.getContext();
|
||||
|
||||
ResourceMergeService.MergeOutcome mergeOutcome =
|
||||
resourceMergeService.merge(mergeOperationParameters, theRequestDetails);
|
||||
|
||||
IBaseParameters retVal = ParametersUtil.newInstance(fhirContext);
|
||||
ParametersUtil.addParameterToParameters(fhirContext, retVal, "outcome", mergeOutcome.getOperationOutcome());
|
||||
|
||||
theServletResponse.setStatus(mergeOutcome.getHttpStatusCode());
|
||||
// we are writing the response to directly, otherwise the response status we set above is ignored.
|
||||
fhirContext
|
||||
.newJsonParser()
|
||||
.setPrettyPrint(true)
|
||||
.encodeResourceToWriter(retVal, theServletResponse.getWriter());
|
||||
theServletResponse.getWriter().close();
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private MergeOperationParameters createMergeOperationParameters(
|
||||
List<Identifier> theSourcePatientIdentifier,
|
||||
List<Identifier> theTargetPatientIdentifier,
|
||||
IBaseReference theSourcePatient,
|
||||
IBaseReference theTargetPatient,
|
||||
IPrimitiveType<Boolean> thePreview,
|
||||
IBaseResource theResultPatient) {
|
||||
MergeOperationParameters mergeOperationParameters = new MergeOperationParameters();
|
||||
if (theSourcePatientIdentifier != null) {
|
||||
List<CanonicalIdentifier> sourceResourceIdentifiers = theSourcePatientIdentifier.stream()
|
||||
.map(IdentifierUtil::identifierDtFromIdentifier)
|
||||
.collect(Collectors.toList());
|
||||
mergeOperationParameters.setSourceResourceIdentifiers(sourceResourceIdentifiers);
|
||||
}
|
||||
if (theTargetPatientIdentifier != null) {
|
||||
List<CanonicalIdentifier> targetResourceIdentifiers = theTargetPatientIdentifier.stream()
|
||||
.map(IdentifierUtil::identifierDtFromIdentifier)
|
||||
.collect(Collectors.toList());
|
||||
mergeOperationParameters.setTargetResourceIdentifiers(targetResourceIdentifiers);
|
||||
}
|
||||
mergeOperationParameters.setSourceResource(theSourcePatient);
|
||||
mergeOperationParameters.setTargetResource(theTargetPatient);
|
||||
mergeOperationParameters.setPreview(thePreview != null && thePreview.getValue());
|
||||
mergeOperationParameters.setResultPatient((Patient) theResultPatient);
|
||||
return mergeOperationParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of string types, return only the ID portions of any parameters passed in.
|
||||
*/
|
||||
|
|
|
@ -22,7 +22,6 @@ package ca.uhn.fhir.mdm.util;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.i18n.Msg;
|
||||
import ca.uhn.fhir.mdm.model.CanonicalEID;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.util.CanonicalIdentifier;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
|
||||
|
@ -31,23 +30,7 @@ public final class IdentifierUtil {
|
|||
private IdentifierUtil() {}
|
||||
|
||||
public static CanonicalIdentifier identifierDtFromIdentifier(IBase theIdentifier) {
|
||||
CanonicalIdentifier retval = new CanonicalIdentifier();
|
||||
|
||||
// TODO add other fields like "use" etc
|
||||
if (theIdentifier instanceof org.hl7.fhir.dstu3.model.Identifier) {
|
||||
org.hl7.fhir.dstu3.model.Identifier ident = (org.hl7.fhir.dstu3.model.Identifier) theIdentifier;
|
||||
retval.setSystem(ident.getSystem()).setValue(ident.getValue());
|
||||
} else if (theIdentifier instanceof org.hl7.fhir.r4.model.Identifier) {
|
||||
org.hl7.fhir.r4.model.Identifier ident = (org.hl7.fhir.r4.model.Identifier) theIdentifier;
|
||||
retval.setSystem(ident.getSystem()).setValue(ident.getValue());
|
||||
} else if (theIdentifier instanceof org.hl7.fhir.r5.model.Identifier) {
|
||||
org.hl7.fhir.r5.model.Identifier ident = (org.hl7.fhir.r5.model.Identifier) theIdentifier;
|
||||
retval.setSystem(ident.getSystem()).setValue(ident.getValue());
|
||||
} else {
|
||||
throw new InternalErrorException(Msg.code(1486) + "Expected 'Identifier' type but was '"
|
||||
+ theIdentifier.getClass().getName() + "'");
|
||||
}
|
||||
return retval;
|
||||
return ca.uhn.fhir.util.IdentifierUtil.identifierDtFromIdentifier(theIdentifier);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -252,6 +252,7 @@ public class ProviderConstants {
|
|||
* Patient $merge operation parameters
|
||||
*/
|
||||
public static final String OPERATION_MERGE_SOURCE_PATIENT = "source-patient";
|
||||
|
||||
public static final String OPERATION_MERGE_SOURCE_PATIENT_IDENTIFIER = "source-patient-identifier";
|
||||
public static final String OPERATION_MERGE_TARGET_PATIENT = "target-patient";
|
||||
public static final String OPERATION_MERGE_TARGET_PATIENT_IDENTIFIER = "target-patient-identifier";
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR Storage api
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2024 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
package ca.uhn.fhir.jpa.dao.merge;
|
||||
|
||||
import ca.uhn.fhir.util.CanonicalIdentifier;
|
||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MergeOperationParameters {
|
||||
|
||||
private List<CanonicalIdentifier> mySourceResourceIdentifiers;
|
||||
private List<CanonicalIdentifier> myTargetResourceIdentifiers;
|
||||
private IBaseReference mySourceResource;
|
||||
private IBaseReference myTargetResource;
|
||||
private boolean myPreview;
|
||||
|
||||
// TODO: this can be changed to a generic resource to support other resources
|
||||
private Patient myResultResource;
|
||||
|
||||
public List<CanonicalIdentifier> getSourceIdentifiers() {
|
||||
return mySourceResourceIdentifiers;
|
||||
}
|
||||
|
||||
public boolean hasAtLeastOneSourceIdentifier() {
|
||||
return mySourceResourceIdentifiers != null && !mySourceResourceIdentifiers.isEmpty();
|
||||
}
|
||||
|
||||
public void setSourceResourceIdentifiers(List<CanonicalIdentifier> theSourceIdentifiers) {
|
||||
this.mySourceResourceIdentifiers = theSourceIdentifiers;
|
||||
}
|
||||
|
||||
public List<CanonicalIdentifier> getTargetIdentifiers() {
|
||||
return myTargetResourceIdentifiers;
|
||||
}
|
||||
|
||||
public boolean hasAtLeastOneTargetIdentifier() {
|
||||
return myTargetResourceIdentifiers != null && !myTargetResourceIdentifiers.isEmpty();
|
||||
}
|
||||
|
||||
public void setTargetResourceIdentifiers(List<CanonicalIdentifier> theTargetIdentifiers) {
|
||||
this.myTargetResourceIdentifiers = theTargetIdentifiers;
|
||||
}
|
||||
|
||||
public boolean isPreview() {
|
||||
return myPreview;
|
||||
}
|
||||
|
||||
public void setPreview(boolean thePreview) {
|
||||
this.myPreview = thePreview;
|
||||
}
|
||||
|
||||
public Patient getResultPatient() {
|
||||
return myResultResource;
|
||||
}
|
||||
|
||||
public void setResultPatient(Patient theResultPatient) {
|
||||
this.myResultResource = theResultPatient;
|
||||
}
|
||||
|
||||
public IBaseReference getSourceResource() {
|
||||
return mySourceResource;
|
||||
}
|
||||
|
||||
public void setSourceResource(IBaseReference theSourceResource) {
|
||||
this.mySourceResource = theSourceResource;
|
||||
}
|
||||
|
||||
public IBaseReference getTargetResource() {
|
||||
return myTargetResource;
|
||||
}
|
||||
|
||||
public void setTargetResource(IBaseReference theTargetResource) {
|
||||
this.myTargetResource = theTargetResource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR Storage api
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2024 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
package ca.uhn.fhir.jpa.dao.merge;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static ca.uhn.fhir.rest.api.Constants.STATUS_HTTP_400_BAD_REQUEST;
|
||||
|
||||
public class ResourceMergeService {
|
||||
|
||||
IFhirResourceDaoPatient<?> myDao;
|
||||
FhirContext myFhirContext;
|
||||
|
||||
public ResourceMergeService(IFhirResourceDaoPatient<?> thePatientDao) {
|
||||
myDao = thePatientDao;
|
||||
myFhirContext = myDao.getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemention of the $merge operation for resources
|
||||
* @param theMergeOperationParameters the merge operation parameters
|
||||
* @param theRequestDetails the request details
|
||||
* @return the merge outcome containing OperationOutcome and HTTP status code
|
||||
*/
|
||||
public MergeOutcome merge(MergeOperationParameters theMergeOperationParameters, RequestDetails theRequestDetails) {
|
||||
|
||||
MergeOutcome mergeOutcome = new MergeOutcome();
|
||||
IBaseOperationOutcome outcome = OperationOutcomeUtil.newInstance(myFhirContext);
|
||||
mergeOutcome.setOperationOutcome(outcome);
|
||||
|
||||
if (!validateMergeOperationParameters(theMergeOperationParameters, outcome)) {
|
||||
mergeOutcome.setHttpStatusCode(STATUS_HTTP_400_BAD_REQUEST);
|
||||
return mergeOutcome;
|
||||
}
|
||||
|
||||
return mergeOutcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the merge operation parameters and adds validation errors to the outcome
|
||||
* @param theMergeOperationParameters the merge operation parameters
|
||||
* @param theOutcome the outcome to add validation errors to
|
||||
* @return true if the parameters are valid, false otherwise
|
||||
*/
|
||||
private boolean validateMergeOperationParameters(
|
||||
MergeOperationParameters theMergeOperationParameters, IBaseOperationOutcome theOutcome) {
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
if (!theMergeOperationParameters.hasAtLeastOneSourceIdentifier()
|
||||
&& theMergeOperationParameters.getSourceResource() == null) {
|
||||
errorMessages.add("There are no source resource parameters provided, include either a source-patient, "
|
||||
+ "source-patient-identifier parameter.");
|
||||
}
|
||||
|
||||
// Spec has conflicting information about this case
|
||||
if (theMergeOperationParameters.hasAtLeastOneSourceIdentifier()
|
||||
&& theMergeOperationParameters.getSourceResource() != null) {
|
||||
errorMessages.add(
|
||||
"Source patient must be provided either by source-patient-identifier or by source-resource, not both.");
|
||||
}
|
||||
|
||||
if (!theMergeOperationParameters.hasAtLeastOneTargetIdentifier()
|
||||
&& theMergeOperationParameters.getTargetResource() == null) {
|
||||
errorMessages.add("There are no target resource parameters provided, include either a target-patient, "
|
||||
+ "target-patient-identifier parameter.");
|
||||
}
|
||||
|
||||
// Spec has conflicting information about this case
|
||||
if (theMergeOperationParameters.hasAtLeastOneTargetIdentifier()
|
||||
&& theMergeOperationParameters.getTargetResource() != null) {
|
||||
errorMessages.add("Target patient must be provided either by target-patient-identifier or by "
|
||||
+ "target-resource, not both.");
|
||||
}
|
||||
|
||||
if (!errorMessages.isEmpty()) {
|
||||
for (String validationError : errorMessages) {
|
||||
OperationOutcomeUtil.addIssue(myFhirContext, theOutcome, "error", validationError, null, null);
|
||||
}
|
||||
// there are validation errors
|
||||
return false;
|
||||
}
|
||||
|
||||
// no validation errors
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class MergeOutcome {
|
||||
private IBaseOperationOutcome myOperationOutcome;
|
||||
private int myHttpStatusCode;
|
||||
|
||||
public IBaseOperationOutcome getOperationOutcome() {
|
||||
return myOperationOutcome;
|
||||
}
|
||||
|
||||
public void setOperationOutcome(IBaseOperationOutcome theOperationOutcome) {
|
||||
this.myOperationOutcome = theOperationOutcome;
|
||||
}
|
||||
|
||||
public int getHttpStatusCode() {
|
||||
return myHttpStatusCode;
|
||||
}
|
||||
|
||||
public void setHttpStatusCode(int theHttpStatusCode) {
|
||||
this.myHttpStatusCode = theHttpStatusCode;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR Storage api
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2024 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
package ca.uhn.fhir.util;
|
||||
|
||||
import ca.uhn.fhir.i18n.Msg;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
|
||||
public final class IdentifierUtil {
|
||||
|
||||
private IdentifierUtil() {}
|
||||
|
||||
public static CanonicalIdentifier identifierDtFromIdentifier(IBase theIdentifier) {
|
||||
CanonicalIdentifier retval = new CanonicalIdentifier();
|
||||
|
||||
// TODO add other fields like "use" etc
|
||||
if (theIdentifier instanceof org.hl7.fhir.dstu3.model.Identifier) {
|
||||
org.hl7.fhir.dstu3.model.Identifier ident = (org.hl7.fhir.dstu3.model.Identifier) theIdentifier;
|
||||
retval.setSystem(ident.getSystem()).setValue(ident.getValue());
|
||||
} else if (theIdentifier instanceof org.hl7.fhir.r4.model.Identifier) {
|
||||
org.hl7.fhir.r4.model.Identifier ident = (org.hl7.fhir.r4.model.Identifier) theIdentifier;
|
||||
retval.setSystem(ident.getSystem()).setValue(ident.getValue());
|
||||
} else if (theIdentifier instanceof org.hl7.fhir.r5.model.Identifier) {
|
||||
org.hl7.fhir.r5.model.Identifier ident = (org.hl7.fhir.r5.model.Identifier) theIdentifier;
|
||||
retval.setSystem(ident.getSystem()).setValue(ident.getValue());
|
||||
} else {
|
||||
throw new InternalErrorException(Msg.code(1486) + "Expected 'Identifier' type but was '"
|
||||
+ theIdentifier.getClass().getName() + "'");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
package ca.uhn.fhir.jpa.dao.merge;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.util.CanonicalIdentifier;
|
||||
import org.hl7.fhir.r4.model.OperationOutcome;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class ResourceMergeServiceTest {
|
||||
|
||||
@Mock
|
||||
private IFhirResourceDaoPatient<?> myDaoMock;
|
||||
@Mock
|
||||
RequestDetails myRequestDetailsMock;
|
||||
|
||||
private ResourceMergeService myResourceMergeService;
|
||||
|
||||
private final FhirContext myFhirContext = FhirContext.forR4Cached();
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
when(myDaoMock.getContext()).thenReturn(myFhirContext);
|
||||
myResourceMergeService = new ResourceMergeService(myDaoMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidatesInputParameters_MissingSourcePatientParams_ReturnsErrorInOutcomeWith400Status() {
|
||||
// Given
|
||||
MergeOperationParameters mergeOperationParameters = new MergeOperationParameters();
|
||||
mergeOperationParameters.setTargetResource(new Reference("Patient/123"));
|
||||
|
||||
// When
|
||||
ResourceMergeService.MergeOutcome mergeOutcome = myResourceMergeService.merge(mergeOperationParameters, myRequestDetailsMock);
|
||||
|
||||
// Then
|
||||
OperationOutcome operationOutcome = (OperationOutcome) mergeOutcome.getOperationOutcome();
|
||||
assertThat(mergeOutcome.getHttpStatusCode()).isEqualTo(400);
|
||||
assertThat(operationOutcome.getIssue()).hasSize(1);
|
||||
assertThat(operationOutcome.getIssueFirstRep().getSeverity()).isEqualTo(OperationOutcome.IssueSeverity.ERROR);
|
||||
assertThat(operationOutcome.getIssueFirstRep().getDiagnostics()).contains("There are no source resource parameters provided, include either a source-patient, " +
|
||||
"source-patient-identifier parameter.");
|
||||
|
||||
verifyNoMoreInteractions(myDaoMock);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testValidatesInputParameters_MissingTargetPatientParams_ReturnsErrorInOutcomeWith400Status() {
|
||||
// Given
|
||||
MergeOperationParameters mergeOperationParameters = new MergeOperationParameters();
|
||||
mergeOperationParameters.setSourceResource(new Reference("Patient/123"));
|
||||
|
||||
// When
|
||||
ResourceMergeService.MergeOutcome mergeOutcome = myResourceMergeService.merge(mergeOperationParameters, myRequestDetailsMock);
|
||||
|
||||
// Then
|
||||
OperationOutcome operationOutcome = (OperationOutcome) mergeOutcome.getOperationOutcome();
|
||||
assertThat(mergeOutcome.getHttpStatusCode()).isEqualTo(400);
|
||||
|
||||
assertThat(operationOutcome.getIssue()).hasSize(1);
|
||||
assertThat(operationOutcome.getIssueFirstRep().getSeverity()).isEqualTo(OperationOutcome.IssueSeverity.ERROR);
|
||||
assertThat(operationOutcome.getIssueFirstRep().getDiagnostics()).contains("There are no target resource " +
|
||||
"parameters provided, include either a target-patient, target-patient-identifier parameter.");
|
||||
|
||||
verifyNoMoreInteractions(myDaoMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidatesInputParameters_MissingBothSourceAndTargetPatientParams_ReturnsErrorsInOutcomeWith400Status() {
|
||||
// Given
|
||||
MergeOperationParameters mergeOperationParameters = new MergeOperationParameters();
|
||||
|
||||
// When
|
||||
ResourceMergeService.MergeOutcome mergeOutcome = myResourceMergeService.merge(mergeOperationParameters, myRequestDetailsMock);
|
||||
|
||||
// Then
|
||||
OperationOutcome operationOutcome = (OperationOutcome) mergeOutcome.getOperationOutcome();
|
||||
assertThat(mergeOutcome.getHttpStatusCode()).isEqualTo(400);
|
||||
assertThat(operationOutcome.getIssue()).hasSize(2);
|
||||
assertThat(operationOutcome.getIssue().get(0).getSeverity()).isEqualTo(OperationOutcome.IssueSeverity.ERROR);
|
||||
assertThat(operationOutcome.getIssue().get(0).getDiagnostics()).contains("There are no source resource " +
|
||||
"parameters provided, include either a source-patient, source-patient-identifier parameter.");
|
||||
assertThat(operationOutcome.getIssue().get(1).getSeverity()).isEqualTo(OperationOutcome.IssueSeverity.ERROR);
|
||||
assertThat(operationOutcome.getIssue().get(1).getDiagnostics()).contains("There are no target resource " +
|
||||
"parameters provided, include either a target-patient, target-patient-identifier parameter.");
|
||||
|
||||
verifyNoMoreInteractions(myDaoMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidatesInputParameters_BothSourceResourceParamsProvided_ReturnsErrorInOutcomeWith400Status() {
|
||||
// Given
|
||||
MergeOperationParameters mergeOperationParameters = new MergeOperationParameters();
|
||||
mergeOperationParameters.setSourceResource(new Reference("Patient/123"));
|
||||
mergeOperationParameters.setSourceResourceIdentifiers(List.of(new CanonicalIdentifier().setSystem("sys").setValue( "val")));
|
||||
mergeOperationParameters.setTargetResource(new Reference("Patient/345"));
|
||||
// When
|
||||
ResourceMergeService.MergeOutcome mergeOutcome = myResourceMergeService.merge(mergeOperationParameters, myRequestDetailsMock);
|
||||
|
||||
// Then
|
||||
OperationOutcome operationOutcome = (OperationOutcome) mergeOutcome.getOperationOutcome();
|
||||
assertThat(mergeOutcome.getHttpStatusCode()).isEqualTo(400);
|
||||
|
||||
assertThat(operationOutcome.getIssue()).hasSize(1);
|
||||
assertThat(operationOutcome.getIssueFirstRep().getSeverity()).isEqualTo(OperationOutcome.IssueSeverity.ERROR);
|
||||
assertThat(operationOutcome.getIssueFirstRep().getDiagnostics()).contains("Source patient must be provided " +
|
||||
"either by source-patient-identifier or by source-resource, not both.");
|
||||
|
||||
|
||||
verifyNoMoreInteractions(myDaoMock);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testValidatesInputParameters_BothTargetResourceParamsProvided_ReturnsErrorInOutcomeWith400Status() {
|
||||
// Given
|
||||
MergeOperationParameters mergeOperationParameters = new MergeOperationParameters();
|
||||
mergeOperationParameters.setTargetResource(new Reference("Patient/123"));
|
||||
mergeOperationParameters.setTargetResourceIdentifiers(List.of(new CanonicalIdentifier().setSystem("sys").setValue( "val")));
|
||||
mergeOperationParameters.setSourceResource(new Reference("Patient/345"));
|
||||
// When
|
||||
ResourceMergeService.MergeOutcome mergeOutcome = myResourceMergeService.merge(mergeOperationParameters, myRequestDetailsMock);
|
||||
|
||||
// Then
|
||||
OperationOutcome operationOutcome = (OperationOutcome) mergeOutcome.getOperationOutcome();
|
||||
assertThat(mergeOutcome.getHttpStatusCode()).isEqualTo(400);
|
||||
|
||||
assertThat(operationOutcome.getIssue()).hasSize(1);
|
||||
assertThat(operationOutcome.getIssueFirstRep().getSeverity()).isEqualTo(OperationOutcome.IssueSeverity.ERROR);
|
||||
assertThat(operationOutcome.getIssueFirstRep().getDiagnostics()).contains("Target patient must be provided " +
|
||||
"either by target-patient-identifier or by target-resource, not both.");
|
||||
|
||||
verifyNoMoreInteractions(myDaoMock);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue