2491 - Fix NullPointerException when performing cascade delete (#2492)

* 2491 - Fix NullPointerException when performing cascade delete.
This commit is contained in:
Kevin Dougan SmileCDR 2021-03-22 10:29:03 -04:00 committed by GitHub
parent dc41d5ad61
commit d1c2d839d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 4 deletions

View File

@ -129,7 +129,7 @@ public class CascadingDeleteInterceptor {
IFhirResourceDao dao = myDaoRegistry.getResourceDao(nextSource.getResourceType());
// Interceptor call: STORAGE_CASCADE_DELETE
IBaseResource resource = dao.read(nextSource);
IBaseResource resource = dao.read(nextSource, theRequest);
HookParams params = new HookParams()
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest)

View File

@ -2,14 +2,17 @@ package ca.uhn.fhir.jpa.interceptor;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.provider.r4.BaseResourceProviderR4Test;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CarePlan;
import org.hl7.fhir.r4.model.Condition;
@ -21,14 +24,21 @@ import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Reference;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.List;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class CascadingDeleteInterceptorTest extends BaseResourceProviderR4Test {
@ -88,6 +98,42 @@ public class CascadingDeleteInterceptorTest extends BaseResourceProviderR4Test {
myConditionId = myClient.create().resource(condition).execute().getId().toUnqualifiedVersionless();
}
@Test
public void testDeleteWithInterceptorVerifyTheRequestGetsPassedToDao() throws IOException {
// The whole and ONLY point of this Cascade Delete Unit Test is to make sure that a non-NULL RequestDetails param
// is passed to the dao.read() method from inside the CascadingDeleteInterceptor.handleDeleteConflicts() method
// For details see: https://gitlab.com/simpatico.ai/cdr/-/issues/1643
DaoRegistry mockDaoRegistry = mock(DaoRegistry.class);
IFhirResourceDao mockResourceDao = mock (IFhirResourceDao.class);
IBaseResource mockResource = mock(IBaseResource.class);
CascadingDeleteInterceptor aDeleteInterceptor = new CascadingDeleteInterceptor(myFhirCtx, mockDaoRegistry, myInterceptorBroadcaster);
ourRestServer.getInterceptorService().unregisterInterceptor(myDeleteInterceptor);
ourRestServer.getInterceptorService().registerInterceptor(aDeleteInterceptor);
when(mockDaoRegistry.getResourceDao(any(String.class))).thenReturn(mockResourceDao);
when(mockResourceDao.read(any(IIdType.class), any(RequestDetails.class))).thenReturn(mockResource);
ArgumentCaptor<RequestDetails> theRequestDetailsCaptor = ArgumentCaptor.forClass(RequestDetails.class);
Patient p = new Patient();
p.setActive(true);
myPatientId = myClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
Encounter e = new Encounter();
e.setSubject(new Reference(myPatientId));
myEncounterId = myClient.create().resource(e).execute().getId().toUnqualifiedVersionless();
HttpDelete delete = new HttpDelete(ourServerBase + "/" + myPatientId.getValue() + "?" + Constants.PARAMETER_CASCADE_DELETE + "=" + Constants.CASCADE_DELETE + "&_pretty=true");
delete.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_JSON_NEW);
try (CloseableHttpResponse response = ourHttpClient.execute(delete)) {
String deleteResponse = IOUtils.toString(response.getEntity().getContent(), Charsets.UTF_8);
ourLog.info("Response: {}", deleteResponse);
}
verify(mockResourceDao).read(any(IIdType.class), theRequestDetailsCaptor.capture());
List<RequestDetails> capturedRequestDetailsParam = theRequestDetailsCaptor.getAllValues();
for (RequestDetails requestDetails : capturedRequestDetailsParam) {
assertNotNull(requestDetails);
}
}
@Test
public void testDeleteWithNoInterceptorAndConstraints() {
createResources();
@ -252,7 +298,4 @@ public class CascadingDeleteInterceptorTest extends BaseResourceProviderR4Test {
// good
}
}
}