Skip to content

Instantly share code, notes, and snippets.

@nvg
Last active June 6, 2021 16:48
Show Gist options
  • Save nvg/e76d158cf5aeb952c8df9b6e5501b64c to your computer and use it in GitHub Desktop.
Save nvg/e76d158cf5aeb952c8df9b6e5501b64c to your computer and use it in GitHub Desktop.
Immunization Interceptor Example
package ca.onfhir.interceptor;
import ca.uhn.fhir.context.FhirContext;
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.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.impl.BaseClient;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.BundleBuilder;
import org.apache.commons.collections4.SetUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.Set;
@Interceptor
public class ImmunizationInterceptor {
private static final String IMMUNIZATION = "Immunization";
public static final String SYSTEM_CVX = "http://hl7.org/fhir/sid/cvx";
private static Logger log = LoggerFactory.getLogger(ImmunizationInterceptor.class);
/**
* Two-dose COVID vaccine codes as defined by CDC https://www2a.cdc.gov/vaccines/iis/iisstandards/vaccines.asp?rpt=cvx
*/
private static Set<String> covidImmunizationCodes = SetUtils.unmodifiableSet("207", "208", "210");
private FhirContext fhirContext;
private DaoRegistry daoRegistry;
private String issuerServerBase;
@Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED)
public void notifyCredentialsIssuer(IBaseResource resource, RequestDetails request, ServletRequestDetails servletRequest, TransactionDetails txDetails) {
if (!IMMUNIZATION.equals(fhirContext.getResourceType(resource))) {
return;
}
Immunization immunization = (Immunization) resource;
if (!isCovidImmunization(immunization)) {
log.debug("Immunization resource {} is not COVID-19 immunization type", immunization);
return;
}
Patient patient = getPatientFromRef(immunization.getPatient());
Immunization previousImmunization = getPreviousCovidImmunization(patient, immunization);
if (previousImmunization == null) {
log.debug("Previous COVID immunization is not found for {}", toJson(patient));
return;
}
String telecom = patient.getTelecomFirstRep().getValue();
patient.getTelecom().clear();
BundleBuilder builder = new BundleBuilder(fhirContext);
for (DomainResource r : Arrays.asList(patient, previousImmunization, immunization)) {
builder.addCollectionEntry(clear(r));
}
IGenericClient client = fhirContext.newRestfulGenericClient(getIssuerServerBase());
((BaseClient) client).setDontValidateConformance(true);
Bundle bundle = (Bundle) builder.getBundle();
Bundle response = (Bundle) client.transaction()
.withBundle(bundle)
.withAdditionalHeader("Patient-Name", patient.getNameFirstRep().getNameAsSingleString())
.withAdditionalHeader("Patient-Email", telecom)
.execute();
log.debug("Published vaccination info with result {}", toJson(response));
}
private DomainResource clear(DomainResource resource) {
resource.setText(null);
resource.setMeta(null);
return resource;
}
private String toJson(IBaseResource resource) {
return fhirContext.newJsonParser().encodeResourceToString(resource);
}
private Immunization getPreviousCovidImmunization(Patient patient, Immunization immunization) {
SearchParameterMap params = new SearchParameterMap();
params.add("patient", new ReferenceParam(patient.getId()));
params.add("date", new DateParam(ParamPrefixEnum.LESSTHAN, immunization.getOccurrenceDateTimeType()));
params.add("vaccine-code", new TokenOrListParam(SYSTEM_CVX, covidImmunizationCodes.toArray(new String[0])));
params.add("status", new TokenParam(Immunization.ImmunizationStatus.COMPLETED.getSystem(),
Immunization.ImmunizationStatus.COMPLETED.toCode()));
IFhirResourceDao<Immunization> resourceDao = getDaoRegistry().getResourceDao(Immunization.class);
IBundleProvider search = resourceDao.search(params);
if (search.isEmpty()) {
return null;
}
return (Immunization) search.getResources(0, 1).get(0);
}
private Patient getPatientFromRef(Reference ref) {
IFhirResourceDao<Patient> resourceDao = getDaoRegistry().getResourceDao(Patient.class);
return resourceDao.read(ref.getReferenceElement());
}
private boolean isCovidImmunization(Immunization immunization) {
return immunization.getVaccineCode().getCoding()
.stream()
.filter(c -> SYSTEM_CVX.equals(c.getSystem()))
.anyMatch(c -> covidImmunizationCodes.contains(c.getCode()));
}
public FhirContext getFhirContext() {
return fhirContext;
}
public void setFhirContext(FhirContext fhirContext) {
this.fhirContext = fhirContext;
}
public DaoRegistry getDaoRegistry() {
return daoRegistry;
}
public void setDaoRegistry(DaoRegistry daoRegistry) {
this.daoRegistry = daoRegistry;
}
public String getIssuerServerBase() {
return issuerServerBase;
}
public void setIssuerServerBase(String issuerServerBase) {
this.issuerServerBase = issuerServerBase;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment