use of org.hl7.davinci.endpoint.Application in project beneficiary-fhir-data by CMSgov.
the class R4PatientResourceProviderIT method testLastUpdatedUrls.
/**
* Test the set of lastUpdated values
*
* @param fhirClient to use
* @param id the beneficiary id to use
* @param urls is a list of lastUpdate values to test to find
* @param expectedValue number of matches
*/
private void testLastUpdatedUrls(IGenericClient fhirClient, String id, List<String> urls, int expectedValue) {
String baseResourceUrl = "Patient?_id=" + id + "&_format=application%2Fjson%2Bfhir";
// Search for each lastUpdated value
for (String lastUpdatedValue : urls) {
String theSearchUrl = baseResourceUrl + "&" + lastUpdatedValue;
Bundle searchResults = fhirClient.search().byUrl(theSearchUrl).returnBundle(Bundle.class).execute();
assertEquals(expectedValue, searchResults.getTotal(), String.format("Expected %s to filter resources using lastUpdated correctly", lastUpdatedValue));
}
}
use of org.hl7.davinci.endpoint.Application 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.davinci.endpoint.Application 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.davinci.endpoint.Application in project cqf-ruler by DBCG.
the class ReportProviderIT method testSubjectPatientNotFoundInGroup.
// This test requires the following application setting:
// enforce_referential_integrity_on_write: false
@Disabled("Provider needs to be updated to use parameter validation and then this test should be re-enabled")
@Test
public void testSubjectPatientNotFoundInGroup() throws IOException {
Parameters params = new Parameters();
params.addParameter().setName("periodStart").setValue(new StringType("2021-01-01"));
params.addParameter().setName("periodEnd").setValue(new StringType("2021-12-31"));
params.addParameter().setName("subject").setValue(new StringType("Group/ra-group00"));
loadResource("Group-ra-group00.json");
Group group = getClient().read().resource(Group.class).withId("ra-group00").execute();
assertNotNull(group);
assertThrows(ResourceNotFoundException.class, () -> {
getClient().operation().onType(MeasureReport.class).named("$report").withParameters(params).returnResourceType(Parameters.class).execute();
});
}
use of org.hl7.davinci.endpoint.Application in project quality-measure-and-cohort-service by Alvearie.
the class CohortEngineRestHandler method evaluateMeasure.
@POST
@Path("/evaluation")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Evaluates a measure bundle for a single patient", notes = EVALUATION_API_NOTES, response = String.class, tags = { "Measure Evaluation" }, nickname = "evaluate_measure", extensions = { @Extension(properties = { @ExtensionProperty(name = DarkFeatureSwaggerFilter.DARK_FEATURE_NAME, value = CohortEngineRestConstants.DARK_LAUNCHED_MEASURE_EVALUATION) }) })
@ApiImplicitParams({ // This is necessary for the dark launch feature
@ApiImplicitParam(access = DarkFeatureSwaggerFilter.DARK_FEATURE_CONTROLLED, paramType = "header", dataType = "string"), // These are necessary to create a proper view of the request body that is all wrapped up in the Liberty IMultipartBody parameter
@ApiImplicitParam(name = REQUEST_DATA_PART, value = EXAMPLE_REQUEST_DATA_JSON, dataTypeClass = MeasureEvaluation.class, required = true, paramType = "form", type = "file"), @ApiImplicitParam(name = MEASURE_PART, value = EXAMPLE_MEASURE_ZIP, dataTypeClass = File.class, required = true, paramType = "form", type = "file") })
@ApiResponses(value = { @ApiResponse(code = 200, message = "Successful Operation: This API returns the JSON representation of a FHIR MeasureReport. A full example can be found at https://www.hl7.org/fhir/measurereport-cms146-cat1-example.html"), @ApiResponse(code = 400, message = "Bad Request", response = ServiceErrorList.class), @ApiResponse(code = 500, message = "Server Error", response = ServiceErrorList.class) })
public Response evaluateMeasure(@Context HttpServletRequest request, @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) {
final String methodName = MethodNames.EVALUATE_MEASURE.getName();
Response response = null;
// Error out if feature is not enabled
ServiceBaseUtility.isDarkFeatureEnabled(CohortEngineRestConstants.DARK_LAUNCHED_MEASURE_EVALUATION);
try {
// Perform api setup
Response errorResponse = ServiceBaseUtility.apiSetup(version, logger, methodName);
if (errorResponse != null) {
return errorResponse;
}
if (multipartBody == null) {
throw new IllegalArgumentException("A multipart/form-data body is required");
}
IAttachment metadataAttachment = multipartBody.getAttachment(REQUEST_DATA_PART);
if (metadataAttachment == null) {
throw new IllegalArgumentException(String.format("Missing '%s' MIME attachment", REQUEST_DATA_PART));
}
IAttachment measureAttachment = multipartBody.getAttachment(MEASURE_PART);
if (measureAttachment == null) {
throw new IllegalArgumentException(String.format("Missing '%s' MIME attachment", MEASURE_PART));
}
// deserialize the MeasuresEvaluation request
ObjectMapper om = new ObjectMapper();
MeasureEvaluation evaluationRequest = om.readValue(metadataAttachment.getDataHandler().getInputStream(), MeasureEvaluation.class);
// validate the contents of the evaluationRequest
validateBean(evaluationRequest);
FhirContext fhirContext = FhirContext.forR4();
try (InputStream is = measureAttachment.getDataHandler().getInputStream();
RetrieveCacheContext retrieveCacheContext = new DefaultRetrieveCacheContext()) {
MeasureEvaluator evaluator = createMeasureEvaluator(is, evaluationRequest.getDataServerConfig(), evaluationRequest.getTerminologyServerConfig(), evaluationRequest.isExpandValueSets(), evaluationRequest.getSearchPageSize(), retrieveCacheContext, fhirContext);
MeasureReport report = evaluator.evaluatePatientMeasure(evaluationRequest.getPatientId(), evaluationRequest.getMeasureContext(), evaluationRequest.getEvidenceOptions());
// The default serializer gets into an infinite loop when trying to serialize MeasureReport, so we use the
// HAPI encoder instead.
IParser parser = fhirContext.newJsonParser();
ResponseBuilder responseBuilder = Response.status(Response.Status.OK).header("Content-Type", "application/json").entity(parser.encodeResourceToString(report));
response = responseBuilder.build();
}
} catch (Throwable e) {
// map any exceptions caught into the proper REST error response objects
response = new CohortServiceExceptionMapper().toResponse(e);
} finally {
// Perform api cleanup
Response errorResponse = ServiceBaseUtility.apiCleanup(logger, methodName);
if (errorResponse != null) {
response = errorResponse;
}
}
return response;
}
Aggregations