allow interceptors to be registered via properties

This commit is contained in:
Craig McClendon
2022-12-20 20:07:18 -06:00
parent 19c68e7cfc
commit ba58a71624
9 changed files with 234 additions and 7 deletions

View File

@@ -0,0 +1,24 @@
package ca.uhn.fhir.jpa.starter;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties = {
"hapi.fhir.custom-bean-packages=some.custom.pkg1,some.custom.pkg2",
"spring.datasource.url=jdbc:h2:mem:dbr4",
// "hapi.fhir.enable_repository_validating_interceptor=true",
"hapi.fhir.fhir_version=r4"
})
public class CustomBeanTest {
@Autowired
some.custom.pkg1.CustomBean customBean1;
@Test
void testCustomBeanExists() {
Assertions.assertNotNull(customBean1);
Assertions.assertEquals("I am alive", customBean1.getInitFlag());
}
}

View File

@@ -0,0 +1,64 @@
package ca.uhn.fhir.jpa.starter;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties = {
"hapi.fhir.custom-bean-packages=some.custom.pkg1",
"hapi.fhir.custom-interceptor-classes=some.custom.pkg1.CustomInterceptorBean,some.custom.pkg1.CustomInterceptorPojo",
"spring.datasource.url=jdbc:h2:mem:dbr4",
// "hapi.fhir.enable_repository_validating_interceptor=true",
"hapi.fhir.fhir_version=r4"
})
public class CustomInterceptorTest {
@LocalServerPort
private int port;
@Autowired
private IFhirResourceDao<Patient> patientResourceDao;
private IGenericClient client;
private FhirContext ctx;
@BeforeEach
void setUp() {
ctx = FhirContext.forR4();
ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ctx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
String ourServerBase = "http://localhost:" + port + "/fhir/";
client = ctx.newRestfulGenericClient(ourServerBase);
// Properties props = new Properties();
// props.put("spring.autoconfigure.exclude", "org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration");
}
@Test
void testAuditInterceptors() {
// we registered two custom interceptors via the property 'hapi.fhir.custom-interceptor-classes'
// one is discovered as a Spring Bean, one instantiated via reflection
// both should be registered with the server and will add a custom extension to any Patient resource created
// so we can verify they were registered
Patient pat = new Patient();
String patId = client.create().resource(pat).execute().getId().getIdPart();
Patient readPat = client.read().resource(Patient.class).withId(patId).execute();
Assertions.assertNotNull(readPat.getExtensionByUrl("http://some.custom.pkg1/CustomInterceptorBean"));
Assertions.assertNotNull(readPat.getExtensionByUrl("http://some.custom.pkg1/CustomInterceptorPojo"));
}
}

View File

@@ -0,0 +1,18 @@
package some.custom.pkg1;
import org.springframework.stereotype.Component;
@Component
public class CustomBean {
private String initFlag;
public CustomBean() {
initFlag = "I am alive";
}
public String getInitFlag() {
return initFlag;
}
}

View File

@@ -0,0 +1,31 @@
package some.custom.pkg1;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StringType;
import org.springframework.stereotype.Component;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Interceptor;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
@Interceptor
@Component
public class CustomInterceptorBean {
@Hook(Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED)
void preHandleResource(ServletRequestDetails servletRequestDetails, RestOperationTypeEnum opType) {
IBaseResource resource = servletRequestDetails.getResource();
// add an extension before saving the resource to mark it
if (opType == RestOperationTypeEnum.CREATE && resource instanceof Patient) {
Patient pat = (Patient) resource;
Extension ext = pat.addExtension();
ext.setUrl("http://some.custom.pkg1/CustomInterceptorBean");
ext.setValue(new StringType("CustomInterceptorBean wuz here"));
}
}
}

View File

@@ -0,0 +1,26 @@
package some.custom.pkg1;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StringType;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
public class CustomInterceptorPojo {
@Hook(Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED)
void preHandleResource(ServletRequestDetails servletRequestDetails, RestOperationTypeEnum opType) {
IBaseResource resource = servletRequestDetails.getResource();
// add an extension before saving the resource to mark it
if (opType == RestOperationTypeEnum.CREATE && resource instanceof Patient) {
Patient pat = (Patient) resource;
Extension ext = pat.addExtension();
ext.setUrl("http://some.custom.pkg1/CustomInterceptorPojo");
ext.setValue(new StringType("CustomInterceptorPojo wuz here"));
}
}
}