diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..13f820c43
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,283 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+tab_width = 3
+indent_size = 3
+charset = utf-8
+
+[*.xml]
+charset = utf-8
+indent_style = tab
+tab_width = 3
+indent_size = 3
+
+[*.json]
+charset = utf-8
+indent_style = tab
+tab_width = 3
+indent_size = 3
+
+[*.vm]
+charset = utf-8
+indent_style = tab
+tab_width = 3
+indent_size = 3
+
+
+[*.java]
+charset = utf-8
+indent_style = tab
+tab_width = 3
+indent_size = 3
+continuation_indent_size=3
+ij_java_align_consecutive_assignments = false
+ij_java_align_consecutive_variable_declarations = false
+ij_java_align_group_field_declarations = false
+ij_java_align_multiline_annotation_parameters = false
+ij_java_align_multiline_array_initializer_expression = false
+ij_java_align_multiline_assignment = false
+ij_java_align_multiline_binary_operation = false
+ij_java_align_multiline_chained_methods = false
+ij_java_align_multiline_extends_list = false
+ij_java_align_multiline_for = true
+ij_java_align_multiline_method_parentheses = false
+ij_java_align_multiline_parameters = true
+ij_java_align_multiline_parameters_in_calls = false
+ij_java_align_multiline_parenthesized_expression = false
+ij_java_align_multiline_records = true
+ij_java_align_multiline_resources = true
+ij_java_align_multiline_ternary_operation = false
+ij_java_align_multiline_text_blocks = false
+ij_java_align_multiline_throws_list = false
+ij_java_align_subsequent_simple_methods = false
+ij_java_align_throws_keyword = false
+ij_java_annotation_parameter_wrap = off
+ij_java_array_initializer_new_line_after_left_brace = false
+ij_java_array_initializer_right_brace_on_new_line = false
+ij_java_array_initializer_wrap = off
+ij_java_assert_statement_colon_on_next_line = false
+ij_java_assert_statement_wrap = off
+ij_java_assignment_wrap = off
+ij_java_binary_operation_sign_on_next_line = false
+ij_java_binary_operation_wrap = off
+ij_java_blank_lines_after_anonymous_class_header = 0
+ij_java_blank_lines_after_class_header = 0
+ij_java_blank_lines_after_imports = 1
+ij_java_blank_lines_after_package = 1
+ij_java_blank_lines_around_class = 1
+ij_java_blank_lines_around_field = 0
+ij_java_blank_lines_around_field_in_interface = 0
+ij_java_blank_lines_around_initializer = 1
+ij_java_blank_lines_around_method = 1
+ij_java_blank_lines_around_method_in_interface = 1
+ij_java_blank_lines_before_class_end = 0
+ij_java_blank_lines_before_imports = 1
+ij_java_blank_lines_before_method_body = 0
+ij_java_blank_lines_before_package = 0
+ij_java_block_brace_style = end_of_line
+ij_java_block_comment_at_first_column = true
+ij_java_call_parameters_new_line_after_left_paren = false
+ij_java_call_parameters_right_paren_on_new_line = false
+ij_java_call_parameters_wrap = off
+ij_java_case_statement_on_separate_line = true
+ij_java_catch_on_new_line = false
+ij_java_class_annotation_wrap = split_into_lines
+ij_java_class_brace_style = end_of_line
+ij_java_class_count_to_use_import_on_demand = 999
+ij_java_class_names_in_javadoc = 1
+ij_java_do_not_indent_top_level_class_members = false
+ij_java_do_not_wrap_after_single_annotation = false
+ij_java_do_while_brace_force = never
+ij_java_doc_add_blank_line_after_description = true
+ij_java_doc_add_blank_line_after_param_comments = false
+ij_java_doc_add_blank_line_after_return = false
+ij_java_doc_add_p_tag_on_empty_lines = true
+ij_java_doc_align_exception_comments = true
+ij_java_doc_align_param_comments = true
+ij_java_doc_do_not_wrap_if_one_line = false
+ij_java_doc_enable_formatting = true
+ij_java_doc_enable_leading_asterisks = true
+ij_java_doc_indent_on_continuation = false
+ij_java_doc_keep_empty_lines = true
+ij_java_doc_keep_empty_parameter_tag = true
+ij_java_doc_keep_empty_return_tag = true
+ij_java_doc_keep_empty_throws_tag = true
+ij_java_doc_keep_invalid_tags = true
+ij_java_doc_param_description_on_new_line = false
+ij_java_doc_preserve_line_breaks = false
+ij_java_doc_use_throws_not_exception_tag = true
+ij_java_else_on_new_line = false
+ij_java_entity_dd_suffix = EJB
+ij_java_entity_eb_suffix = Bean
+ij_java_entity_hi_suffix = Home
+ij_java_entity_lhi_prefix = Local
+ij_java_entity_lhi_suffix = Home
+ij_java_entity_li_prefix = Local
+ij_java_entity_pk_class = java.lang.String
+ij_java_entity_vo_suffix = VO
+ij_java_enum_constants_wrap = off
+ij_java_extends_keyword_wrap = off
+ij_java_extends_list_wrap = off
+ij_java_field_annotation_wrap = split_into_lines
+ij_java_field_name_prefix = my
+ij_java_finally_on_new_line = false
+ij_java_for_brace_force = never
+ij_java_for_statement_new_line_after_left_paren = false
+ij_java_for_statement_right_paren_on_new_line = false
+ij_java_for_statement_wrap = off
+ij_java_generate_final_locals = false
+ij_java_generate_final_parameters = false
+ij_java_if_brace_force = never
+ij_java_imports_layout = *,|,javax.**,java.**,|,$*
+ij_java_indent_case_from_switch = true
+ij_java_insert_inner_class_imports = false
+ij_java_insert_override_annotation = true
+ij_java_keep_blank_lines_before_right_brace = 2
+ij_java_keep_blank_lines_between_package_declaration_and_header = 2
+ij_java_keep_blank_lines_in_code = 2
+ij_java_keep_blank_lines_in_declarations = 2
+ij_java_keep_control_statement_in_one_line = true
+ij_java_keep_first_column_comment = true
+ij_java_keep_indents_on_empty_lines = false
+ij_java_keep_line_breaks = true
+ij_java_keep_multiple_expressions_in_one_line = false
+ij_java_keep_simple_blocks_in_one_line = false
+ij_java_keep_simple_classes_in_one_line = false
+ij_java_keep_simple_lambdas_in_one_line = false
+ij_java_keep_simple_methods_in_one_line = false
+ij_java_label_indent_absolute = false
+ij_java_label_indent_size = 0
+ij_java_lambda_brace_style = end_of_line
+ij_java_layout_static_imports_separately = true
+ij_java_line_comment_add_space = false
+ij_java_line_comment_at_first_column = true
+ij_java_message_dd_suffix = EJB
+ij_java_message_eb_suffix = Bean
+ij_java_method_annotation_wrap = split_into_lines
+ij_java_method_brace_style = end_of_line
+ij_java_method_call_chain_wrap = off
+ij_java_method_parameters_new_line_after_left_paren = false
+ij_java_method_parameters_right_paren_on_new_line = false
+ij_java_method_parameters_wrap = off
+ij_java_modifier_list_wrap = false
+ij_java_names_count_to_use_import_on_demand = 999
+ij_java_new_line_after_lparen_in_record_header = false
+ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
+ij_java_parameter_annotation_wrap = off
+ij_java_parameter_name_prefix = the
+ij_java_parentheses_expression_new_line_after_left_paren = false
+ij_java_parentheses_expression_right_paren_on_new_line = false
+ij_java_place_assignment_sign_on_next_line = false
+ij_java_prefer_longer_names = true
+ij_java_prefer_parameters_wrap = false
+ij_java_record_components_wrap = normal
+ij_java_repeat_synchronized = true
+ij_java_replace_instanceof_and_cast = false
+ij_java_replace_null_check = true
+ij_java_replace_sum_lambda_with_method_ref = true
+ij_java_resource_list_new_line_after_left_paren = false
+ij_java_resource_list_right_paren_on_new_line = false
+ij_java_resource_list_wrap = off
+ij_java_rparen_on_new_line_in_record_header = false
+ij_java_session_dd_suffix = EJB
+ij_java_session_eb_suffix = Bean
+ij_java_session_hi_suffix = Home
+ij_java_session_lhi_prefix = Local
+ij_java_session_lhi_suffix = Home
+ij_java_session_li_prefix = Local
+ij_java_session_si_suffix = Service
+ij_java_space_after_closing_angle_bracket_in_type_argument = false
+ij_java_space_after_colon = true
+ij_java_space_after_comma = true
+ij_java_space_after_comma_in_type_arguments = true
+ij_java_space_after_for_semicolon = true
+ij_java_space_after_quest = true
+ij_java_space_after_type_cast = true
+ij_java_space_before_annotation_array_initializer_left_brace = false
+ij_java_space_before_annotation_parameter_list = false
+ij_java_space_before_array_initializer_left_brace = false
+ij_java_space_before_catch_keyword = true
+ij_java_space_before_catch_left_brace = true
+ij_java_space_before_catch_parentheses = true
+ij_java_space_before_class_left_brace = true
+ij_java_space_before_colon = true
+ij_java_space_before_colon_in_foreach = true
+ij_java_space_before_comma = false
+ij_java_space_before_do_left_brace = true
+ij_java_space_before_else_keyword = true
+ij_java_space_before_else_left_brace = true
+ij_java_space_before_finally_keyword = true
+ij_java_space_before_finally_left_brace = true
+ij_java_space_before_for_left_brace = true
+ij_java_space_before_for_parentheses = true
+ij_java_space_before_for_semicolon = false
+ij_java_space_before_if_left_brace = true
+ij_java_space_before_if_parentheses = true
+ij_java_space_before_method_call_parentheses = false
+ij_java_space_before_method_left_brace = true
+ij_java_space_before_method_parentheses = false
+ij_java_space_before_opening_angle_bracket_in_type_parameter = false
+ij_java_space_before_quest = true
+ij_java_space_before_switch_left_brace = true
+ij_java_space_before_switch_parentheses = true
+ij_java_space_before_synchronized_left_brace = true
+ij_java_space_before_synchronized_parentheses = true
+ij_java_space_before_try_left_brace = true
+ij_java_space_before_try_parentheses = true
+ij_java_space_before_type_parameter_list = false
+ij_java_space_before_while_keyword = true
+ij_java_space_before_while_left_brace = true
+ij_java_space_before_while_parentheses = true
+ij_java_space_inside_one_line_enum_braces = false
+ij_java_space_within_empty_array_initializer_braces = false
+ij_java_space_within_empty_method_call_parentheses = false
+ij_java_space_within_empty_method_parentheses = false
+ij_java_spaces_around_additive_operators = true
+ij_java_spaces_around_assignment_operators = true
+ij_java_spaces_around_bitwise_operators = true
+ij_java_spaces_around_equality_operators = true
+ij_java_spaces_around_lambda_arrow = true
+ij_java_spaces_around_logical_operators = true
+ij_java_spaces_around_method_ref_dbl_colon = false
+ij_java_spaces_around_multiplicative_operators = true
+ij_java_spaces_around_relational_operators = true
+ij_java_spaces_around_shift_operators = true
+ij_java_spaces_around_type_bounds_in_type_parameters = true
+ij_java_spaces_around_unary_operator = false
+ij_java_spaces_within_angle_brackets = false
+ij_java_spaces_within_annotation_parentheses = false
+ij_java_spaces_within_array_initializer_braces = false
+ij_java_spaces_within_braces = false
+ij_java_spaces_within_brackets = false
+ij_java_spaces_within_cast_parentheses = false
+ij_java_spaces_within_catch_parentheses = false
+ij_java_spaces_within_for_parentheses = false
+ij_java_spaces_within_if_parentheses = false
+ij_java_spaces_within_method_call_parentheses = false
+ij_java_spaces_within_method_parentheses = false
+ij_java_spaces_within_parentheses = false
+ij_java_spaces_within_switch_parentheses = false
+ij_java_spaces_within_synchronized_parentheses = false
+ij_java_spaces_within_try_parentheses = false
+ij_java_spaces_within_while_parentheses = false
+ij_java_special_else_if_treatment = true
+ij_java_static_field_name_prefix = our
+ij_java_subclass_name_suffix = Impl
+ij_java_ternary_operation_signs_on_next_line = false
+ij_java_ternary_operation_wrap = off
+ij_java_test_name_suffix = Test
+ij_java_throws_keyword_wrap = off
+ij_java_throws_list_wrap = off
+ij_java_use_external_annotations = false
+ij_java_use_fq_class_names = false
+ij_java_use_relative_indents = false
+ij_java_use_single_class_imports = true
+ij_java_variable_annotation_wrap = off
+ij_java_visibility = public
+ij_java_while_brace_force = never
+ij_java_while_on_new_line = false
+ij_java_wrap_comments = false
+ij_java_wrap_first_method_in_call_chain = false
+ij_java_wrap_long_lines = false
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index b0c8e512b..88ddaa2bd 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -9,7 +9,9 @@
-
+
+
+
@@ -17,7 +19,9 @@
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 4a43f0d20..18f04cc77 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -3,8 +3,12 @@
+
+
+
+
diff --git a/.vscode/launch.json b/.vscode/launch.json
index ae2a4261b..665fa9c47 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -10,7 +10,12 @@
"request": "launch",
"mainClass": "org.opencds.cqf.ruler.Application",
"projectName": "cqf-ruler-server",
- "vmArgs": ["-XX:TieredStopAtLevel=1", "-Xverify:none", "-Dspring.main.lazy-initialization=true"],
+ "vmArgs": [
+ "-XX:TieredStopAtLevel=1",
+ "-Xverify:none",
+ "-Dspring.main.lazy-initialization=true",
+ "-Dloader.debug=true"
+ ],
"stepFilters": {
"classNameFilters": [
"java.*",
@@ -24,6 +29,7 @@
"classPaths": [
"$Auto",
"${workspaceFolder}/plugin/hello-world/target/classes",
+ "${workspaceFolder}/plugin/ra/target/classes",
"${workspaceFolder}/plugin/sdc/target/classes",
"${workspaceFolder}/plugin/utility/target/classes"
]
@@ -81,4 +87,4 @@
}
}
]
-}
\ No newline at end of file
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6b7faefb3..ceb50694e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -16,5 +16,6 @@
"jpaserver",
"springframework",
"Versionless"
- ]
-}
\ No newline at end of file
+ ],
+ "java.saveActions.organizeImports": true
+}
diff --git a/README.md b/README.md
index d98e2bf59..ec930aef3 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@ Visit the [wiki](https://github.com/DBCG/cqf-ruler/wiki) for more documentation.
To run the cqf-ruler directory from this project use:
-`java -jar server/target/cqf-ruler-server-*.jar`
+`java -jar server/target/cqf-ruler-server-*.war`
### Plugins
diff --git a/external/hapi-fhir-jpaserver-starter b/external/hapi-fhir-jpaserver-starter
index ea3f10ec8..79fddf830 160000
--- a/external/hapi-fhir-jpaserver-starter
+++ b/external/hapi-fhir-jpaserver-starter
@@ -1 +1 @@
-Subproject commit ea3f10ec86774abfaedf220f46a7b515f9751d26
+Subproject commit 79fddf8309db91795fafaf3c877d96833f3b5dff
diff --git a/external/pom.xml b/external/pom.xml
index 2d9f73223..f466e1afc 100644
--- a/external/pom.xml
+++ b/external/pom.xml
@@ -94,7 +94,7 @@
maven-antrun-plugin
-
+
generate-sources
@@ -160,7 +160,7 @@
1.4.1
-
+
generate-sources
replace
diff --git a/plugin/hello-world/src/test/java/org/opencds/cqf/ruler/plugin/hello/HelloWorldProviderIT.java b/plugin/hello-world/src/test/java/org/opencds/cqf/ruler/plugin/hello/HelloWorldProviderIT.java
index eb470d975..8c7375ccb 100644
--- a/plugin/hello-world/src/test/java/org/opencds/cqf/ruler/plugin/hello/HelloWorldProviderIT.java
+++ b/plugin/hello-world/src/test/java/org/opencds/cqf/ruler/plugin/hello/HelloWorldProviderIT.java
@@ -16,7 +16,6 @@
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
-
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { Application.class,
HelloWorldConfig.class }, properties = {
diff --git a/plugin/ra/pom.xml b/plugin/ra/pom.xml
new file mode 100644
index 000000000..6c8494ffb
--- /dev/null
+++ b/plugin/ra/pom.xml
@@ -0,0 +1,60 @@
+
+ 4.0.0
+
+ org.opencds.cqf.ruler
+ cqf-ruler
+ 0.5.0-SNAPSHOT
+ ../..
+
+
+ cqf-ruler-plugin-ra
+
+
+ org.opencds.cqf.ruler
+ cqf-ruler-external
+ 0.5.0-SNAPSHOT
+ provided
+
+
+ org.opencds.cqf.ruler
+ cqf-ruler-server
+ 0.5.0-SNAPSHOT
+ classes
+ provided
+
+
+ org.opencds.cqf.ruler
+ cqf-ruler-plugin-utility
+ 0.5.0-SNAPSHOT
+ provided
+
+
+ org.opencds.cqf.ruler
+ cqf-ruler-plugin-test-utility
+ 0.5.0-SNAPSHOT
+ provided
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ provided
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
diff --git a/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/RAConfig.java b/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/RAConfig.java
new file mode 100644
index 000000000..f4e8ff0c9
--- /dev/null
+++ b/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/RAConfig.java
@@ -0,0 +1,25 @@
+package org.opencds.cqf.ruler.plugin.ra;
+
+import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition;
+
+import org.opencds.cqf.ruler.api.OperationProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConditionalOnProperty(prefix = "hapi.fhir.ra", name = "enabled", havingValue = "true")
+public class RAConfig {
+
+ @Bean
+ public RAProperties RAProperties() {
+ return new RAProperties();
+ }
+
+ @Bean
+ @Conditional(OnR4Condition.class)
+ public OperationProvider r4ReportProvider() {
+ return new org.opencds.cqf.ruler.plugin.ra.r4.ReportProvider();
+ }
+}
diff --git a/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/RAProperties.java b/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/RAProperties.java
new file mode 100644
index 000000000..f9aa9cce8
--- /dev/null
+++ b/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/RAProperties.java
@@ -0,0 +1,44 @@
+package org.opencds.cqf.ruler.plugin.ra;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@ConfigurationProperties(prefix = "hapi.fhir.ra")
+@Configuration
+@EnableConfigurationProperties
+public class RAProperties {
+
+ private Boolean enabled = true;
+
+ public Boolean getEnabled() {
+ return this.enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ private Report report = new Report();
+
+ public Report getReport() {
+ return report;
+ }
+
+ public void setReport(Report report) {
+ this.report = report;
+ }
+
+ public static class Report {
+
+ private String endpoint;
+
+ public String getEndpoint() {
+ return endpoint;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+ }
+}
diff --git a/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/r4/ReportProvider.java b/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/r4/ReportProvider.java
new file mode 100644
index 000000000..91dfc2172
--- /dev/null
+++ b/plugin/ra/src/main/java/org/opencds/cqf/ruler/plugin/ra/r4/ReportProvider.java
@@ -0,0 +1,234 @@
+package org.opencds.cqf.ruler.plugin.ra.r4;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.hl7.fhir.exceptions.FHIRException;
+import org.hl7.fhir.instance.model.api.IAnyResource;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.model.Bundle;
+import org.hl7.fhir.r4.model.Group;
+import org.hl7.fhir.r4.model.Identifier;
+import org.hl7.fhir.r4.model.MeasureReport;
+import org.hl7.fhir.r4.model.Meta;
+import org.hl7.fhir.r4.model.Parameters;
+import org.hl7.fhir.r4.model.Patient;
+import org.hl7.fhir.r4.model.Period;
+import org.hl7.fhir.r4.model.Reference;
+import org.hl7.fhir.r4.model.Resource;
+import org.opencds.cqf.ruler.api.OperationProvider;
+import org.opencds.cqf.ruler.plugin.utility.OperatorUtilities;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+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.jpa.starter.AppProperties;
+import ca.uhn.fhir.model.api.annotation.Description;
+import ca.uhn.fhir.rest.annotation.Operation;
+import ca.uhn.fhir.rest.annotation.OperationParam;
+import ca.uhn.fhir.rest.param.ReferenceParam;
+public class ReportProvider implements OperationProvider, OperatorUtilities {
+
+ @Autowired
+ private DaoRegistry myDaoRegistry;
+
+ @Autowired
+ private AppProperties myAppProperties;
+
+ private static final Logger ourLog = LoggerFactory.getLogger(ReportProvider.class);
+
+ /**
+ * Implements the $report
+ * operation found in the
+ * Da Vinci Risk
+ * Adjustment IG.
+ *
+ * @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 $report operation found in the Da Vinci Risk Adjustment IG.")
+
+ @Operation(name = "$report", idempotent = true, type = MeasureReport.class)
+ public Parameters report(
+ @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 {
+
+ Period period = validateParamaters(periodStart, periodEnd, subject);
+ Parameters result = initializeParametersResult(subject);
+ List patients = getPatientListFromSubject(subject);
+
+ (patients)
+ .forEach(
+ patient -> {
+ Parameters.ParametersParameterComponent patientParameter = patientReport(patient, period,
+ myAppProperties.getServer_address());
+ result.addParameter(patientParameter);
+ });
+
+ return result;
+ }
+
+ private Period validateParamaters(String periodStart, String periodEnd, String subject) {
+ if (periodStart == null) {
+ throw new IllegalArgumentException("Parameter 'periodStart' is required.");
+ }
+ if (periodEnd == null) {
+ throw new IllegalArgumentException("Parameter 'periodEnd' is required.");
+ }
+ Date periodStartDate = resolveRequestDate(periodStart, true);
+ Date periodEndDate = resolveRequestDate(periodEnd, false);
+ if (periodStartDate.after(periodEndDate)) {
+ throw new IllegalArgumentException("Parameter 'periodStart' must be before 'periodEnd'.");
+ }
+
+ if (subject == null) {
+ throw new IllegalArgumentException("Parameter 'subject' is required.");
+ }
+ if (!subject.startsWith("Patient/") && !subject.startsWith("Group/")) {
+ throw new IllegalArgumentException(
+ "Parameter 'subject' must be in the format 'Patient/[id]' or 'Group/[id]'.");
+ }
+
+ return new Period().setStart(periodStartDate).setEnd(periodEndDate);
+ }
+
+ private Parameters initializeParametersResult(String subject) {
+ Parameters result = new Parameters();
+ result.setId(subject.replace("/", "-") + "-report");
+
+ return result;
+ }
+
+ private static String PATIENT_REPORT_PROFILE_URL = "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-measurereport-bundle";
+
+ private Parameters.ParametersParameterComponent patientReport(Patient thePatient, Period thePeriod,
+ String serverBase) {
+
+ String patientId = thePatient.getIdElement().getIdPart();
+ final Map bundleEntries = new HashMap<>();
+ bundleEntries.put(thePatient.getIdElement(), thePatient);
+
+ SearchParameterMap theParams = SearchParameterMap.newSynchronous();
+ ReferenceParam subjectParam = new ReferenceParam(patientId);
+ theParams.add("subject", subjectParam);
+ IFhirResourceDao measureReportDao = myDaoRegistry.getResourceDao(MeasureReport.class);
+ measureReportDao.search(theParams).getAllResources().forEach(baseResource -> {
+ MeasureReport measureReport = (MeasureReport) baseResource;
+
+ if (measureReport.getPeriod().getEnd().before(thePeriod.getStart())
+ || measureReport.getPeriod().getStart().after(thePeriod.getEnd())) {
+ return;
+ }
+
+ bundleEntries.putIfAbsent(measureReport.getIdElement(), measureReport);
+
+ getEvaluatedResources(measureReport).forEach(resource -> {
+ bundleEntries.putIfAbsent(resource.getIdElement(), resource);
+ });
+ });
+
+ Bundle patientReportBundle = new Bundle();
+ patientReportBundle.setMeta(new Meta().addProfile(PATIENT_REPORT_PROFILE_URL));
+ patientReportBundle.setType(Bundle.BundleType.COLLECTION);
+ patientReportBundle.setTimestamp(new Date());
+ patientReportBundle.setId(patientId + "-report");
+ patientReportBundle.setIdentifier(
+ new Identifier().setSystem("urn:ietf:rfc:3986").setValue("urn:uuid:" + UUID.randomUUID().toString()));
+
+ bundleEntries.entrySet().forEach(resource -> {
+ patientReportBundle.addEntry(
+ new Bundle.BundleEntryComponent()
+ .setResource((Resource) resource.getValue())
+ .setFullUrl(getFullUrl(serverBase, resource.getValue().fhirType(),
+ resource.getValue().getIdElement().getIdPart())));
+ });
+
+ Parameters.ParametersParameterComponent patientParameter = new Parameters.ParametersParameterComponent();
+ patientParameter.setResource(patientReportBundle);
+ patientParameter.setId(thePatient.getIdElement().getIdPart() + "-report");
+ patientParameter.setName("return");
+
+ return patientParameter;
+ }
+
+ // TODO: this might be useful to make a utility
+ private List getEvaluatedResources(MeasureReport report) {
+ List resources = new ArrayList<>();
+ for (Reference evaluatedResource : report.getEvaluatedResource()) {
+ IIdType theEvaluatedId = evaluatedResource.getReferenceElement();
+ IBaseResource resourceBase = this.resolveById(myDaoRegistry, theEvaluatedId);
+ if (resourceBase != null && resourceBase instanceof Resource) {
+ Resource resource = (Resource) resourceBase;
+ resources.add(resource);
+ }
+ }
+ return resources;
+
+ }
+
+ // TODO: replace this with version from the evaluator?
+ private Patient ensurePatient(String patientRef) {
+ IBaseResource patient = resolveById(myDaoRegistry, Patient.class, patientRef);
+ if (patient == null) {
+ throw new RuntimeException("Could not find Patient: " + patientRef);
+ }
+ return (Patient) patient;
+ }
+
+ // TODO: replace this with version from the evaluator?
+ private List getPatientListFromSubject(String subject) {
+ List patientList = null;
+
+ if (subject.startsWith("Patient/")) {
+ Patient patient = ensurePatient(subject);
+ patientList = new ArrayList();
+ patientList.add(patient);
+ } else if (subject.startsWith("Group/")) {
+ patientList = getPatientListFromGroup(subject);
+ } else {
+ ourLog.info(String.format("Subject member was not a Patient or a Group, so skipping. \n%s", subject));
+ }
+
+ return patientList;
+ }
+
+ // TODO: replace this with version from the evaluator?
+ private List getPatientListFromGroup(String subjectGroupId) {
+ List patientList = new ArrayList<>();
+
+ IBaseResource baseGroup = resolveById(myDaoRegistry, Group.class, subjectGroupId);
+ if (baseGroup == null) {
+ throw new RuntimeException("Could not find Group: " + subjectGroupId);
+ }
+
+ Group group = (Group) baseGroup;
+ group.getMember().forEach(member -> {
+ Reference reference = member.getEntity();
+ if (reference.getReferenceElement().getResourceType().equals("Patient")) {
+ Patient patient = ensurePatient(reference.getReference());
+ patientList.add(patient);
+ } else if (reference.getReferenceElement().getResourceType().equals("Group")) {
+ patientList.addAll(getPatientListFromGroup(reference.getReference()));
+ } else {
+ ourLog.info(
+ String.format("Group member was not a Patient or a Group, so skipping. \n%s",
+ reference.getReference()));
+ }
+ });
+
+ return patientList;
+ }
+}
diff --git a/plugin/ra/src/main/resources/META-INF/spring.factories b/plugin/ra/src/main/resources/META-INF/spring.factories
new file mode 100644
index 000000000..c7f2c02f9
--- /dev/null
+++ b/plugin/ra/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.opencds.cqf.ruler.plugin.ra.RAConfig
\ No newline at end of file
diff --git a/plugin/ra/src/main/resources/application.yaml b/plugin/ra/src/main/resources/application.yaml
new file mode 100644
index 000000000..b064ee800
--- /dev/null
+++ b/plugin/ra/src/main/resources/application.yaml
@@ -0,0 +1,6 @@
+hapi:
+ fhir:
+ ra:
+ enabled: true
+ report:
+ endpoint: ''
\ No newline at end of file
diff --git a/plugin/ra/src/test/java/org/opencds/cqf/ruler/plugin/ra/r4/ReportProviderIT.java b/plugin/ra/src/test/java/org/opencds/cqf/ruler/plugin/ra/r4/ReportProviderIT.java
new file mode 100644
index 000000000..5e9c8e5d6
--- /dev/null
+++ b/plugin/ra/src/test/java/org/opencds/cqf/ruler/plugin/ra/r4/ReportProviderIT.java
@@ -0,0 +1,340 @@
+package org.opencds.cqf.ruler.plugin.ra.r4;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.io.IOException;
+
+import org.hl7.fhir.r4.model.Bundle;
+import org.hl7.fhir.r4.model.Group;
+import org.hl7.fhir.r4.model.MeasureReport;
+import org.hl7.fhir.r4.model.Parameters;
+import org.hl7.fhir.r4.model.StringType;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.opencds.cqf.ruler.Application;
+import org.opencds.cqf.ruler.plugin.ra.RAConfig;
+import org.opencds.cqf.ruler.plugin.ra.RAProperties;
+import org.opencds.cqf.ruler.plugin.testutility.ResolutionUtilities;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.context.FhirVersionEnum;
+import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
+import ca.uhn.fhir.rest.client.api.IGenericClient;
+import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
+import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
+
+@ExtendWith(SpringExtension.class)
+@ActiveProfiles("test")
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { Application.class,
+ RAConfig.class }, properties = { "hapi.fhir.fhir_version=r4", "hapi.fhir.ra.enabled=true" })
+public class ReportProviderIT implements org.opencds.cqf.ruler.plugin.testutility.ClientUtilities, ResolutionUtilities,
+ org.opencds.cqf.ruler.plugin.utility.ClientUtilities {
+
+ private IGenericClient ourClient;
+ private FhirContext ourCtx;
+
+ @Autowired
+ private DaoRegistry ourRegistry;
+
+ @Autowired
+ private RAProperties myRaProperties;
+
+ @LocalServerPort
+ private int port;
+
+ @BeforeEach
+ void beforeEach() {
+
+ ourCtx = FhirContext.forCached(FhirVersionEnum.R4);
+ ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
+ ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
+ String ourServerBase = getClientUrl(myRaProperties.getReport().getEndpoint(), port);
+ ourClient = createClient(ourCtx, ourServerBase);
+ myRaProperties.getReport().setEndpoint(ourServerBase);
+ }
+
+ @Test
+ public void testMissingPeriodStartParam() throws IOException {
+
+ Parameters params = new Parameters();
+ params.addParameter().setName("periodEnd").setValue(new StringType("2021-12-31"));
+ params.addParameter().setName("subject").setValue(new StringType("Patient/testReport01"));
+
+ assertThrows(InternalErrorException.class, () -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ @Test
+ public void testMissingPeriodEndParam() throws IOException {
+
+ Parameters params = new Parameters();
+ params.addParameter().setName("periodStart").setValue(new StringType("2021-01-01"));
+ params.addParameter().setName("subject").setValue(new StringType("Patient/testReport01"));
+
+ assertThrows(InternalErrorException.class, () -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ @Test
+ public void testMissingSubjectParam() 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"));
+
+ assertThrows(InternalErrorException.class, () -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ @Test
+ public void testStartPeriodBeforeEndPeriod() throws IOException {
+
+ Parameters params = new Parameters();
+ params.addParameter().setName("periodStart").setValue(new StringType("2021-01-01"));
+ params.addParameter().setName("periodEnd").setValue(new StringType("2020-12-31"));
+
+ assertThrows(InternalErrorException.class, () -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ // TODO: add the count of patients returned
+ @Test
+ public void testSubjectPatient() 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("Patient/ra-patient01"));
+ resolveByLocation(ourRegistry, "Patient-ra-patient01.json", ourCtx);
+
+ assertDoesNotThrow(() -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ // TODO: add the count of patients returned
+ @Test
+ public void testSubjectGroup() 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-group01"));
+ resolveByLocation(ourRegistry, "Patient-ra-patient01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Group-ra-group01.json", ourCtx);
+
+ assertDoesNotThrow(() -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ @Test
+ public void testSubjectIsNotPatientOrGroup() 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("ra-patient01"));
+
+ assertThrows(InternalErrorException.class, () -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ @Test
+ public void testPatientSubjectNotFound() 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("Patient/bad-patient"));
+
+ assertThrows(ResourceNotFoundException.class, () -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ @Test
+ public void testGroupSubjectNotFound() 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/bad-group"));
+
+ assertThrows(ResourceNotFoundException.class, () -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ // This test requires the following application setting:
+ // enforce_referential_integrity_on_write: false
+ @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"));
+ resolveByLocation(ourRegistry, "Group-ra-group00.json", ourCtx);
+ Group group = ourClient.read().resource(Group.class).withId("ra-group00").execute();
+ assertNotNull(group);
+
+ assertThrows(ResourceNotFoundException.class, () -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ // TODO: add the count of patients returned
+ @Test
+ public void testSubjectMultiplePatientGroup() 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-group02"));
+ resolveByLocation(ourRegistry, "Patient-ra-patient02.json", ourCtx);
+ resolveByLocation(ourRegistry, "Patient-ra-patient03.json", ourCtx);
+ resolveByLocation(ourRegistry, "Group-ra-group02.json", ourCtx);
+
+ assertDoesNotThrow(() -> {
+ ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+ });
+ }
+
+ @Test
+ public void testSingleSubjectSingleReport() 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("Patient/ra-patient01"));
+ resolveByLocation(ourRegistry, "Patient-ra-patient01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition02pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition03pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition08pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition09pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition10pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition11pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition17pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition18pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition33pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition43pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition44pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Observation-ra-obs21pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter02pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter03pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter08pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter09pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter11pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter43pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter44pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "MeasureReport-ra-measurereport01.json", ourCtx);
+
+ Parameters actual = ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+
+ assertNotNull(actual);
+ assertEquals(1, actual.getParameter().size());
+
+ Bundle bundle = (Bundle) actual.getParameter().get(0).getResource();
+ assertNotNull(bundle);
+ // all the resources inserted above are in the bundle entry
+ assertEquals(21, bundle.getEntry().size());
+ }
+
+ @Test
+ public void testReportDoesNotIncludeNonEvaluatedResources() 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("Patient/ra-patient01"));
+ resolveByLocation(ourRegistry, "Patient-ra-patient01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition02pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition03pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition08pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition09pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition10pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition11pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition17pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition18pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition33pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition43pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Condition-ra-condition44pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Observation-ra-obs21pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter02pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter03pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter08pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter09pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter11pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter43pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter44pat01.json", ourCtx);
+ resolveByLocation(ourRegistry, "MeasureReport-ra-measurereport01.json", ourCtx);
+ // this is not an evaluatedResource of the report
+ resolveByLocation(ourRegistry, "Encounter-ra-encounter45pat01.json", ourCtx);
+
+ Parameters actual = ourClient.operation().onType(MeasureReport.class).named("$report")
+ .withParameters(params)
+ .returnResourceType(Parameters.class)
+ .execute();
+
+ Bundle bundle = (Bundle) actual.getParameter().get(0).getResource();
+ // all the resources inserted above are in the bundle entry except the one that
+ // was not evaluated
+ assertEquals(21, bundle.getEntry().size());
+ }
+
+ // TODO: create test for single patient, multiple reports
+ // TODO: create test for multiple patients, multiple reports
+ // TODO: create tests of overlap of MeasureReport date and period
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition02pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition02pat01.json
new file mode 100644
index 000000000..178f30357
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition02pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition02pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "E08.29",
+ "display": "Diabetes mellitus due to underlying condition with other diabetic kidney complication"
+ }
+ ],
+ "text": "E08.29: Diabetes mellitus due to underlying condition with other diabetic kidney complication"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2021-01-31"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition03pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition03pat01.json
new file mode 100644
index 000000000..d3f03d4eb
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition03pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition03pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "J45.31",
+ "display": "Mild persistent asthma with (acute) exacerbation"
+ }
+ ],
+ "text": "J45.31: Mild persistent asthma with (acute) exacerbation"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2021-09-26"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition08pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition08pat01.json
new file mode 100644
index 000000000..479a2f40a
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition08pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition08pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "F31.61",
+ "display": "Bipolar disorder, current episode mixed, mild"
+ }
+ ],
+ "text": "Bipolar disorder, current episode mixed, mild"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2017-02-03"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition09pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition09pat01.json
new file mode 100644
index 000000000..044a20d7e
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition09pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition09pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "B44.81",
+ "display": "Allergic bronchopulmonary aspergillosis"
+ }
+ ],
+ "text": "B44.81: Allergic bronchopulmonary aspergillosis"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2021-03-27"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition10pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition10pat01.json
new file mode 100644
index 000000000..2010d7910
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition10pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition10pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "J45.31",
+ "display": "Mild persistent asthma with (acute) exacerbation"
+ }
+ ],
+ "text": "J45.31: Mild persistent asthma with (acute) exacerbation"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2021-09-26"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition11pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition11pat01.json
new file mode 100644
index 000000000..aaed40233
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition11pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition11pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "J81.0",
+ "display": "Acute pulmonary edema"
+ }
+ ],
+ "text": "J81.0: Acute pulmonary edema"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2020-11-02"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition17pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition17pat01.json
new file mode 100644
index 000000000..8f233ad99
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition17pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition17pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "Z68.42",
+ "display": "Body mass index [BMI] 45.0-49.9, adult"
+ }
+ ],
+ "text": "Z68.42: Body mass index [BMI] 45.0-49.9, adult"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2021-01-31"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition18pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition18pat01.json
new file mode 100644
index 000000000..9647dbf20
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition18pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition18pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "I48.11",
+ "display": "Longstanding persistent atrial fibrillation"
+ }
+ ],
+ "text": "I48.11: Longstanding persistent atrial fibrillation"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2021-09-26"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition33pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition33pat01.json
new file mode 100644
index 000000000..1df5577c6
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition33pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition33pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "R09.2",
+ "display": "Respiratory arrest"
+ }
+ ],
+ "text": "R09.2: Respiratory arrest"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2021-09-26"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition43pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition43pat01.json
new file mode 100644
index 000000000..2a4ea9b9a
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition43pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition43pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "E08.29",
+ "display": "Diabetes mellitus due to underlying condition with other diabetic kidney complication"
+ }
+ ],
+ "text": "E08.29: Diabetes mellitus due to underlying condition with other diabetic kidney complication"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2019-02-10"
+}
diff --git a/plugin/ra/src/test/resources/Condition-ra-condition44pat01.json b/plugin/ra/src/test/resources/Condition-ra-condition44pat01.json
new file mode 100644
index 000000000..ec73b41c8
--- /dev/null
+++ b/plugin/ra/src/test/resources/Condition-ra-condition44pat01.json
@@ -0,0 +1,55 @@
+{
+ "resourceType": "Condition",
+ "id": "ra-condition44pat01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
+ ]
+ },
+ "clinicalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
+ "code": "active",
+ "display": "Active"
+ }
+ ],
+ "text": "Active"
+ },
+ "verificationStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+ "code": "confirmed",
+ "display": "Confirmed"
+ }
+ ],
+ "text": "Confirmed"
+ },
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/condition-category",
+ "code": "encounter-diagnosis",
+ "display": "Encounter Diagnosis"
+ }
+ ],
+ "text": "Encounter Diagnosis"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://hl7.org/fhir/sid/icd-10-cm",
+ "code": "B44.81",
+ "display": "Allergic bronchopulmonary aspergillosis"
+ }
+ ],
+ "text": "B44.81: Allergic bronchopulmonary aspergillosis"
+ },
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "onsetDateTime": "2017-01-18"
+}
diff --git a/plugin/ra/src/test/resources/Encounter-ra-encounter02pat01.json b/plugin/ra/src/test/resources/Encounter-ra-encounter02pat01.json
new file mode 100644
index 000000000..054a8d434
--- /dev/null
+++ b/plugin/ra/src/test/resources/Encounter-ra-encounter02pat01.json
@@ -0,0 +1,59 @@
+{
+ "resourceType": "Encounter",
+ "id": "ra-encounter02pat01",
+ "meta": {
+ "extension": [{
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString": "Encounter with Dr Howell on 20210714 for Patient 03"
+ },
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown": "This is Encounter with Dr Howell on 20210714 for Patient 03."
+ }
+ ],
+ "lastUpdated": "2021-07-14T11:56:57.250-04:00",
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter"
+ ]
+ },
+ "status": "finished",
+ "class": {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+ "code": "AMB",
+ "display": "ambulatory"
+ },
+ "type": [{
+ "coding": [{
+ "system": "http://www.ama-assn.org/go/cpt",
+ "code": "99215"
+ }],
+ "text": "Office Visit, High Complexity"
+ }],
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+
+ "participant": [{
+ "individual": {
+ "reference": "Practitioner/ra-prac01pat01"
+ }
+ }],
+ "diagnosis": [{
+ "condition": {
+ "reference": "Condition/ra-condition02pat01"
+ }
+ },
+ {
+ "condition": {
+ "reference": "Condition/ra-condition17pat01"
+ }
+ }
+ ],
+ "period": {
+ "start": "2021-01-31",
+ "end": "2021-01-31"
+ },
+ "serviceProvider": {
+ "reference": "Organization/ra-org01pat01"
+ }
+}
diff --git a/plugin/ra/src/test/resources/Encounter-ra-encounter03pat01.json b/plugin/ra/src/test/resources/Encounter-ra-encounter03pat01.json
new file mode 100644
index 000000000..62bb5bbb8
--- /dev/null
+++ b/plugin/ra/src/test/resources/Encounter-ra-encounter03pat01.json
@@ -0,0 +1,68 @@
+{
+ "resourceType": "Encounter",
+ "id": "ra-encounter03pat01",
+ "meta": {
+ "extension": [{
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString": "Encounter with Dr Howell on 20210714 for Patient 03"
+ },
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown": "This is Encounter with Dr Howell on 20210714 for Patient 03."
+ }
+ ],
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter"
+ ]
+ },
+ "status": "finished",
+ "class": {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+ "code": "AMB",
+ "display": "ambulatory"
+ },
+ "type": [{
+ "coding": [{
+ "system": "http://www.ama-assn.org/go/cpt",
+ "code": "99215"
+ }],
+ "text": "Office Visit, High Complexity"
+ }],
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+
+ "participant": [{
+ "individual": {
+ "reference": "Practitioner/ra-prac01pat01"
+ }
+ }],
+ "diagnosis": [{
+ "condition": {
+ "reference": "Condition/ra-condition03pat01"
+ }
+ },
+ {
+ "condition": {
+ "reference": "Condition/ra-condition10pat01"
+ }
+ },
+ {
+ "condition": {
+ "reference": "Condition/ra-condition18pat01"
+ }
+ },
+ {
+ "condition": {
+ "reference": "Condition/ra-condition33pat01"
+ }
+ }
+ ],
+ "period": {
+ "start": "2021-09-26",
+ "end": "2021-09-26"
+ },
+ "serviceProvider": {
+ "reference": "Organization/ra-org01pat01"
+ }
+}
diff --git a/plugin/ra/src/test/resources/Encounter-ra-encounter08pat01.json b/plugin/ra/src/test/resources/Encounter-ra-encounter08pat01.json
new file mode 100644
index 000000000..a79439d39
--- /dev/null
+++ b/plugin/ra/src/test/resources/Encounter-ra-encounter08pat01.json
@@ -0,0 +1,53 @@
+{
+ "resourceType": "Encounter",
+ "id": "ra-encounter08pat01",
+ "meta": {
+ "extension": [{
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString": "Encounter with Dr Howell on 20210714 for Patient 03"
+ },
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown": "This is Encounter with Dr Howell on 20210714 for Patient 03."
+ }
+ ],
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter"
+ ]
+ },
+ "status": "finished",
+ "class": {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+ "code": "AMB",
+ "display": "ambulatory"
+ },
+ "type": [{
+ "coding": [{
+ "system": "http://www.ama-assn.org/go/cpt",
+ "code": "99215"
+ }],
+ "text": "Office Visit, High Complexity"
+ }],
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+
+ "participant": [{
+ "individual": {
+ "reference": "Practitioner/ra-prac01pat01"
+ }
+ }],
+ "diagnosis": [{
+ "condition": {
+ "reference": "Condition/ra-condition08pat01"
+ }
+ }
+ ],
+ "period": {
+ "start": "2017-02-03",
+ "end": "2017-02-03"
+ },
+ "serviceProvider": {
+ "reference": "Organization/ra-org01pat01"
+ }
+}
diff --git a/plugin/ra/src/test/resources/Encounter-ra-encounter09pat01.json b/plugin/ra/src/test/resources/Encounter-ra-encounter09pat01.json
new file mode 100644
index 000000000..3476375fe
--- /dev/null
+++ b/plugin/ra/src/test/resources/Encounter-ra-encounter09pat01.json
@@ -0,0 +1,53 @@
+{
+ "resourceType": "Encounter",
+ "id": "ra-encounter09pat01",
+ "meta": {
+ "extension": [{
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString": "Encounter with Dr Howell on 20210714 for Patient 03"
+ },
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown": "This is Encounter with Dr Howell on 20210714 for Patient 03."
+ }
+ ],
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter"
+ ]
+ },
+ "status": "finished",
+ "class": {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+ "code": "AMB",
+ "display": "ambulatory"
+ },
+ "type": [{
+ "coding": [{
+ "system": "http://www.ama-assn.org/go/cpt",
+ "code": "99215"
+ }],
+ "text": "Office Visit, High Complexity"
+ }],
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+
+ "participant": [{
+ "individual": {
+ "reference": "Practitioner/ra-prac01pat01"
+ }
+ }],
+ "diagnosis": [{
+ "condition": {
+ "reference": "Condition/ra-condition09pat01"
+ }
+ }
+ ],
+ "period": {
+ "start": "2021-03-27",
+ "end": "2021-03-27"
+ },
+ "serviceProvider": {
+ "reference": "Organization/ra-org01pat01"
+ }
+}
diff --git a/plugin/ra/src/test/resources/Encounter-ra-encounter11pat01.json b/plugin/ra/src/test/resources/Encounter-ra-encounter11pat01.json
new file mode 100644
index 000000000..d0d017829
--- /dev/null
+++ b/plugin/ra/src/test/resources/Encounter-ra-encounter11pat01.json
@@ -0,0 +1,53 @@
+{
+ "resourceType": "Encounter",
+ "id": "ra-encounter11pat01",
+ "meta": {
+ "extension": [{
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString": "Encounter with Dr Howell on 20210714 for Patient 03"
+ },
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown": "This is Encounter with Dr Howell on 20210714 for Patient 03."
+ }
+ ],
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter"
+ ]
+ },
+ "status": "finished",
+ "class": {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+ "code": "AMB",
+ "display": "ambulatory"
+ },
+ "type": [{
+ "coding": [{
+ "system": "http://www.ama-assn.org/go/cpt",
+ "code": "99215"
+ }],
+ "text": "Office Visit, High Complexity"
+ }],
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+
+ "participant": [{
+ "individual": {
+ "reference": "Practitioner/ra-prac01pat01"
+ }
+ }],
+ "diagnosis": [{
+ "condition": {
+ "reference": "Condition/ra-condition11pat01"
+ }
+ }
+ ],
+ "period": {
+ "start": "2020-11-02",
+ "end": "2020-11-02"
+ },
+ "serviceProvider": {
+ "reference": "Organization/ra-org01pat01"
+ }
+}
diff --git a/plugin/ra/src/test/resources/Encounter-ra-encounter43pat01.json b/plugin/ra/src/test/resources/Encounter-ra-encounter43pat01.json
new file mode 100644
index 000000000..3e3d8d789
--- /dev/null
+++ b/plugin/ra/src/test/resources/Encounter-ra-encounter43pat01.json
@@ -0,0 +1,53 @@
+{
+ "resourceType": "Encounter",
+ "id": "ra-encounter43pat01",
+ "meta": {
+ "extension": [{
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString": "Encounter with Dr Howell on 20210714 for Patient 03"
+ },
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown": "This is Encounter with Dr Howell on 20210714 for Patient 03."
+ }
+ ],
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter"
+ ]
+ },
+ "status": "finished",
+ "class": {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+ "code": "AMB",
+ "display": "ambulatory"
+ },
+ "type": [{
+ "coding": [{
+ "system": "http://www.ama-assn.org/go/cpt",
+ "code": "99215"
+ }],
+ "text": "Office Visit, High Complexity"
+ }],
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+
+ "participant": [{
+ "individual": {
+ "reference": "Practitioner/ra-prac01pat01"
+ }
+ }],
+ "diagnosis": [{
+ "condition": {
+ "reference": "Condition/ra-condition43pat01"
+ }
+ }
+ ],
+ "period": {
+ "start": "2019-02-10",
+ "end": "2019-02-10"
+ },
+ "serviceProvider": {
+ "reference": "Organization/ra-org01pat01"
+ }
+}
diff --git a/plugin/ra/src/test/resources/Encounter-ra-encounter44pat01.json b/plugin/ra/src/test/resources/Encounter-ra-encounter44pat01.json
new file mode 100644
index 000000000..71611842d
--- /dev/null
+++ b/plugin/ra/src/test/resources/Encounter-ra-encounter44pat01.json
@@ -0,0 +1,53 @@
+{
+ "resourceType": "Encounter",
+ "id": "ra-encounter44pat01",
+ "meta": {
+ "extension": [{
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString": "Encounter with Dr Howell on 20210714 for Patient 03"
+ },
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown": "This is Encounter with Dr Howell on 20210714 for Patient 03."
+ }
+ ],
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter"
+ ]
+ },
+ "status": "finished",
+ "class": {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+ "code": "AMB",
+ "display": "ambulatory"
+ },
+ "type": [{
+ "coding": [{
+ "system": "http://www.ama-assn.org/go/cpt",
+ "code": "99215"
+ }],
+ "text": "Office Visit, High Complexity"
+ }],
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+
+ "participant": [{
+ "individual": {
+ "reference": "Practitioner/ra-prac01pat01"
+ }
+ }],
+ "diagnosis": [{
+ "condition": {
+ "reference": "Condition/ra-condition44pat01"
+ }
+ }
+ ],
+ "period": {
+ "start": "2017-01-18",
+ "end": "2017-01-18"
+ },
+ "serviceProvider": {
+ "reference": "Organization/ra-org01pat01"
+ }
+}
diff --git a/plugin/ra/src/test/resources/Encounter-ra-encounter45pat01.json b/plugin/ra/src/test/resources/Encounter-ra-encounter45pat01.json
new file mode 100644
index 000000000..bb726de44
--- /dev/null
+++ b/plugin/ra/src/test/resources/Encounter-ra-encounter45pat01.json
@@ -0,0 +1,53 @@
+{
+ "resourceType": "Encounter",
+ "id": "ra-encounter45pat01",
+ "meta": {
+ "extension": [{
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString": "Encounter with Dr Howell on 20210714 for Patient 03"
+ },
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown": "This is Encounter with Dr Howell on 20210714 for Patient 03."
+ }
+ ],
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter"
+ ]
+ },
+ "status": "finished",
+ "class": {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+ "code": "AMB",
+ "display": "ambulatory"
+ },
+ "type": [{
+ "coding": [{
+ "system": "http://www.ama-assn.org/go/cpt",
+ "code": "99215"
+ }],
+ "text": "Office Visit, High Complexity"
+ }],
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+
+ "participant": [{
+ "individual": {
+ "reference": "Practitioner/ra-prac01pat01"
+ }
+ }],
+ "diagnosis": [{
+ "condition": {
+ "reference": "Condition/ra-condition44pat01"
+ }
+ }
+ ],
+ "period": {
+ "start": "2018-07-21",
+ "end": "2018-07-21"
+ },
+ "serviceProvider": {
+ "reference": "Organization/ra-org01pat01"
+ }
+}
diff --git a/plugin/ra/src/test/resources/Group-ra-group00.json b/plugin/ra/src/test/resources/Group-ra-group00.json
new file mode 100644
index 000000000..10c1e7e0b
--- /dev/null
+++ b/plugin/ra/src/test/resources/Group-ra-group00.json
@@ -0,0 +1,18 @@
+{
+ "resourceType": "Group",
+ "id": "ra-group00",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-patient-group"
+ ]
+ },
+ "type": "person",
+ "actual": true,
+ "member": [
+ {
+ "entity": {
+ "reference": "Patient/ra-patient00"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/plugin/ra/src/test/resources/Group-ra-group01.json b/plugin/ra/src/test/resources/Group-ra-group01.json
new file mode 100644
index 000000000..d0982f5ef
--- /dev/null
+++ b/plugin/ra/src/test/resources/Group-ra-group01.json
@@ -0,0 +1,18 @@
+{
+ "resourceType": "Group",
+ "id": "ra-group01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-patient-group"
+ ]
+ },
+ "type": "person",
+ "actual": true,
+ "member": [
+ {
+ "entity": {
+ "reference": "Patient/ra-patient01"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/plugin/ra/src/test/resources/Group-ra-group02.json b/plugin/ra/src/test/resources/Group-ra-group02.json
new file mode 100644
index 000000000..a386565f6
--- /dev/null
+++ b/plugin/ra/src/test/resources/Group-ra-group02.json
@@ -0,0 +1,23 @@
+{
+ "resourceType": "Group",
+ "id": "ra-group02",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-patient-group"
+ ]
+ },
+ "type": "person",
+ "actual": true,
+ "member": [
+ {
+ "entity": {
+ "reference": "Patient/ra-patient02"
+ }
+ },
+ {
+ "entity": {
+ "reference": "Patient/ra-patient03"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/plugin/ra/src/test/resources/MeasureReport-ra-measurereport01.json b/plugin/ra/src/test/resources/MeasureReport-ra-measurereport01.json
new file mode 100644
index 000000000..6360e034c
--- /dev/null
+++ b/plugin/ra/src/test/resources/MeasureReport-ra-measurereport01.json
@@ -0,0 +1,750 @@
+{
+ "resourceType": "MeasureReport",
+ "id": "ra-measurereport01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-measurereport"
+ ]
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-clinicalDataCollectionDeadline",
+ "valueDate": "2022-03-31"
+ }
+ ],
+ "status": "complete",
+ "type": "individual",
+ "measure": "https://build.fhir.org/ig/HL7/davinci-ra/Measure-RAModelExample01",
+ "subject": {
+ "reference": "Patient/ra-patient01"
+ },
+ "date": "2021-10-18",
+ "reporter": {
+ "reference": "Organization/ra-payer01"
+ },
+ "period": {
+ "start": "2021-01-01",
+ "end": "2021-09-30"
+ },
+ "group": [
+ {
+ "id": "group-001",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "18",
+ "display": "Diabetes with Chronic Complications"
+ }
+ ],
+ "text": "HCC 18: Diabetes with Chronic Complications"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "historic",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "closed-gap",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2021-04-01"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-not-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-002",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "111",
+ "display": "Chronic Obstructive Pulmonary Disease"
+ }
+ ],
+ "text": "HCC 111: Chronic Obstructive Pulmonary Disease"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "historic",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "pending",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2021-09-29"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-not-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-003",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "53",
+ "display": "Major Depressive, Bipolar, and Paranoid Disorders"
+ }
+ ],
+ "text": "HCC 59: Major Depressive, Bipolar, and Paranoid Disorders"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "historic",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "open-gap",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2020-07-15"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-not-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-004",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "112",
+ "display": "Fibrosis of lung and other chronic lung disorders"
+ }
+ ],
+ "text": "HCC 112: Fibrosis of lung and other chronic lung disorders"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "historic",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "closed-gap",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2021-04-27"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-005",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "19",
+ "display": "Diabetes without Complications"
+ }
+ ],
+ "text": "HCC 19: Diabetes without Complications"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "historic",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "pending",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2021-09-27"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-006",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "84",
+ "display": "Cardio-Respiratory Failure and Shock"
+ }
+ ],
+ "text": "HCC 84: Cardio-Respiratory Failure and Shock"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "historic",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "open-gap",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2020-12-15"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-007",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "22",
+ "display": "Morbid Obesity"
+ }
+ ],
+ "text": "HCC 22: Morbid Obesity"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "suspected",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "closed-gap",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2021-03-15"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-not-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-008",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "96",
+ "display": "Specified Heart Arrhythmias"
+ }
+ ],
+ "text": "HCC 96: Specified Heart Arrhythmias"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "suspected",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "pending",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2021-09-27"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-not-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-009",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "110",
+ "display": "Cystic Fibrosis"
+ }
+ ],
+ "text": "HCC 110: Cystic Fibrosis"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "suspected",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "open-gap",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2020-07-15"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-not-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "group-010",
+ "code": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/cmshcc",
+ "version": "24",
+ "code": "83",
+ "display": "Respiratory Arrest"
+ }
+ ],
+ "text": "HCC 110: Cystic Fibrosis"
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-suspectType",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "net-new",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/suspect-type"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "pending",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/evidence-status"
+ }
+ ]
+ }
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-evidenceStatusDate",
+ "valueDate": "2021-09-28"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-hierarchicalStatus",
+ "valueCodeableConcept": {
+ "coding": [
+ {
+ "code": "applied-not-superseded",
+ "system": "http://hl7.org/fhir/us/davinci-ra/CodeSystem/hierarchical-status"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ],
+ "evaluatedResource": [
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-001"
+ }
+ ],
+ "reference": "Condition/ra-condition02pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-002"
+ }
+ ],
+ "reference": "Condition/ra-condition03pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-003"
+ }
+ ],
+ "reference": "Condition/ra-condition08pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-004"
+ }
+ ],
+ "reference": "Condition/ra-condition09pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-005"
+ }
+ ],
+ "reference": "Condition/ra-condition10pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-006"
+ }
+ ],
+ "reference": "Condition/ra-condition11pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-007"
+ }
+ ],
+ "reference": "Condition/ra-condition17pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-008"
+ }
+ ],
+ "reference": "Condition/ra-condition18pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-010"
+ }
+ ],
+ "reference": "Condition/ra-condition33pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-001"
+ }
+ ],
+ "reference": "Condition/ra-condition43pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-004"
+ }
+ ],
+ "reference": "Condition/ra-condition44pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-001"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-007"
+ }
+ ],
+ "reference": "Encounter/ra-encounter02pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-002"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-005"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-008"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-010"
+ }
+ ],
+ "reference": "Encounter/ra-encounter03pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-003"
+ }
+ ],
+ "reference": "Encounter/ra-encounter08pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-004"
+ }
+ ],
+ "reference": "Encounter/ra-encounter09pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-006"
+ }
+ ],
+ "reference": "Encounter/ra-encounter11pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-001"
+ }
+ ],
+ "reference": "Encounter/ra-encounter43pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-004"
+ }
+ ],
+ "reference": "Encounter/ra-encounter44pat01"
+ },
+ {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/davinci-ra/StructureDefinition/ra-groupReference",
+ "valueString": "group-009"
+ }
+ ],
+ "reference": "Observation/ra-obs21pat01"
+ }
+ ]
+}
diff --git a/plugin/ra/src/test/resources/Observation-ra-obs21pat01.json b/plugin/ra/src/test/resources/Observation-ra-obs21pat01.json
new file mode 100644
index 000000000..fc7053f0d
--- /dev/null
+++ b/plugin/ra/src/test/resources/Observation-ra-obs21pat01.json
@@ -0,0 +1,79 @@
+{
+ "resourceType" : "Observation",
+ "id" : "ra-obs21pat01",
+ "meta" : {
+ "extension" : [
+ {
+ "url" : "http://hl7.org/fhir/StructureDefinition/instance-name",
+ "valueString" : "Trypsin [Mass/volume] in Serum or Plasma for Pat01"
+ },
+ {
+ "url" : "http://hl7.org/fhir/StructureDefinition/instance-description",
+ "valueMarkdown" : "Trypsin [Mass/volume] in Serum or Plasma for Pat01*."
+ }
+ ],
+ "profile" : [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab"
+ ]
+ },
+ "status" : "final",
+ "category" : [
+ {
+ "coding" : [
+ {
+ "system" : "http://terminology.hl7.org/CodeSystem/observation-category",
+ "code" : "laboratory",
+ "display" : "Laboratory"
+ }
+ ],
+ "text" : "Laboratory"
+ }
+ ],
+ "code" : {
+ "coding" : [
+ {
+ "system" : "http://loinc.org",
+ "code" : "33325-2",
+ "display" : "Trypsin [Mass/volume] in Serum or Plasma"
+ }
+ ],
+ "text" : "Trypsin [Mass/volume] in Serum or Plasma"
+ },
+ "subject" : {
+ "reference" : "Patient/ra-patient01",
+ "display" : "Eve Everywoman"
+ },
+ "effectiveDateTime" : "2019-06-17",
+ "valueQuantity" : {
+ "value" : 770,
+ "unit" : "ng/mL",
+ "system" : "http://unitsofmeasure.org"
+ },
+ "referenceRange" : [
+ {
+ "low" : {
+ "value" : 169,
+ "unit" : "ng/mL",
+ "system" : "http://unitsofmeasure.org",
+ "code" : "ng/mL"
+ },
+ "high" : {
+ "value" : 773,
+ "unit" : "ng/mL",
+ "system" : "http://unitsofmeasure.org",
+ "code" : "mg/dL"
+ },
+ "type" :
+ {
+ "coding" : [
+ {
+ "system" : "http://terminology.hl7.org/CodeSystem/referencerange-meaning",
+ "code" : "normal",
+ "display" : "Normal Range"
+ }
+ ],
+ "text" : "Normal Range"
+ }
+ }
+ ]
+}
diff --git a/plugin/ra/src/test/resources/Patient-ra-patient01.json b/plugin/ra/src/test/resources/Patient-ra-patient01.json
new file mode 100644
index 000000000..f1a1b86b8
--- /dev/null
+++ b/plugin/ra/src/test/resources/Patient-ra-patient01.json
@@ -0,0 +1,113 @@
+{
+ "resourceType": "Patient",
+ "id": "ra-patient01",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
+ ]
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex",
+ "valueCode": "F"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race",
+ "extension": [
+ {
+ "url": "ombCategory",
+ "valueCoding": {
+ "system": "urn:oid:2.16.840.1.113883.6.238",
+ "code": "2106-3",
+ "display": "White"
+ }
+ },
+ {
+ "url": "text",
+ "valueString": "White"
+ }
+ ]
+ },
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity",
+ "extension": [
+ {
+ "url": "ombCategory",
+ "valueCoding": {
+ "system": "urn:oid:2.16.840.1.113883.6.238",
+ "code": "2186-5",
+ "display": "Not Hispanic or Latino"
+ }
+ },
+ {
+ "url": "text",
+ "valueString": "Not Hispanic or Latino"
+ }
+ ]
+ }
+ ],
+ "identifier": [
+ {
+ "use": "usual",
+ "type": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
+ "code": "MR",
+ "display": "Medical record number"
+ }
+ ]
+ },
+ "system": "http://hospital.davinci.org",
+ "value": "12345"
+ }
+ ],
+ "active": true,
+ "name": [
+ {
+ "use": "official",
+ "family": "Everywoman",
+ "given": [
+ "Eve"
+ ]
+ }
+ ],
+ "gender": "female",
+ "birthDate": "1975-01-16",
+ "deceasedBoolean": false,
+ "address": [
+ {
+ "use": "home",
+ "line": [
+ "2222 Home Street"
+ ],
+ "city": "Ann Arbor",
+ "state": "MI",
+ "postalCode": "99999",
+ "country": "USA"
+ }
+ ],
+ "maritalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-MaritalStatus",
+ "code": "M",
+ "display": "Married"
+ }
+ ]
+ },
+ "communication": [
+ {
+ "language": {
+ "coding": [
+ {
+ "system": "urn:ietf:bcp:47",
+ "code": "en-US",
+ "display": "English (Region=United States)"
+ }
+ ]
+ },
+ "preferred": true
+ }
+ ]
+}
diff --git a/plugin/ra/src/test/resources/Patient-ra-patient02.json b/plugin/ra/src/test/resources/Patient-ra-patient02.json
new file mode 100644
index 000000000..5256799b2
--- /dev/null
+++ b/plugin/ra/src/test/resources/Patient-ra-patient02.json
@@ -0,0 +1,113 @@
+{
+ "resourceType": "Patient",
+ "id": "ra-patient02",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
+ ]
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex",
+ "valueCode": "M"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race",
+ "extension": [
+ {
+ "url": "ombCategory",
+ "valueCoding": {
+ "system": "urn:oid:2.16.840.1.113883.6.238",
+ "code": "2106-3",
+ "display": "White"
+ }
+ },
+ {
+ "url": "text",
+ "valueString": "White"
+ }
+ ]
+ },
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity",
+ "extension": [
+ {
+ "url": "ombCategory",
+ "valueCoding": {
+ "system": "urn:oid:2.16.840.1.113883.6.238",
+ "code": "2186-5",
+ "display": "Not Hispanic or Latino"
+ }
+ },
+ {
+ "url": "text",
+ "valueString": "Not Hispanic or Latino"
+ }
+ ]
+ }
+ ],
+ "identifier": [
+ {
+ "use": "usual",
+ "type": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
+ "code": "MR",
+ "display": "Medical record number"
+ }
+ ]
+ },
+ "system": "http://hospital.davinci.org",
+ "value": "23456"
+ }
+ ],
+ "active": true,
+ "name": [
+ {
+ "use": "official",
+ "family": "Everyman",
+ "given": [
+ "Adam"
+ ]
+ }
+ ],
+ "gender": "female",
+ "birthDate": "1950-12-16",
+ "deceasedBoolean": false,
+ "address": [
+ {
+ "use": "home",
+ "line": [
+ "2222 Home Street"
+ ],
+ "city": "Ann Arbor",
+ "state": "MI",
+ "postalCode": "99999",
+ "country": "USA"
+ }
+ ],
+ "maritalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-MaritalStatus",
+ "code": "M",
+ "display": "Married"
+ }
+ ]
+ },
+ "communication": [
+ {
+ "language": {
+ "coding": [
+ {
+ "system": "urn:ietf:bcp:47",
+ "code": "en-US",
+ "display": "English (Region=United States)"
+ }
+ ]
+ },
+ "preferred": true
+ }
+ ]
+}
diff --git a/plugin/ra/src/test/resources/Patient-ra-patient03.json b/plugin/ra/src/test/resources/Patient-ra-patient03.json
new file mode 100644
index 000000000..1b45ef856
--- /dev/null
+++ b/plugin/ra/src/test/resources/Patient-ra-patient03.json
@@ -0,0 +1,113 @@
+{
+ "resourceType": "Patient",
+ "id": "ra-patient03",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
+ ]
+ },
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex",
+ "valueCode": "F"
+ },
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race",
+ "extension": [
+ {
+ "url": "ombCategory",
+ "valueCoding": {
+ "system": "urn:oid:2.16.840.1.113883.6.238",
+ "code": "2054-5",
+ "display": "Black or African American"
+ }
+ },
+ {
+ "url": "text",
+ "valueString": "Black or African American"
+ }
+ ]
+ },
+ {
+ "url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity",
+ "extension": [
+ {
+ "url": "ombCategory",
+ "valueCoding": {
+ "system": "urn:oid:2.16.840.1.113883.6.238",
+ "code": "2186-5",
+ "display": "Not Hispanic or Latino"
+ }
+ },
+ {
+ "url": "text",
+ "valueString": "Not Hispanic or Latino"
+ }
+ ]
+ }
+ ],
+ "identifier": [
+ {
+ "use": "usual",
+ "type": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
+ "code": "MR",
+ "display": "Medical record number"
+ }
+ ]
+ },
+ "system": "http://hospital.davinci.org",
+ "value": "34567"
+ }
+ ],
+ "active": true,
+ "name": [
+ {
+ "use": "official",
+ "family": "Nuclear",
+ "given": [
+ "Nelda"
+ ]
+ }
+ ],
+ "gender": "female",
+ "birthDate": "1965-07-26",
+ "deceasedBoolean": false,
+ "address": [
+ {
+ "use": "home",
+ "line": [
+ "6666 Home Street"
+ ],
+ "city": "Ann Arbor",
+ "state": "MI",
+ "postalCode": "99999",
+ "country": "USA"
+ }
+ ],
+ "maritalStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-MaritalStatus",
+ "code": "M",
+ "display": "Married"
+ }
+ ]
+ },
+ "communication": [
+ {
+ "language": {
+ "coding": [
+ {
+ "system": "urn:ietf:bcp:47",
+ "code": "en-US",
+ "display": "English (Region=United States)"
+ }
+ ]
+ },
+ "preferred": true
+ }
+ ]
+}
diff --git a/plugin/ra/src/test/resources/application-test.yaml b/plugin/ra/src/test/resources/application-test.yaml
new file mode 100644
index 000000000..ad73d33c4
--- /dev/null
+++ b/plugin/ra/src/test/resources/application-test.yaml
@@ -0,0 +1,18 @@
+spring:
+ config:
+ import: application.yaml
+ main:
+ allow-bean-definition-overriding: true
+ batch:
+ job:
+ enabled: false"
+ datasource:
+ url: jdbc:h2:mem:dbr4-mt
+
+hapi:
+ fhir:
+ tester_enabled: false;
+ enforce_referential_integrity_on_write: false
+ ra:
+ report:
+ endpoint: http://localhost:%d/fhir
diff --git a/plugin/sdc/pom.xml b/plugin/sdc/pom.xml
index 46fa2f6f8..4c694123e 100644
--- a/plugin/sdc/pom.xml
+++ b/plugin/sdc/pom.xml
@@ -34,6 +34,12 @@
spring-boot-autoconfigure
provided
+
+ org.opencds.cqf.ruler
+ cqf-ruler-plugin-test-utility
+ 0.5.0-SNAPSHOT
+ test
+
org.junit.jupiter
junit-jupiter-api
diff --git a/plugin/sdc/src/test/java/org/opencds/cqf/ruler/plugin/sdc/r4/ExtractProviderIT.java b/plugin/sdc/src/test/java/org/opencds/cqf/ruler/plugin/sdc/r4/ExtractProviderIT.java
index c3966e2b3..f18324175 100644
--- a/plugin/sdc/src/test/java/org/opencds/cqf/ruler/plugin/sdc/r4/ExtractProviderIT.java
+++ b/plugin/sdc/src/test/java/org/opencds/cqf/ruler/plugin/sdc/r4/ExtractProviderIT.java
@@ -15,9 +15,8 @@
import org.opencds.cqf.ruler.Application;
import org.opencds.cqf.ruler.plugin.sdc.SDCConfig;
import org.opencds.cqf.ruler.plugin.sdc.SDCProperties;
-import org.opencds.cqf.ruler.plugin.utility.ResolutionUtilities;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opencds.cqf.ruler.plugin.testutility.ResolutionUtilities;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
@@ -37,8 +36,6 @@
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { Application.class,
SDCConfig.class }, properties = {"hapi.fhir.fhir_version=r4", "hapi.fhir.sdc.enabled=true" })
public class ExtractProviderIT implements ResolutionUtilities {
- private Logger log = LoggerFactory.getLogger(ExtractProviderIT.class);
-
private IGenericClient ourClient;
private FhirContext ourCtx;
diff --git a/plugin/test-utility/README.md b/plugin/test-utility/README.md
new file mode 100644
index 000000000..e195d10e9
--- /dev/null
+++ b/plugin/test-utility/README.md
@@ -0,0 +1,3 @@
+# test utility Plugin
+
+This plugin provides cross-cutting test utility functions for other plugins
diff --git a/plugin/test-utility/pom.xml b/plugin/test-utility/pom.xml
new file mode 100644
index 000000000..d47c25928
--- /dev/null
+++ b/plugin/test-utility/pom.xml
@@ -0,0 +1,55 @@
+
+ 4.0.0
+
+ org.opencds.cqf.ruler
+ cqf-ruler
+ 0.5.0-SNAPSHOT
+ ../..
+
+
+ cqf-ruler-plugin-test-utility
+
+
+ org.opencds.cqf.ruler
+ cqf-ruler-external
+ 0.5.0-SNAPSHOT
+ provided
+
+
+ org.opencds.cqf.ruler
+ cqf-ruler-server
+ 0.5.0-SNAPSHOT
+ classes
+ provided
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ provided
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ commons-io
+ commons-io
+
+
+ commons-validator
+ commons-validator
+
+
+
diff --git a/plugin/test-utility/src/main/java/org/opencds/cqf/ruler/plugin/testutility/ClientUtilities.java b/plugin/test-utility/src/main/java/org/opencds/cqf/ruler/plugin/testutility/ClientUtilities.java
new file mode 100644
index 000000000..7a2809337
--- /dev/null
+++ b/plugin/test-utility/src/main/java/org/opencds/cqf/ruler/plugin/testutility/ClientUtilities.java
@@ -0,0 +1,30 @@
+package org.opencds.cqf.ruler.plugin.testutility;
+
+/**
+ * This interface provides test utility functions for creating IGenericClients and
+ * setting up authentication
+ */
+public interface ClientUtilities {
+ public static String SERVER_URL = "http://localhost:%d/fhir";
+
+ /**
+ * Creates an client url given a url template and port
+ *
+ * @param theUrlTemplate the url template to use
+ * @param thePort the port to use
+ * @return String for the client url
+ */
+ public default String getClientUrl(String theUrlTemplate, Integer thePort) {
+ return String.format(theUrlTemplate, thePort);
+ }
+
+ /**
+ * Creates an client url using the default url and port
+ *
+ * @param thePort the port to use
+ * @return String for the client url
+ */
+ public default String getClientUrl(Integer thePort) {
+ return getClientUrl(SERVER_URL, thePort);
+ }
+}
diff --git a/plugin/test-utility/src/main/java/org/opencds/cqf/ruler/plugin/testutility/ResolutionUtilities.java b/plugin/test-utility/src/main/java/org/opencds/cqf/ruler/plugin/testutility/ResolutionUtilities.java
new file mode 100644
index 000000000..8f76ee35c
--- /dev/null
+++ b/plugin/test-utility/src/main/java/org/opencds/cqf/ruler/plugin/testutility/ResolutionUtilities.java
@@ -0,0 +1,68 @@
+package org.opencds.cqf.ruler.plugin.testutility;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.google.common.base.Charsets;
+import org.apache.commons.io.IOUtils;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
+import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
+
+/**
+ * This interface provides test utility functions for resolving FHIR resources from a location.
+ *
+ */
+public interface ResolutionUtilities {
+
+ /**
+ * Returns the Resource at the specified location.
+ *
+ * @param an IBaseResource type
+ * @param theResourceDao the DaoRegistry to use for resolution
+ * @param theLocation the location of the Resource to resolve
+ * @param theFhirContext the FhirContext to use to parse the resource
+ * @return the Resource at the specified location
+ * @throws IOException if the location does not exist or is unaccessible
+ */
+ @SuppressWarnings("unchecked")
+ public default ResourceType resolveByLocation(
+ DaoRegistry theResourceDao, String theLocation, FhirContext theFhirContext)
+ throws IOException {
+ String json = stringFromResource(theLocation);
+ IBaseResource resource = theFhirContext.newJsonParser().parseResource(json);
+ IFhirResourceDao dao = theResourceDao.getResourceDao(resource.getIdElement().getResourceType());
+ if (dao == null) {
+ return null;
+ } else {
+ dao.update(resource);
+ return (ResourceType) resource;
+ }
+ }
+
+ /**
+ * Returns a String representation of the Resource
+ * at the specified location.
+ *
+ * @param theLocation the location of the Resource to resolve
+ * @return the string representation of the Resource
+ * @throws IOException if the location does not exist or is unaccessible
+ */
+ public default String stringFromResource(String theLocation) throws IOException {
+ InputStream is = null;
+ if (theLocation.startsWith(File.separator)) {
+ is = new FileInputStream(theLocation);
+ } else {
+ DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
+ Resource resource = resourceLoader.getResource(theLocation);
+ is = resource.getInputStream();
+ }
+ return IOUtils.toString(is, Charsets.UTF_8);
+ }
+}
diff --git a/plugin/test-utility/src/main/resources/META-INF/spring.factories b/plugin/test-utility/src/main/resources/META-INF/spring.factories
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugin/test-utility/src/test/java/org/opencds/cqf/ruler/plugin/testutility/ClientUtilitiesTest.java b/plugin/test-utility/src/test/java/org/opencds/cqf/ruler/plugin/testutility/ClientUtilitiesTest.java
new file mode 100644
index 000000000..c76a48062
--- /dev/null
+++ b/plugin/test-utility/src/test/java/org/opencds/cqf/ruler/plugin/testutility/ClientUtilitiesTest.java
@@ -0,0 +1,36 @@
+package org.opencds.cqf.ruler.plugin.testutility;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.commons.validator.routines.UrlValidator;
+import org.junit.jupiter.api.Test;
+
+public class ClientUtilitiesTest implements ClientUtilities {
+ @Test
+ public void testClientUrlWithTemplate() {
+
+ String template = "http://localhost:%d/fhir";
+ Integer port = 8084;
+ String url = getClientUrl(template, port);
+
+ String[] schemes = {"http","https"};
+ UrlValidator urlValidator = new UrlValidator(schemes, UrlValidator.ALLOW_LOCAL_URLS);
+
+ assertTrue(urlValidator.isValid(url));
+
+ assertEquals("http://localhost:8084/fhir", url);
+ }
+
+ @Test
+ public void testClientUrlWithoutTemplate() {
+
+ Integer port = 8084;
+ String url = getClientUrl(port);
+
+ String[] schemes = {"http","https"};
+ UrlValidator urlValidator = new UrlValidator(schemes, UrlValidator.ALLOW_LOCAL_URLS);
+
+ assertTrue(urlValidator.isValid(url));
+ }
+}
diff --git a/plugin/utility/pom.xml b/plugin/utility/pom.xml
index 50d10f69b..884eb8740 100644
--- a/plugin/utility/pom.xml
+++ b/plugin/utility/pom.xml
@@ -14,19 +14,19 @@
org.opencds.cqf.ruler
cqf-ruler-external
0.5.0-SNAPSHOT
-
+ provided
org.opencds.cqf.ruler
cqf-ruler-server
0.5.0-SNAPSHOT
classes
-
+ provided
org.springframework.boot
spring-boot-autoconfigure
-
+ provided
org.junit.jupiter
@@ -43,11 +43,9 @@
spring-boot-starter-test
test
-
-
- commons-io
- commons-io
- 2.6
-
+
+ commons-io
+ commons-io
+
diff --git a/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/ClientUtilities.java b/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/ClientUtilities.java
index 05b06ba16..5f76425b4 100644
--- a/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/ClientUtilities.java
+++ b/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/ClientUtilities.java
@@ -19,7 +19,7 @@
* setting up authentication
*/
public interface ClientUtilities {
-
+
/**
* Creates an IGenericClient for the given url. Defaults to NEVER
* ServerValidationMode
diff --git a/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/OperatorUtilities.java b/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/OperatorUtilities.java
new file mode 100644
index 000000000..54468d97c
--- /dev/null
+++ b/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/OperatorUtilities.java
@@ -0,0 +1,139 @@
+package org.opencds.cqf.ruler.plugin.utility;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This interface provides utilities for implementing FHIR operators.
+ */
+public interface OperatorUtilities extends ResolutionUtilities {
+
+ public static final Logger ourLog = LoggerFactory.getLogger(OperatorUtilities.class);
+
+ /**
+ * This function converts a string representation of a FHIR period date to a
+ * java.util.Date.
+ *
+ * @param date the date to convert
+ * @param start whether the date is the start of a period
+ * @return the FHIR period date as a java.util.Date type
+ */
+ public default Date resolveRequestDate(String date, boolean start) {
+ // split it up - support dashes or slashes
+ String[] dissect = date.contains("-") ? date.split("-") : date.split("/");
+ List dateVals = new ArrayList<>();
+ for (String dateElement : dissect) {
+ dateVals.add(Integer.parseInt(dateElement));
+ }
+
+ if (dateVals.isEmpty()) {
+ throw new IllegalArgumentException("Invalid date");
+ }
+
+ // for now support dates up to day precision
+ Calendar calendar = Calendar.getInstance();
+ calendar.clear();
+ calendar.setTimeZone(TimeZone.getDefault());
+ calendar.set(Calendar.YEAR, dateVals.get(0));
+ if (dateVals.size() > 1) {
+ // java.util.Date months are zero based, hence the negative 1 -- 2014-01 ==
+ // February 2014
+ calendar.set(Calendar.MONTH, dateVals.get(1) - 1);
+ }
+ if (dateVals.size() > 2)
+ calendar.set(Calendar.DAY_OF_MONTH, dateVals.get(2));
+ else {
+ if (start) {
+ calendar.set(Calendar.DAY_OF_MONTH, 1);
+ } else {
+ // get last day of month for end period
+ calendar.add(Calendar.MONTH, 1);
+ calendar.set(Calendar.DAY_OF_MONTH, 1);
+ calendar.add(Calendar.DATE, -1);
+ }
+ }
+ return calendar.getTime();
+ }
+
+ /**
+ * This function returns a fullUrl for a resource.
+ *
+ * @param serverAddress the address of the server
+ * @param fhirType the type of the resource
+ * @param elementId the id of the resource
+ * @return the FHIR period date as a java.util.Date type
+ */
+ public default String getFullUrl(String serverAddress, String fhirType, String elementId) {
+ String fullUrl = String.format("%s%s/%s", serverAddress, fhirType, elementId);
+ return fullUrl;
+ }
+
+ // This has some issues
+ // public default void ensurePatient(String
+ // patientRef, DaoRegistry theRegistry, Class theResourceType) {
+ // IBaseResource patient = resolveById(theRegistry, theResourceType,
+ // patientRef);
+ // if (patient == null) {
+ // throw new RuntimeException("Could not find Patient: " + patientRef);
+ // }
+ // }
+
+ // //TODO: replace this with version from base structures
+ // public default List
+ // getPatientListFromSubject(String theSubject, DaoRegistry theRegistry,
+ // Class thePatientType, Class theGroupType) {
+ // List patientList = null;
+
+ // if (theSubject.startsWith("Patient/")) {
+ // ensurePatient(theSubject, theRegistry, thePatientType);
+ // patientList = new ArrayList();
+ // Reference patientReference = new Reference().setReference(theSubject);
+ // patientList.add(patientReference);
+ // } else if (theSubject.startsWith("Group/")) {
+ // patientList = getPatientListFromGroup(theSubject, theRegistry,
+ // thePatientType, theGroupType);
+ // } else {
+ // ourLog.info(String.format("Subject member was not a Patient or a Group, so
+ // skipping. \n%s", theSubject));
+ // }
+
+ // return patientList;
+ // }
+
+ // //TODO: replace this with version from base structures
+ // public default List
+ // getPatientListFromGroup(String subjectGroupId, DaoRegistry theRegistry,
+ // Class thePatientType, Class theGroupType){
+ // List patientList = new ArrayList<>();
+
+ // IBaseResource baseGroup = resolveById(theRegistry, theGroupType,
+ // subjectGroupId);
+ // if (baseGroup == null) {
+ // throw new RuntimeException("Could not find Group: " + subjectGroupId);
+ // }
+
+ // Group group = (Group)baseGroup;
+ // group.getMember().forEach(member -> {
+ // Reference reference = member.getEntity();
+ // if (reference.getReference().getValue().startsWith("/Patient")) {
+ // ensurePatient(reference.getReference().getValue(), theRegistry,
+ // thePatientType);
+ // patientList.add(reference);
+ // } else if (reference.getReference().getValue().startsWith("/Group")) {
+ // patientList.addAll(getPatientListFromGroup(reference.getReference().getValue(),
+ // theRegistry, thePatientType, theGroupType));
+ // } else {
+ // ourLog.info(String.format("Group member was not a Patient or a Group, so
+ // skipping. \n%s", reference.getReference()));
+ // }
+ // });
+
+ // return patientList;
+ // }
+}
diff --git a/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/ResolutionUtilities.java b/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/ResolutionUtilities.java
index b813775dc..1add20388 100644
--- a/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/ResolutionUtilities.java
+++ b/plugin/utility/src/main/java/org/opencds/cqf/ruler/plugin/utility/ResolutionUtilities.java
@@ -1,20 +1,11 @@
package org.opencds.cqf.ruler.plugin.utility;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.List;
-import com.google.common.base.Charsets;
-import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
-import org.springframework.core.io.DefaultResourceLoader;
-import org.springframework.core.io.Resource;
-import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@@ -33,9 +24,9 @@ public interface ResolutionUtilities extends IdUtilities, VersionUtilities {
/**
* Returns the Resource with a matching Id
*
- * @param an IBaseResource type
- * @param theDaoRegistry the DaoRegistry to use for resolution
- * @param theId the Id of the Resource to resolve
+ * @param an IBaseResource type
+ * @param theDaoRegistry the DaoRegistry to use for resolution
+ * @param theId the Id of the Resource to resolve
* @return the Resource matching the criteria
*/
public default ResourceType resolveById(DaoRegistry theDaoRegistry,
@@ -467,45 +458,4 @@ public default ResourceType resolveByCanoni
RequestDetails theRequestDetails) {
return this.resolveByCanonicalUrl(theResourceDao, theUrl.getValue(), theRequestDetails);
}
-
- /**
- * Returns the Resource at the specified location.
- * @param an IBaseResource type
- * @param theResourceDao the DaoRegistry to use for resolution
- * @param theLocation the location of the Resource to resolve
- * @param theFhirContext the FhirContext to use to parse the resource
- * @return the Resource at the specified location
- */
- @SuppressWarnings("unchecked")
- public default ResourceType resolveByLocation(
- DaoRegistry theResourceDao, String theLocation, FhirContext theFhirContext)
- throws IOException {
- String json = stringFromResource(theLocation);
- IBaseResource resource = theFhirContext.newJsonParser().parseResource(json);
- IFhirResourceDao dao = theResourceDao.getResourceDao(resource.getIdElement().getResourceType());
- if (dao == null) {
- return null;
- } else {
- dao.update(resource);
- return (ResourceType) resource;
- }
- }
-
- /**
- * Returns a String representation of the Resource
- * at the specified location.
- * @param theLocation the location of the Resource to resolve
- * @return the string representation of the Resource
- */
- public default String stringFromResource(String theLocation) throws IOException {
- InputStream is = null;
- if (theLocation.startsWith(File.separator)) {
- is = new FileInputStream(theLocation);
- } else {
- DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
- Resource resource = resourceLoader.getResource(theLocation);
- is = resource.getInputStream();
- }
- return IOUtils.toString(is, Charsets.UTF_8);
- }
}
diff --git a/plugin/utility/src/test/java/org/opencds/cqf/ruler/plugin/utility/ResolutionUtilitiesIT.java b/plugin/utility/src/test/java/org/opencds/cqf/ruler/plugin/utility/ResolutionUtilitiesIT.java
index c02c370f5..2cb829318 100644
--- a/plugin/utility/src/test/java/org/opencds/cqf/ruler/plugin/utility/ResolutionUtilitiesIT.java
+++ b/plugin/utility/src/test/java/org/opencds/cqf/ruler/plugin/utility/ResolutionUtilitiesIT.java
@@ -17,135 +17,143 @@
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
+import ca.uhn.fhir.jpa.model.config.PartitionSettings;
+
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {
- Application.class }, properties = {
- // Override is currently required when using MDM as the construction of the MDM
- // beans are ambiguous as they are constructed multiple places. This is evident
- // when running in a spring boot environment
- "spring.main.allow-bean-definition-overriding=true",
- "spring.batch.job.enabled=false",
- "spring.datasource.url=jdbc:h2:mem:dbr4-mt",
- "hapi.fhir.fhir_version=r4",
- "hapi.fhir.tester_enabled=false",
+ Application.class }, properties = {
+ // Override is currently required when using MDM as the construction of the MDM
+ // beans are ambiguous as they are constructed multiple places. This is evident
+ // when running in a spring boot environment
+ "spring.main.allow-bean-definition-overriding=true",
+ "spring.batch.job.enabled=false",
+ "spring.datasource.url=jdbc:h2:mem:dbr4-mt",
+ "hapi.fhir.fhir_version=r4",
+ "hapi.fhir.tester_enabled=false",
})
@TestInstance(Lifecycle.PER_CLASS)
public class ResolutionUtilitiesIT implements ResolutionUtilities {
- @Autowired
- private DaoRegistry ourRegistry;
-
- @LocalServerPort
- private int port;
-
- @BeforeAll
- void beforeAll() {
- Library library1 = new Library().setName("TestLibrary").setVersion("1.0.0")
- .setUrl("http://test.com/Library/TestLibrary");
- library1.setId("libraryone");
- ourRegistry.getResourceDao(Library.class).update(library1);
-
- Library library2 = new Library().setName("TestLibrary").setVersion("2.0.0")
- .setUrl("http://test.com/Library/TestLibrary");
- library2.setId("librarytwo");
- ourRegistry.getResourceDao(Library.class).update(library2);
-
- Patient patient = new Patient();
- patient.setId("patientone");
- ourRegistry.getResourceDao(Patient.class).update(patient);
-
- Observation obs = new Observation();
- patient.setId("observationone");
- ourRegistry.getResourceDao(Observation.class).create(obs);
- }
-
- @Test
- public void testResolveByCanonicalUrl() {
- // Versionless resolves latest version
- Library lib = this.resolveByCanonicalUrl(ourRegistry, Library.class, "http://test.com/Library/TestLibrary");
- assertNotNull(lib);
- assertEquals("2.0.0", lib.getVersion());
-
- // Versioned resolves correct version
- lib = this.resolveByCanonicalUrl(ourRegistry, Library.class, "http://test.com/Library/TestLibrary|1.0.0");
- assertNotNull(lib);
- assertEquals("1.0.0", lib.getVersion());
-
- // Non-url Resource type explodes
- assertThrows(RuntimeException.class, () -> {
- this.resolveByCanonicalUrl(ourRegistry, Patient.class, "http://test.com/Patient");
- });
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void testResolveByName() {
- // Name only resolves latest version
- Library lib = this.resolveByName(ourRegistry, Library.class, "TestLibrary");
- assertNotNull(lib);
- assertEquals("2.0.0", lib.getVersion());
-
- // Name only on resource dao resolves latest version
- lib = (Library) this.resolveByName(ourRegistry.getResourceDao("Library"), "TestLibrary");
- assertNotNull(lib);
- assertEquals("2.0.0", lib.getVersion());
-
- // Non-name Resource type explodes
- assertThrows(RuntimeException.class, () -> {
- this.resolveByName(ourRegistry, Observation.class, "NotAName");
- });
- }
-
- @Test
- public void testResolveByNameAndVersion() {
- // Name only resolves latest version
- Library lib = this.resolveByNameAndVersion(ourRegistry, Library.class, "TestLibrary", null);
- assertNotNull(lib);
- assertEquals("2.0.0", lib.getVersion());
-
- // Version resolves correct version
- lib = this.resolveByNameAndVersion(ourRegistry, Library.class, "TestLibrary", "1.0.0");
- assertNotNull(lib);
- assertEquals("1.0.0", lib.getVersion());
-
- // Non-name Resource type explodes
- assertThrows(RuntimeException.class, () -> {
- this.resolveByNameAndVersion(ourRegistry, Observation.class, "NotAName", null);
- });
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void testResolveById() {
- // Full Id resolves
- Library lib = this.resolveById(ourRegistry, Library.class, "Library/librarytwo");
- assertNotNull(lib);
- assertEquals("librarytwo", lib.getIdElement().getIdPart());
-
- // Partial Id resolves
- lib = this.resolveById(ourRegistry, Library.class, "libraryone");
- assertNotNull(lib);
- assertEquals("libraryone", lib.getIdElement().getIdPart());
-
- // FhirDao resolves
- lib = (Library) this.resolveById(ourRegistry.getResourceDao("Library"), "Library/librarytwo");
- assertNotNull(lib);
- assertEquals("librarytwo", lib.getIdElement().getIdPart());
-
- // Doesn't exist explodes
- assertThrows(RuntimeException.class, () -> {
- this.resolveById(ourRegistry, Library.class, "librarythree");
- });
-
- // Doesn't exist on partition explodes
- assertThrows(RuntimeException.class, () -> {
- this.resolveById(ourRegistry, Patient.class, "patienttwo");
- });
-
- // Mismatched Id types explodes
- assertThrows(RuntimeException.class, () -> {
- this.resolveById(ourRegistry, Library.class, "Patient/patientone");
- });
- }
+ @Autowired
+ private DaoRegistry ourRegistry;
+
+ @LocalServerPort
+ private int port;
+
+ @Autowired
+ protected PartitionSettings myPartitionSettings;
+
+ @BeforeAll
+ void beforeAll() {
+ // Spring reusues application context, so need to set this because there are multi-tenant tests
+ myPartitionSettings.setPartitioningEnabled(false);
+
+ Library library1 = new Library().setName("TestLibrary").setVersion("1.0.0")
+ .setUrl("http://test.com/Library/TestLibrary");
+ library1.setId("libraryone");
+ ourRegistry.getResourceDao(Library.class).update(library1);
+
+ Library library2 = new Library().setName("TestLibrary").setVersion("2.0.0")
+ .setUrl("http://test.com/Library/TestLibrary");
+ library2.setId("librarytwo");
+ ourRegistry.getResourceDao(Library.class).update(library2);
+
+ Patient patient = new Patient();
+ patient.setId("patientone");
+ ourRegistry.getResourceDao(Patient.class).update(patient);
+
+ Observation obs = new Observation();
+ patient.setId("observationone");
+ ourRegistry.getResourceDao(Observation.class).create(obs);
+ }
+
+ @Test
+ public void testResolveByCanonicalUrl() {
+ // Versionless resolves latest version
+ Library lib = this.resolveByCanonicalUrl(ourRegistry, Library.class, "http://test.com/Library/TestLibrary");
+ assertNotNull(lib);
+ assertEquals("2.0.0", lib.getVersion());
+
+ // Versioned resolves correct version
+ lib = this.resolveByCanonicalUrl(ourRegistry, Library.class, "http://test.com/Library/TestLibrary|1.0.0");
+ assertNotNull(lib);
+ assertEquals("1.0.0", lib.getVersion());
+
+ // Non-url Resource type explodes
+ assertThrows(RuntimeException.class, () -> {
+ this.resolveByCanonicalUrl(ourRegistry, Patient.class, "http://test.com/Patient");
+ });
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testResolveByName() {
+ // Name only resolves latest version
+ Library lib = this.resolveByName(ourRegistry, Library.class, "TestLibrary");
+ assertNotNull(lib);
+ assertEquals("2.0.0", lib.getVersion());
+
+ // Name only on resource dao resolves latest version
+ lib = (Library) this.resolveByName(ourRegistry.getResourceDao("Library"), "TestLibrary");
+ assertNotNull(lib);
+ assertEquals("2.0.0", lib.getVersion());
+
+ // Non-name Resource type explodes
+ assertThrows(RuntimeException.class, () -> {
+ this.resolveByName(ourRegistry, Observation.class, "NotAName");
+ });
+ }
+
+ @Test
+ public void testResolveByNameAndVersion() {
+ // Name only resolves latest version
+ Library lib = this.resolveByNameAndVersion(ourRegistry, Library.class, "TestLibrary", null);
+ assertNotNull(lib);
+ assertEquals("2.0.0", lib.getVersion());
+
+ // Version resolves correct version
+ lib = this.resolveByNameAndVersion(ourRegistry, Library.class, "TestLibrary", "1.0.0");
+ assertNotNull(lib);
+ assertEquals("1.0.0", lib.getVersion());
+
+ // Non-name Resource type explodes
+ assertThrows(RuntimeException.class, () -> {
+ this.resolveByNameAndVersion(ourRegistry, Observation.class, "NotAName", null);
+ });
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testResolveById() {
+ // Full Id resolves
+ Library lib = this.resolveById(ourRegistry, Library.class, "Library/librarytwo");
+ assertNotNull(lib);
+ assertEquals("librarytwo", lib.getIdElement().getIdPart());
+
+ // Partial Id resolves
+ lib = this.resolveById(ourRegistry, Library.class, "libraryone");
+ assertNotNull(lib);
+ assertEquals("libraryone", lib.getIdElement().getIdPart());
+
+ // FhirDao resolves
+ lib = (Library) this.resolveById(ourRegistry.getResourceDao("Library"), "Library/librarytwo");
+ assertNotNull(lib);
+ assertEquals("librarytwo", lib.getIdElement().getIdPart());
+
+ // Doesn't exist explodes
+ assertThrows(RuntimeException.class, () -> {
+ this.resolveById(ourRegistry, Library.class, "librarythree");
+ });
+
+ // Doesn't exist on partition explodes
+ assertThrows(RuntimeException.class, () -> {
+ this.resolveById(ourRegistry, Patient.class, "patientblahblah");
+ });
+
+ // Mismatched Id types explodes
+ assertThrows(RuntimeException.class, () -> {
+ this.resolveById(ourRegistry, Library.class, "Patient/patientone");
+ });
+ }
}
diff --git a/pom.xml b/pom.xml
index e9c264b1f..a600014f3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,113 +1,115 @@
- 4.0.0
-
- org.opencds.cqf.ruler
- cqf-ruler
- 0.5.0-SNAPSHOT
- pom
-
-
- external
- server
- plugin/utility
- plugin/hello-world
- plugin/sdc
-
-
+
-
-
-
- cqf-ruler
- CQL Ruler
- https://github.com/DBCG/cqf-ruler/tree/master
-
-
-
- The Apache Software License, Version 2.0
- http://www.apache.org/licenses/LICENSE-2.0.txt
-
-
-
-
-
- Bryn Rhodes
-
-
- Chris Schuler
-
-
- Jonathan Percival
- Alphora
-
-
-
-
- scm:git:git://github.com/DBCG/cqf-ruler.git
- scm:git:ssh://github.com:DBCG/cqf-ruler.git
- https://github.com/DBCG/cqf-ruler/tree/master
-
-
-
-
- UTF-8
- UTF-8
-
-
- 5.3.11
- 5.5.3
- image/v5.5.1
- 8.0.1
- 0.62.2
- 2.5.6
- 5.3.12
-
-
- 1.5.3-SNAPSHOT
- 1.3.1-SNAPSHOT
- 1.5.4
- 1.3.1-SNAPSHOT
- 1.3.1-SNAPSHOT
-
-
-
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
-
-
-
- ossrh
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
-
-
-
-
- oss-sonatype
- https://oss.sonatype.org/content/repositories/snapshots
-
- true
-
-
-
- oss-sonatype-public
- https://oss.sonatype.org/content/groups/public/
-
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-dependencies
- ${spring_boot_version}
- pom
- import
-
-
-
+
+
+ cqf-ruler
+ CQL Ruler
+ https://github.com/DBCG/cqf-ruler/tree/master
+
+
+
+ The Apache Software License, Version 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+
+
+
+
+
+ Bryn Rhodes
+
+
+ Chris Schuler
+
+
+ Jonathan Percival
+ Alphora
+
+
+
+
+ scm:git:git://github.com/DBCG/cqf-ruler.git
+ scm:git:ssh://github.com:DBCG/cqf-ruler.git
+ https://github.com/DBCG/cqf-ruler/tree/master
+
+
+
+
+ UTF-8
+ UTF-8
+
+
+ 5.3.11
+ 5.5.3
+ image/v5.5.1
+ 8.0.1
+ 0.62.2
+ 2.5.6
+ 5.3.12
+
+
+ 1.5.3-SNAPSHOT
+ 1.3.1-SNAPSHOT
+ 1.5.4
+ 1.3.1-SNAPSHOT
+ 1.3.1-SNAPSHOT
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+
+ ossrh
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+
+ oss-sonatype
+ https://oss.sonatype.org/content/repositories/snapshots
+
+ true
+
+
+
+ oss-sonatype-public
+ https://oss.sonatype.org/content/groups/public/
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring_boot_version}
+ pom
+ import
+
+
+
-
- ca.uhn.hapi.fhir
- hapi-fhir-bom
- ${hapi_version}
- pom
- import
-
-
-
- org.junit
- junit-bom
- 5.8.1
- pom
- import
-
-
-
-
- ca.uhn.hapi.fhir
- hapi-fhir-test-utilities
- ${hapi_version}
- test
-
-
-
- ca.uhn.hapi.fhir
- hapi-fhir-testpage-overlay
- ${hapi_version}
- classes
-
-
-
- ca.uhn.hapi.fhir
- hapi-fhir-testpage-overlay
- ${hapi_version}
- war
-
-
-
- ca.uhn.hapi.fhir
- hapi-fhir-jpaserver-cql
- ${hapi_version}
-
-
- org.opencds.cqf.cql
- evaluator.engine
- ${cql-evaluator.version}
-
-
- org.opencds.cqf.cql
- evaluator.fhir
- ${cql-evaluator.version}
-
-
-
- org.opencds.cqf.cql
- evaluator.activitydefinition
- ${cql-evaluator.version}
-
-
- org.opencds.cqf.cql
- evaluator.expression
- ${cql-evaluator.version}
-
-
- org.opencds.cqf.cql
- evaluator.plandefinition
- ${cql-evaluator.version}
-
-
- org.opencds.cqf.cql
- evaluator.spring
- ${cql-evaluator.version}
-
-
- org.opencds.cqf.cql
- evaluator.library
- ${cql-evaluator.version}
-
-
- org.opencds.cqf
- tooling
- ${cqf-tooling.version}
-
-
-
- org.opencds.cqf.cql
- engine
- ${cql-engine.version}
-
-
-
- org.opencds.cqf.cql
- engine.fhir
- ${cql-engine.version}
-
-
-
- info.cqframework
- cql-to-elm
- ${cqframework.version}
-
-
-
- info.cqframework
- cql-formatter
- ${cqframework.version}
-
-
-
- info.cqframework
- qdm
- ${cqframework.version}
-
-
-
- info.cqframework
- quick
- ${cqframework.version}
-
-
-
- info.cqframework
- cql
- ${cqframework.version}
-
-
-
- info.cqframework
- model
- ${cqframework.version}
-
-
-
- info.cqframework
- elm
- ${cqframework.version}
-
-
-
- org.opencds.cqf
- cds
- ${cds-hooks.version}
-
-
-
- com.vladsch.flexmark
- flexmark
- ${flexmark_version}
-
-
- com.vladsch.flexmark
- flexmark-ext-tables
- ${flexmark_version}
-
-
- com.vladsch.flexmark
- flexmark-ext-gfm-strikethrough
- ${flexmark_version}
-
-
- com.vladsch.flexmark
- flexmark-profile-pegdown
- ${flexmark_version}
-
-
-
- com.vladsch.flexmark
- flexmark-ext-autolink
- ${flexmark_version}
-
-
- com.vladsch.flexmark
- flexmark-ext-gfm-tasklist
- ${flexmark_version}
-
-
-
- javax
- javaee-api
- ${javax.version}
-
-
-
-
- commons-io
- commons-io
- 2.11.0
-
-
-
- org.yaml
- snakeyaml
- 1.28
-
-
-
- org.webjars
- bootstrap
- 5.0.1
-
-
-
- org.springframework
- spring-context
- ${spring_version}
-
-
-
- org.springframework.boot
- spring-boot-autoconfigure
- ${spring_boot_version}
-
-
-
- org.springframework.boot
- spring-boot-starter
- ${spring_boot_version}
-
-
-
- org.springframework.boot
- spring-boot-starter-web
- ${spring_boot_version}
-
-
-
- org.springframework.boot
- spring-boot-devtools
- ${spring_boot_version}
- true
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- ${spring_boot_version}
- test
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-antrun-plugin
- 3.0.0
-
-
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
+
+ commons-validator
+ commons-validator
+ 1.7
+
+
+
+ org.yaml
+ snakeyaml
+ 1.28
+
+
+
+ org.webjars
+ bootstrap
+ 5.0.1
+
+
+
+ org.springframework
+ spring-context
+ ${spring_version}
+
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ ${spring_boot_version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+ ${spring_boot_version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring_boot_version}
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ ${spring_boot_version}
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ ${spring_boot_version}
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 3.0.0
+
+
-
- org.apache.maven.plugins
- maven-dependency-plugin
- 3.2.0
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.8.1
-
-
- 1.8
- true
- true
-
- -Xlint:all
-
- -Xlint:-options
- -Xlint:-processing
- -Werror
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.2.0
-
-
-
- true
- true
-
-
-
-
-
- org.apache.maven.plugins
- maven-war-plugin
- 3.3.2
-
-
-
- true
- true
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 3.3.1
-
-
-
-
-
- attach-javadocs
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 3.2.1
-
-
- attach-sources
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-gpg-plugin
- 3.0.1
-
-
- sign-artifacts
- deploy
-
- sign
-
-
-
-
-
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.8
- true
-
- ossrh
- https://oss.sonatype.org/
- true
-
-
-
- org.apache.maven.plugins
- maven-enforcer-plugin
- 3.0.0
-
-
- enforce-no-snapshots
-
- enforce
-
-
-
-
- No Snapshot Versions Allowed!
-
-
- No Snapshot Dependencies Allowed!
-
-
- true
-
-
-
-
-
- org.basepom.maven
- duplicate-finder-maven-plugin
- 1.5.0
-
-
- org.apache.maven.plugins
- maven-failsafe-plugin
- 3.0.0-M5
-
- true
-
-
-
-
- integration-test
- verify
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.0.0-M5
-
-
- org.apache.maven.plugins
- maven-deploy-plugin
- 3.0.0-M1
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
- 3.2.0
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- org.apache.maven.plugins
- maven-failsafe-plugin
-
-
-
-
-
- java-9
-
- [9,)
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- 8
-
-
-
-
-
-
-
- ci
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
-
-
- org.apache.maven.plugins
- maven-deploy-plugin
-
-
-
-
-
- release
-
-
-
- org.apache.maven.plugins
- maven-enforcer-plugin
-
-
- org.apache.maven.plugins
- maven-gpg-plugin
-
-
- org.sonatype.plugins
- nexus-staging-maven-plugin
-
-
-
-
-
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.2.0
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 1.8
+ true
+ true
+
+ -Xlint:all
+
+ -Xlint:-options
+ -Xlint:-processing
+ -Werror
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.2.0
+
+
+
+ true
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 3.3.2
+
+
+
+ true
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.3.1
+
+
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.0.1
+
+
+ sign-artifacts
+ deploy
+
+ sign
+
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ 1.6.8
+ true
+
+ ossrh
+ https://oss.sonatype.org/
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 3.0.0
+
+
+ enforce-no-snapshots
+
+ enforce
+
+
+
+
+ No Snapshot Versions Allowed!
+
+
+ No Snapshot Dependencies Allowed!
+
+
+ true
+
+
+
+
+
+ org.basepom.maven
+ duplicate-finder-maven-plugin
+ 1.5.0
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 3.0.0-M5
+
+ true
+
+
+
+
+ integration-test
+ verify
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M5
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 3.0.0-M1
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.2.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+
+
+
+ java-9
+
+ [9,)
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+
+
+
+
+
+
+
+ ci
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+
+
+
+
+ release
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+
+
+
+
+
diff --git a/server/src/main/resources/application.yaml b/server/src/main/resources/application.yaml
index 0f16434df..26ee8793e 100644
--- a/server/src/main/resources/application.yaml
+++ b/server/src/main/resources/application.yaml
@@ -138,6 +138,14 @@ hapi:
### 1: NORMALIZED_QUANTITY_STORAGE_SUPPORTED
### 2: NORMALIZED_QUANTITY_SEARCH_SUPPORTED
# normalized_quantity_search_level: 2
+
+## RA Settings
+ ra:
+ enabled: true
+ report:
+ endpoint: ''
+
+
#elasticsearch:
# debug:
# pretty_print_json_log: false