Last active
June 6, 2021 16:48
-
-
Save nvg/e76d158cf5aeb952c8df9b6e5501b64c to your computer and use it in GitHub Desktop.
Immunization Interceptor Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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