use of org.hl7.gravity.refimpl.sdohexchange.model.Server 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();
JsonObject requestJson = parser.parse(request.getReader()).getAsJsonObject();
logger.info(requestJson.toString());
Request cdsHooksRequest = new Request(service, requestJson, JsonHelper.getObjectRequired(getService(service), "prefetch"));
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.getTriggerDefinition().forEach(triggerDefn -> {
if (hookName.equals(triggerDefn.getEventName())) {
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)));
Reference reference = planDefinition.getLibrary().get(0);
Library library = read(reference.getReferenceElement());
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);
// TODO make sure tooling handles remote
context.registerDataProvider("http://hl7.org/fhir", fhirRetrieveProviderFactory.create(requestDetails, serverTerminologyProvider));
context.registerTerminologyProvider(serverTerminologyProvider);
context.registerLibraryLoader(libraryLoader);
context.setContextValue("Patient", hook.getRequest().getContext().getPatientId().replace("Patient/", ""));
context.setExpressionCaching(true);
EvaluationContext<PlanDefinition> evaluationContext = new Stu3EvaluationContext(hook, FhirContext.forCached(FhirVersionEnum.DSTU3).newRestfulGenericClient(baseUrl), context, elm, planDefinition, this.getProviderConfiguration(), this.modelResolver);
this.setAccessControlHeaders(response);
response.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
Stu3HookEvaluator evaluator = new Stu3HookEvaluator(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.gravity.refimpl.sdohexchange.model.Server 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.gravity.refimpl.sdohexchange.model.Server in project cqf-ruler by DBCG.
the class ExtractProviderIT method testExtract.
@Test
public void testExtract() throws IOException, URISyntaxException {
String examplePatient = "example_patient.json";
String exampleQuestionnaire = "questionnaire_1559.json";
String exampleQR = "questionnaire_response_1558.json";
loadResource(examplePatient);
loadResource(exampleQuestionnaire);
QuestionnaireResponse questionnaireResponse = (QuestionnaireResponse) loadResource(exampleQR);
Parameters params = new Parameters();
params.addParameter().setName("questionnaireResponse").setResource(questionnaireResponse);
Bundle actual = getClient().operation().onType(QuestionnaireResponse.class).named("$extract").withParameters(params).returnResourceType(Bundle.class).execute();
assertNotNull(actual);
// Expecting one observation per item
assertEquals(5, actual.getEntry().size());
// Ensure the Observations were saved to the local server
for (Bundle.BundleEntryComponent bec : actual.getEntry()) {
assertEquals("201 Created", bec.getResponse().getStatus());
}
}
use of org.hl7.gravity.refimpl.sdohexchange.model.Server in project cqf-ruler by DBCG.
the class ReportProvider method report.
/**
* Implements the <a href=
* "https://build.fhir.org/ig/HL7/davinci-ra/OperationDefinition-report.html">$report</a>
* operation found in the
* <a href="https://build.fhir.org/ig/HL7/davinci-ra/index.html">Da Vinci Risk
* Adjustment IG</a>.
*
* @param requestDetails metadata about the current request being processed.
* Generally auto-populated by the HAPI FHIR server
* framework.
* @param periodStart the start of the clinical evaluation period
* @param periodEnd the end of the clinical evaluation period
* @param subject a Patient or Patient Group
* @return a Parameters with Bundles of MeasureReports and evaluatedResource
* Resources
*/
@Description(shortDefinition = "$report", value = "Implements the <a href=\"https://build.fhir.org/ig/HL7/davinci-ra/OperationDefinition-report.html\">$report</a> operation found in the <a href=\"https://build.fhir.org/ig/HL7/davinci-ra/index.html\">Da Vinci Risk Adjustment IG</a>.")
@Operation(name = "$report", idempotent = true, type = MeasureReport.class)
public Parameters report(RequestDetails requestDetails, @OperationParam(name = "periodStart", min = 1, max = 1) String periodStart, @OperationParam(name = "periodEnd", min = 1, max = 1) String periodEnd, @OperationParam(name = "subject", min = 1, max = 1) String subject) throws FHIRException {
validateParameters(periodStart, periodEnd, subject);
Parameters result = newResource(Parameters.class, subject.replace("/", "-") + "-report");
Date periodStartDate = Operations.resolveRequestDate(periodStart, true);
Date periodEndDate = Operations.resolveRequestDate(periodEnd, false);
Period period = new Period().setStart(periodStartDate).setEnd(periodEndDate);
List<Patient> patients = getPatientListFromSubject(subject);
(patients).forEach(patient -> {
Parameters.ParametersParameterComponent patientParameter = patientReport(patient, period, requestDetails.getFhirServerBase());
result.addParameter(patientParameter);
});
return result;
}
use of org.hl7.gravity.refimpl.sdohexchange.model.Server in project quality-measure-and-cohort-service by Alvearie.
the class CohortEngineRestHandler method getMeasureParametersById.
@POST
@Path("/fhir/measure/{measure_id}/parameters")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@ApiOperation(value = "Get measure parameters by id", notes = CohortEngineRestHandler.MEASURE_API_NOTES, response = MeasureParameterInfoList.class, nickname = "get_measure_parameters_by_id", tags = { "FHIR Measures" })
@ApiImplicitParams({ @ApiImplicitParam(name = FHIR_DATA_SERVER_CONFIG_PART, value = CohortEngineRestHandler.EXAMPLE_DATA_SERVER_CONFIG_JSON, dataTypeClass = FhirServerConfig.class, required = true, paramType = "form", type = "file") })
@ApiResponses(value = { @ApiResponse(code = 200, message = "Successful Operation", response = MeasureParameterInfoList.class), @ApiResponse(code = 400, message = "Bad Request", response = ServiceErrorList.class), @ApiResponse(code = 500, message = "Server Error", response = ServiceErrorList.class) })
public Response getMeasureParametersById(@ApiParam(value = ServiceBaseConstants.MINOR_VERSION_DESCRIPTION, required = true, defaultValue = ServiceBuildConstants.DATE) @QueryParam(CohortEngineRestHandler.VERSION) String version, @ApiParam(hidden = true, type = "file", required = true) IMultipartBody multipartBody, @ApiParam(value = CohortEngineRestHandler.MEASURE_ID_DESC, required = true) @PathParam(CohortEngineRestHandler.MEASURE_ID) String measureId) {
final String methodName = MethodNames.GET_MEASURE_PARAMETERS_BY_ID.getName();
Response response = null;
try {
// Perform api setup
Response errorResponse = ServiceBaseUtility.apiSetup(version, logger, methodName);
if (errorResponse != null) {
return errorResponse;
}
IAttachment dataSourceAttachment = multipartBody.getAttachment(FHIR_DATA_SERVER_CONFIG_PART);
if (dataSourceAttachment == null) {
throw new IllegalArgumentException(String.format("Missing '%s' MIME attachment", FHIR_DATA_SERVER_CONFIG_PART));
}
// deserialize the MeasuresEvaluation request
ObjectMapper om = new ObjectMapper();
FhirServerConfig fhirServerConfig = om.readValue(dataSourceAttachment.getDataHandler().getInputStream(), FhirServerConfig.class);
// validate the contents of the fhirServerConfig
validateBean(fhirServerConfig);
// get the fhir client object used to call to FHIR
FhirClientBuilder clientBuilder = FhirClientBuilderFactory.newInstance().newFhirClientBuilder();
IGenericClient measureClient = clientBuilder.createFhirClient(fhirServerConfig);
// resolve the measure, and return the parameter info for all the libraries linked to by the measure
FhirResourceResolver<Measure> measureResolver = R4FhirServerResourceResolverFactory.createMeasureResolver(measureClient);
List<MeasureParameterInfo> parameterInfoList = FHIRRestUtils.getParametersForMeasureId(measureResolver, measureId);
// return the results
MeasureParameterInfoList status = new MeasureParameterInfoList().measureParameterInfoList(parameterInfoList);
response = Response.ok(status).build();
} catch (Throwable e) {
// map any exceptions caught into the proper REST error response objects
return new CohortServiceExceptionMapper().toResponse(e);
} finally {
// Perform api cleanup
Response errorResponse = ServiceBaseUtility.apiCleanup(logger, methodName);
if (errorResponse != null) {
response = errorResponse;
}
}
return response;
}
Aggregations