Skip to content

Commit

Permalink
Recommendation Foracast operation in progress, Interface created for …
Browse files Browse the repository at this point in the history
…services present across R4 and R5 config
  • Loading branch information
cerbeor committed Oct 21, 2024
1 parent 8d0551c commit a2a0fad
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 68 deletions.
44 changes: 17 additions & 27 deletions src/main/java/org/immregistries/iis/kernal/fhir/ServerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;

import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.config.ThreadPoolFactoryConfig;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
Expand All @@ -18,19 +17,13 @@
import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor;
import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider;
import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc;
import ca.uhn.fhir.jpa.partition.PartitionManagementProvider;
import ca.uhn.fhir.jpa.provider.*;
import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider;
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.mdm.provider.MdmProviderLoader;
import org.immregistries.iis.kernal.fhir.bulkQuery.BulkQueryGroupProviderR4;
import org.immregistries.iis.kernal.fhir.bulkQuery.BulkQueryGroupProviderR5;
import org.immregistries.iis.kernal.fhir.bulkQuery.CustomBulkDataExportProvider;
import org.immregistries.iis.kernal.fhir.common.StarterJpaConfig;
import org.immregistries.iis.kernal.fhir.interceptors.*;
import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor;
import ca.uhn.fhir.mdm.provider.MdmProviderLoader;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.narrative2.NullNarrativeGenerator;
import ca.uhn.fhir.rest.openapi.OpenApiInterceptor;
Expand All @@ -42,6 +35,15 @@
import ca.uhn.fhir.validation.IValidatorModule;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import com.google.common.base.Strings;
import org.immregistries.iis.kernal.fhir.bulkQuery.BulkQueryGroupProviderR4;
import org.immregistries.iis.kernal.fhir.bulkQuery.BulkQueryGroupProviderR5;
import org.immregistries.iis.kernal.fhir.bulkQuery.CustomBulkDataExportProvider;
import org.immregistries.iis.kernal.fhir.common.StarterJpaConfig;
import org.immregistries.iis.kernal.fhir.immdsForecast.IRecommendationForecastProvider;
import org.immregistries.iis.kernal.fhir.interceptors.GroupAuthorityInterceptor;
import org.immregistries.iis.kernal.fhir.interceptors.IIdentifierSolverInterceptor;
import org.immregistries.iis.kernal.fhir.interceptors.PartitionCreationInterceptor;
import org.immregistries.iis.kernal.fhir.interceptors.SessionAuthorizationInterceptor;
import org.immregistries.iis.kernal.fhir.ips.IpsConfig;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
Expand Down Expand Up @@ -70,12 +72,12 @@ public RestfulServer restfulServer(IFhirSystemDao<?, ?> fhirSystemDao, AppProper
PartitionCreationInterceptor partitionCreationInterceptor,
Optional<BulkQueryGroupProviderR5> bulkQueryGroupProviderR5,
Optional<BulkQueryGroupProviderR4> bulkQueryGroupProviderR4,
Optional<IdentifierSolverInterceptorR5> identifierSolverInterceptorR5,
Optional<IdentifierSolverInterceptorR4> identifierSolverInterceptorR4,
Optional<IIdentifierSolverInterceptor> identifierSolverInterceptor,
Optional<IFhirResourceDao<org.hl7.fhir.r4.model.Group>> fhirResourceGroupDaoR4,
Optional<IFhirResourceDao<org.hl7.fhir.r5.model.Group>> fhirResourceGroupDaoR5,
Optional<GroupAuthorityInterceptor> groupAuthorityInterceptor,
IpsOperationProvider ipsOperationProvider,
Optional<IRecommendationForecastProvider> recommendationForecastProvider,
SessionAuthorizationInterceptor sessionAuthorizationInterceptor) {
RestfulServer fhirServer = new RestfulServer(fhirSystemDao.getContext());
List<String> supportedResourceTypes = appProperties.getSupported_resource_types();
Expand Down Expand Up @@ -263,15 +265,12 @@ public RestfulServer restfulServer(IFhirSystemDao<?, ?> fhirSystemDao, AppProper
repositoryValidatingInterceptor.ifPresent(fhirServer::registerInterceptor);

//register the IPS Provider
if (!theIpsOperationProvider.isEmpty()) {
fhirServer.registerProvider(theIpsOperationProvider.get());
}
theIpsOperationProvider.ifPresent(fhirServer::registerProvider);
// recommendationForecastProvider.ifPresent(fhirServer::registerProvider);

// register custom interceptors
fhirServer.registerInterceptor(sessionAuthorizationInterceptor);
if (identifierSolverInterceptorR5.isPresent()) {
fhirServer.registerInterceptor(identifierSolverInterceptorR5.get());
} else identifierSolverInterceptorR4.ifPresent(fhirServer::registerInterceptor);
identifierSolverInterceptor.ifPresent(fhirServer::registerInterceptor);
// registerCustomInterceptors(fhirServer, appContext, appProperties.getCustomInterceptorClasses());
groupAuthorityInterceptor.ifPresent(fhirServer::registerInterceptor);

Expand Down Expand Up @@ -322,16 +321,7 @@ private void registerCustomInterceptors(RestfulServer fhirServer, ApplicationCon

public static IServerConformanceProvider<?> calculateConformanceProvider(IFhirSystemDao fhirSystemDao, RestfulServer fhirServer, JpaStorageSettings jpaStorageSettings, ISearchParamRegistry searchParamRegistry, IValidationSupport theValidationSupport) {
FhirVersionEnum fhirVersion = fhirSystemDao.getContext().getVersion().getVersion();
if (fhirVersion == FhirVersionEnum.DSTU2) {
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(fhirServer, fhirSystemDao, jpaStorageSettings);
confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server");
return confProvider;
} else if (fhirVersion == FhirVersionEnum.DSTU3) {

JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry);
confProvider.setImplementationDescription("HAPI FHIR DSTU3 Server");
return confProvider;
} else if (fhirVersion == FhirVersionEnum.R4) {
if (fhirVersion == FhirVersionEnum.R4) {

JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry, theValidationSupport);
confProvider.setImplementationDescription("HAPI FHIR R4 Server");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.immregistries.iis.kernal.fhir.immdsForecast;

import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IDomainResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;

import java.util.Date;
import java.util.List;

public interface IRecommendationForecastProvider<Parameters extends IBaseParameters, Patient extends IDomainResource, Immunization extends IDomainResource> {
String $_IMMDS_FORECAST = "$immds-forecast";
String ASSESSMENT_DATE = "assessmentDate";
String PATIENT = "patient";
String RECOMMENDATION = "recommendation";
String IMMUNIZATION = "immunization";

@Operation(name = $_IMMDS_FORECAST)
Parameters immdsForecastOperation(
@Description(shortDefinition = "The date on which to assess the forecast.")
@OperationParam(name = ASSESSMENT_DATE, min = 1, max = 1, typeName = "date")
IPrimitiveType<Date> assessmentDate,
@Description(shortDefinition = "Patient information.")
@OperationParam(name = PATIENT, min = 1, max = 1)
Patient patient,
@Description(shortDefinition = "Patient immunization history.")
@OperationParam(name = IMMUNIZATION)
List<Immunization> immunization);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.immregistries.iis.kernal.fhir.immdsForecast;


import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Immunization;
import org.hl7.fhir.r4.model.ImmunizationRecommendation;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient;
import org.immregistries.iis.kernal.fhir.annotations.OnR4Condition;
import org.immregistries.iis.kernal.fhir.security.ServletHelper;
import org.immregistries.iis.kernal.logic.ImmunizationRecommendationServiceR4;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Controller;

import java.util.Date;
import java.util.List;

@Controller
@Conditional(OnR4Condition.class)
public class RecommendationForecastProviderR4 implements IRecommendationForecastProvider<Parameters, Patient, Immunization> {

@Autowired
ImmunizationRecommendationServiceR4 immunizationRecommendationServiceR4;

@Override
@Operation(name = $_IMMDS_FORECAST)
public Parameters immdsForecastOperation(
@Description(shortDefinition = "The date on which to assess the forecast.")
@OperationParam(name = ASSESSMENT_DATE, min = 1, max = 1, typeName = "date")
IPrimitiveType<Date> assessmentDate,
@Description(shortDefinition = "Patient information.")
@OperationParam(name = PATIENT, min = 1, max = 1)
Patient patient,
@Description(shortDefinition = "Patient immunization history.")
@OperationParam(name = IMMUNIZATION)
List<Immunization> immunization
) {
Parameters out = new Parameters();
ImmunizationRecommendation immunizationRecommendation = immunizationRecommendationServiceR4.generate(ServletHelper.getTenant(), new Date(), patient);// generate(assessmentDate.getValue(), patient);
out.addParameter().setName(RECOMMENDATION).setResource(immunizationRecommendation);
return out;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.immregistries.iis.kernal.fhir.immdsForecast;

import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r5.model.Immunization;
import org.hl7.fhir.r5.model.ImmunizationRecommendation;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Patient;
import org.immregistries.iis.kernal.fhir.annotations.OnR5Condition;
import org.immregistries.iis.kernal.fhir.security.ServletHelper;
import org.immregistries.iis.kernal.logic.ImmunizationRecommendationServiceR5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Controller;

import java.util.Date;
import java.util.List;

@Controller
@Conditional(OnR5Condition.class)
public class RecommendationForecastProviderR5 implements IRecommendationForecastProvider<Parameters, Patient, Immunization> {

@Autowired
ImmunizationRecommendationServiceR5 immunizationRecommendationServiceR5;

@Override
@Operation(name = $_IMMDS_FORECAST)
public Parameters immdsForecastOperation(
@Description(shortDefinition = "The date on which to assess the forecast.")
@OperationParam(name = ASSESSMENT_DATE, min = 1, max = 1, typeName = "date")
IPrimitiveType<Date> assessmentDate,
@Description(shortDefinition = "Patient information.")
@OperationParam(name = PATIENT, min = 1, max = 1)
Patient patient,
@Description(shortDefinition = "Patient immunization history.")
@OperationParam(name = IMMUNIZATION)
List<Immunization> immunization
) {
Parameters out = new Parameters();
ImmunizationRecommendation immunizationRecommendation = immunizationRecommendationServiceR5.generate(ServletHelper.getTenant(), new Date(), patient);// generate(assessmentDate.getValue(), patient);
out.addParameter().setName(RECOMMENDATION).setResource(immunizationRecommendation);
return out;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.immregistries.iis.kernal.fhir.interceptors;

import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IDomainResource;

public interface IIdentifierSolverInterceptor<Identifier, Immunization extends IDomainResource, Group extends IDomainResource> {
/**
* Resolves business identifier resources to actual resources references id
* Currently only Immunization supported
* TODO support Observation and other
* TODO add flavours
*/
void handle(RequestDetails requestDetails) throws InvalidRequestException;

void handleImmunization(RequestDetails requestDetails, Immunization immunization);

void handleGroup(RequestDetails requestDetails, Group group);

String solvePatientIdentifier(RequestDetails requestDetails, Identifier identifier);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,15 @@
@Interceptor
@Conditional(OnR4Condition.class)
@Service
public class IdentifierSolverInterceptorR4 {
public class IdentifierSolverInterceptorR4 implements IIdentifierSolverInterceptor<Identifier, Immunization, Group> {

Logger logger = LoggerFactory.getLogger(IdentifierSolverInterceptorR4.class);

@Autowired
IFhirResourceDao<Patient> patientDao;

/**
* Resolves business identifier resources to actual resources references id
* Currently only Immunization supported
* TODO support Observation and other
* TODO add flavours
*/

@Override
@Hook(SERVER_INCOMING_REQUEST_PRE_HANDLED)
public void handle(RequestDetails requestDetails) throws InvalidRequestException {
if (requestDetails.getResource() instanceof Immunization) {
Expand All @@ -48,7 +44,8 @@ public void handle(RequestDetails requestDetails) throws InvalidRequestException
}
}

private void handleImmunization(RequestDetails requestDetails, Immunization immunization) {
@Override
public void handleImmunization(RequestDetails requestDetails, Immunization immunization) {

if (immunization == null
|| immunization.getPatient().getIdentifier() == null
Expand Down Expand Up @@ -77,7 +74,8 @@ private void handleImmunization(RequestDetails requestDetails, Immunization immu
}
}

private void handleGroup(RequestDetails requestDetails, Group group) {
@Override
public void handleGroup(RequestDetails requestDetails, Group group) {
logger.info("Identifier reference interception for Group");
for (Group.GroupMemberComponent memberComponent : group.getMember()) {
if (!memberComponent.getEntity().hasIdentifier()) {
Expand All @@ -101,6 +99,7 @@ private void handleGroup(RequestDetails requestDetails, Group group) {
}


@Override
public String solvePatientIdentifier(RequestDetails requestDetails, Identifier identifier) {
String id = null;
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,14 @@
@Interceptor
@Conditional(OnR5Condition.class)
@Service
public class IdentifierSolverInterceptorR5 {
public class IdentifierSolverInterceptorR5 implements IIdentifierSolverInterceptor<Identifier, Immunization, Group> {

Logger logger = LoggerFactory.getLogger(IdentifierSolverInterceptorR5.class);

@Autowired
IFhirResourceDao<Patient> patientDao;

/**
* Resolves business identifier resources to actual resources references id
* Currently only Immunization supported
* TODO support Observation and other
* TODO add flavours
*/
@Override
@Hook(SERVER_INCOMING_REQUEST_PRE_HANDLED)
public void handle(RequestDetails requestDetails) throws InvalidRequestException {
if (requestDetails.getResource() instanceof Immunization) {
Expand All @@ -48,7 +43,8 @@ public void handle(RequestDetails requestDetails) throws InvalidRequestException
}
}

private void handleImmunization(RequestDetails requestDetails, Immunization immunization) {
@Override
public void handleImmunization(RequestDetails requestDetails, Immunization immunization) {

if (immunization == null
|| immunization.getPatient().getIdentifier() == null
Expand Down Expand Up @@ -77,7 +73,8 @@ private void handleImmunization(RequestDetails requestDetails, Immunization immu
}
}

private void handleGroup(RequestDetails requestDetails, Group group) {
@Override
public void handleGroup(RequestDetails requestDetails, Group group) {
logger.info("Identifier reference interception for Group");
for (Group.GroupMemberComponent memberComponent : group.getMember()) {
if (!memberComponent.getEntity().hasIdentifier()) {
Expand All @@ -101,6 +98,7 @@ private void handleGroup(RequestDetails requestDetails, Group group) {
}


@Override
public String solvePatientIdentifier(RequestDetails requestDetails, Identifier identifier) {
String id = null;
/**
Expand All @@ -112,8 +110,8 @@ public String solvePatientIdentifier(RequestDetails requestDetails, Identifier i
.setValue(GOLDEN_RECORD));
if (StringUtils.isNotBlank(identifier.getSystem())) {
goldenSearchParameterMap.add(Patient.SP_IDENTIFIER, new TokenParam()
.setSystem(identifier.getSystem())
.setValue(identifier.getValue()));
.setSystem(identifier.getSystem())
.setValue(identifier.getValue()));
} else {
goldenSearchParameterMap.add(Patient.SP_IDENTIFIER, new TokenParam()
.setValue(identifier.getValue()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.mdm.util.*;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.util.TerserUtil;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
Expand All @@ -23,10 +22,10 @@

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import static ca.uhn.fhir.context.FhirVersionEnum.*;
import static ca.uhn.fhir.context.FhirVersionEnum.R4;
import static ca.uhn.fhir.context.FhirVersionEnum.R5;

/**
* Custom Made for Accepting R5 and adding any original identifier to golden identifiers
Expand Down Expand Up @@ -190,7 +189,7 @@ private void cloneMDMEidsIntoNewGoldenResource(

private void validateContextSupported() {
FhirVersionEnum fhirVersion = myFhirContext.getVersion().getVersion();
if (fhirVersion == R5 ||fhirVersion == R4 || fhirVersion == DSTU3) {
if (fhirVersion == R5 || fhirVersion == R4) {
return;
}
throw new UnsupportedOperationException(Msg.code(1489) + "Version not supported: "
Expand Down
Loading

0 comments on commit a2a0fad

Please sign in to comment.