use of org.hl7.fhir.r4.model.PlanDefinition in project cqf-ruler by DBCG.
the class CdsHooksServlet method doPost.
@Override
@SuppressWarnings("deprecation")
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.info(request.getRequestURI());
try {
// validate that we are dealing with JSON
if (request.getContentType() == null || !request.getContentType().startsWith("application/json")) {
throw new ServletException(String.format("Invalid content type %s. Please use application/json.", request.getContentType()));
}
String baseUrl = this.myAppProperties.getServer_address();
String service = request.getPathInfo().replace("/", "");
JsonParser parser = new JsonParser();
Request cdsHooksRequest = new Request(service, parser.parse(request.getReader()).getAsJsonObject(), JsonHelper.getObjectRequired(getService(service), "prefetch"));
logger.info(cdsHooksRequest.getRequestJson().toString());
Hook hook = HookFactory.createHook(cdsHooksRequest);
String hookName = hook.getRequest().getHook();
logger.info("cds-hooks hook: {}", hookName);
logger.info("cds-hooks hook instance: {}", hook.getRequest().getHookInstance());
logger.info("cds-hooks maxCodesPerQuery: {}", this.getProviderConfiguration().getMaxCodesPerQuery());
logger.info("cds-hooks expandValueSets: {}", this.getProviderConfiguration().getExpandValueSets());
logger.info("cds-hooks searchStyle: {}", this.getProviderConfiguration().getSearchStyle());
logger.info("cds-hooks prefetch maxUriLength: {}", this.getProviderConfiguration().getMaxUriLength());
logger.info("cds-hooks local server address: {}", baseUrl);
logger.info("cds-hooks fhir server address: {}", hook.getRequest().getFhirServerUrl());
logger.info("cds-hooks cql_logging_enabled: {}", this.getProviderConfiguration().getCqlLoggingEnabled());
PlanDefinition planDefinition = read(Ids.newId(PlanDefinition.class, hook.getRequest().getServiceName()));
AtomicBoolean planDefinitionHookMatchesRequestHook = new AtomicBoolean(false);
planDefinition.getAction().forEach(action -> {
action.getTrigger().forEach(trigger -> {
if (hookName.equals(trigger.getName())) {
planDefinitionHookMatchesRequestHook.set(true);
return;
}
});
if (planDefinitionHookMatchesRequestHook.get()) {
return;
}
});
if (!planDefinitionHookMatchesRequestHook.get()) {
throw new ServletException("ERROR: Request hook does not match the service called.");
}
// No tenant information available, so create local system request
RequestDetails requestDetails = new SystemRequestDetails();
LibraryLoader libraryLoader = libraryLoaderFactory.create(Lists.newArrayList(jpaLibraryContentProviderFactory.create(requestDetails)));
CanonicalType canonical = planDefinition.getLibrary().get(0);
Library library = search(Library.class, Searches.byCanonical(canonical)).single();
org.cqframework.cql.elm.execution.Library elm = libraryLoader.load(new VersionedIdentifier().withId(library.getName()).withVersion(library.getVersion()));
Context context = new Context(elm);
context.setDebugMap(this.getDebugMap());
// provider case
// No tenant information available for cds-hooks
TerminologyProvider serverTerminologyProvider = myJpaTerminologyProviderFactory.create(requestDetails);
context.registerDataProvider("http://hl7.org/fhir", // TODO make sure tooling
fhirRetrieveProviderFactory.create(requestDetails, serverTerminologyProvider));
// handles remote
context.registerTerminologyProvider(serverTerminologyProvider);
context.registerLibraryLoader(libraryLoader);
context.setContextValue("Patient", hook.getRequest().getContext().getPatientId().replace("Patient/", ""));
context.setExpressionCaching(true);
EvaluationContext<PlanDefinition> evaluationContext = new R4EvaluationContext(hook, FhirContext.forCached(FhirVersionEnum.R4).newRestfulGenericClient(baseUrl), context, elm, planDefinition, this.getProviderConfiguration(), this.modelResolver);
this.setAccessControlHeaders(response);
response.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
R4HookEvaluator evaluator = new R4HookEvaluator(this.modelResolver);
String jsonResponse = toJsonResponse(evaluator.evaluate(evaluationContext));
logger.info(jsonResponse);
response.getWriter().println(jsonResponse);
} catch (BaseServerResponseException e) {
this.setAccessControlHeaders(response);
// This will be overwritten with the correct status code downstream if needed.
response.setStatus(500);
response.getWriter().println("ERROR: Exception connecting to remote server.");
this.printMessageAndCause(e, response);
this.handleServerResponseException(e, response);
this.printStackTrack(e, response);
logger.error(e.toString());
} catch (DataProviderException e) {
this.setAccessControlHeaders(response);
// This will be overwritten with the correct status code downstream if needed.
response.setStatus(500);
response.getWriter().println("ERROR: Exception in DataProvider.");
this.printMessageAndCause(e, response);
if (e.getCause() != null && (e.getCause() instanceof BaseServerResponseException)) {
this.handleServerResponseException((BaseServerResponseException) e.getCause(), response);
}
this.printStackTrack(e, response);
logger.error(e.toString());
} catch (CqlException e) {
this.setAccessControlHeaders(response);
// This will be overwritten with the correct status code downstream if needed.
response.setStatus(500);
response.getWriter().println("ERROR: Exception in CQL Execution.");
this.printMessageAndCause(e, response);
if (e.getCause() != null && (e.getCause() instanceof BaseServerResponseException)) {
this.handleServerResponseException((BaseServerResponseException) e.getCause(), response);
}
this.printStackTrack(e, response);
logger.error(e.toString());
} catch (Exception e) {
logger.error(e.toString());
throw new ServletException("ERROR: Exception in cds-hooks processing.", e);
}
}
use of org.hl7.fhir.r4.model.PlanDefinition in project cqf-ruler by DBCG.
the class PlanDefinitionApplyProviderIT method testPlanDefinitionApplyFormerSmoker.
@Test
public void testPlanDefinitionApplyFormerSmoker() throws Exception {
DomainResource plandefinition = (DomainResource) planDefinitions.get("lcs-cds-patient-view");
// Patient First
uploadTests("test/plandefinition/LungCancerScreening/Former-Smoker/Patient");
Map<String, IBaseResource> resources = uploadTests("test/plandefinition/LungCancerScreening/Former-Smoker");
IBaseResource patient = resources.get("Former-Smoker");
Object isFormerSmoker = planDefinitionApplyProvider.applyPlanDefinition(new SystemRequestDetails(), plandefinition.getIdElement(), patient.getIdElement().getIdPart(), null, null, null, null, null, null, null, null);
assertTrue(isFormerSmoker instanceof CarePlan);
}
use of org.hl7.fhir.r4.model.PlanDefinition in project cqf-ruler by DBCG.
the class Session method applyPlanDefinition.
@Operation(name = "$apply", idempotent = true, type = PlanDefinition.class)
public CarePlan applyPlanDefinition(RequestDetails theRequest, @IdParam IdType theId, @OperationParam(name = "patient") String patientId, @OperationParam(name = "encounter") String encounterId, @OperationParam(name = "practitioner") String practitionerId, @OperationParam(name = "organization") String organizationId, @OperationParam(name = "userType") String userType, @OperationParam(name = "userLanguage") String userLanguage, @OperationParam(name = "userTaskContext") String userTaskContext, @OperationParam(name = "setting") String setting, @OperationParam(name = "settingContext") String settingContext) throws IOException, FHIRException {
PlanDefinition planDefinition = this.planDefinitionDao.read(theId);
if (planDefinition == null) {
throw new IllegalArgumentException("Couldn't find PlanDefinition " + theId);
}
logger.info("Performing $apply operation on PlanDefinition/{}", theId);
CarePlanBuilder builder = new CarePlanBuilder();
builder.buildInstantiatesCanonical(planDefinition.getUrl()).buildSubject(new Reference(patientId)).buildStatus(CarePlan.CarePlanStatus.DRAFT);
if (encounterId != null)
builder.buildEncounter(new Reference(encounterId));
if (practitionerId != null)
builder.buildAuthor(new Reference(practitionerId));
if (organizationId != null)
builder.buildAuthor(new Reference(organizationId));
if (userLanguage != null)
builder.buildLanguage(userLanguage);
// Each Group of actions shares a RequestGroup
RequestGroupBuilder requestGroupBuilder = new RequestGroupBuilder().buildStatus().buildIntent();
Session session = new Session(planDefinition, builder, patientId, encounterId, practitionerId, organizationId, userType, userLanguage, userTaskContext, setting, settingContext, requestGroupBuilder);
return (CarePlan) ContainedHelper.liftContainedResourcesToParent(resolveActions(session, theRequest));
}
use of org.hl7.fhir.r4.model.PlanDefinition in project cqf-ruler by DBCG.
the class Session method resolveCdsHooksPlanDefinition.
// For library use
public CarePlan resolveCdsHooksPlanDefinition(RequestDetails theRequest, Context context, PlanDefinition planDefinition, String patientId) {
CarePlanBuilder carePlanBuilder = new CarePlanBuilder();
RequestGroupBuilder requestGroupBuilder = new RequestGroupBuilder().buildStatus().buildIntent();
// links
if (planDefinition.hasRelatedArtifact()) {
List<Extension> extensions = new ArrayList<>();
for (RelatedArtifact relatedArtifact : planDefinition.getRelatedArtifact()) {
AttachmentBuilder attachmentBuilder = new AttachmentBuilder();
ExtensionBuilder extensionBuilder = new ExtensionBuilder();
if (relatedArtifact.hasDisplay()) {
// label
attachmentBuilder.buildTitle(relatedArtifact.getDisplay());
}
if (relatedArtifact.hasUrl()) {
// url
attachmentBuilder.buildUrl(relatedArtifact.getUrl());
}
if (relatedArtifact.hasExtension()) {
// type
attachmentBuilder.buildExtension(relatedArtifact.getExtension());
}
extensionBuilder.buildUrl("http://example.org");
extensionBuilder.buildValue(attachmentBuilder.build());
extensions.add(extensionBuilder.build());
}
requestGroupBuilder.buildExtension(extensions);
}
resolveActions(theRequest, planDefinition, planDefinition.getAction(), context, patientId, requestGroupBuilder, new ArrayList<>());
CarePlanActivityBuilder carePlanActivityBuilder = new CarePlanActivityBuilder();
carePlanActivityBuilder.buildReferenceTarget(requestGroupBuilder.build());
carePlanBuilder.buildActivity(carePlanActivityBuilder.build());
return carePlanBuilder.build();
}
use of org.hl7.fhir.r4.model.PlanDefinition in project cqf-ruler by DBCG.
the class Session method applyPlanDefinition.
@Operation(name = "$apply", idempotent = true, type = PlanDefinition.class)
public CarePlan applyPlanDefinition(RequestDetails theRequest, @IdParam IdType theId, @OperationParam(name = "patient") String patientId, @OperationParam(name = "encounter") String encounterId, @OperationParam(name = "practitioner") String practitionerId, @OperationParam(name = "organization") String organizationId, @OperationParam(name = "userType") String userType, @OperationParam(name = "userLanguage") String userLanguage, @OperationParam(name = "userTaskContext") String userTaskContext, @OperationParam(name = "setting") String setting, @OperationParam(name = "settingContext") String settingContext) throws IOException, FHIRException {
PlanDefinition planDefinition = this.planDefinitionDao.read(theId);
if (planDefinition == null) {
throw new IllegalArgumentException("Couldn't find PlanDefinition " + theId);
}
logger.info("Performing $apply operation on PlanDefinition/{}", theId);
CarePlanBuilder builder = new CarePlanBuilder();
builder.buildDefinition(new Reference(planDefinition.getIdElement().getIdPart())).buildSubject(new Reference(patientId)).buildStatus(CarePlan.CarePlanStatus.DRAFT);
if (encounterId != null)
builder.buildContext(new Reference(encounterId));
if (practitionerId != null)
builder.buildAuthor(new Reference(practitionerId));
if (organizationId != null)
builder.buildAuthor(new Reference(organizationId));
if (userLanguage != null)
builder.buildLanguage(userLanguage);
// Each Group of actions shares a RequestGroup
RequestGroupBuilder requestGroupBuilder = new RequestGroupBuilder().buildStatus().buildIntent();
Session session = new Session(planDefinition, builder, patientId, encounterId, practitionerId, organizationId, userType, userLanguage, userTaskContext, setting, settingContext, requestGroupBuilder);
return (CarePlan) ContainedHelper.liftContainedResourcesToParent(resolveActions(theRequest, session));
}
Aggregations