From 6e2b425fb5b1bf0d51140ed3267d7e701a662958 Mon Sep 17 00:00:00 2001 From: Joseph Kotanchik Date: Fri, 13 Dec 2024 13:49:06 -0500 Subject: [PATCH] MAT-8019: Skip Bundle validation for QICore STU6 Test Cases. Bundle validation is generic, check for presence of a Patient Resource to ensure passed Bundle is a Test Case. When skipping validations, return a "Nothing to see here!"-esque response with just enough content to be used by the frontend. Control validation skip via feature flag, stu6TestCaseValidation. --- .../dto/MadieFeatureFlag.java | 3 +- .../resources/ValidationController.java | 32 ++++++++++++++++++- .../ValidationControllerMvcTest.java | 2 ++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/main/java/gov/cms/madie/madiefhirservice/dto/MadieFeatureFlag.java b/src/main/java/gov/cms/madie/madiefhirservice/dto/MadieFeatureFlag.java index f1f515ed..718ecbdf 100644 --- a/src/main/java/gov/cms/madie/madiefhirservice/dto/MadieFeatureFlag.java +++ b/src/main/java/gov/cms/madie/madiefhirservice/dto/MadieFeatureFlag.java @@ -2,7 +2,8 @@ /** Feature flags relevant to the measure-service */ public enum MadieFeatureFlag { - QiCore_STU4_UPDATES("qiCoreStu4Updates"); + QiCore_STU4_UPDATES("qiCoreStu4Updates"), + STU6_TEST_CASE_VALIDATION("stu6TestCaseValidation"); private final String flag; diff --git a/src/main/java/gov/cms/madie/madiefhirservice/resources/ValidationController.java b/src/main/java/gov/cms/madie/madiefhirservice/resources/ValidationController.java index 32fdca37..5891e8f7 100644 --- a/src/main/java/gov/cms/madie/madiefhirservice/resources/ValidationController.java +++ b/src/main/java/gov/cms/madie/madiefhirservice/resources/ValidationController.java @@ -6,9 +6,12 @@ import ca.uhn.fhir.util.OperationOutcomeUtil; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.ValidationResult; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import gov.cms.madie.madiefhirservice.dto.MadieFeatureFlag; import gov.cms.madie.madiefhirservice.factories.ModelAwareFhirFactory; +import gov.cms.madie.madiefhirservice.services.AppConfigService; import gov.cms.madie.models.common.ModelType; import gov.cms.madie.models.measure.HapiOperationOutcome; import gov.cms.madie.madiefhirservice.exceptions.HapiJsonException; @@ -16,8 +19,10 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; +import org.hl7.fhir.r4.model.OperationOutcome; import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -26,6 +31,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.Objects; + import static gov.cms.madie.madiefhirservice.utils.ModelEndpointMap.QICORE_VERSION_MODELTYPE_MAP; @Slf4j @@ -39,6 +46,7 @@ public class ValidationController { private ResourceValidationService validationService; private ModelAwareFhirFactory validatorFactory; + private AppConfigService appConfigService; private ObjectMapper mapper; @@ -49,8 +57,17 @@ public class ValidationController { public HapiOperationOutcome validateBundleByModel( @PathVariable("model") String modelVersion, HttpEntity request) { final ModelType modelType = QICORE_VERSION_MODELTYPE_MAP.get(modelVersion); - FhirContext fhirContext = validatorFactory.getContextForModel(modelType); IParser parser = validatorFactory.getJsonParserForModel(modelType); + + // MAT-8019: Disable Test Case Validations for QI-Core STU 6 only. + if (ModelType.QI_CORE_6_0_0.equals(modelType) + && !appConfigService.isFlagEnabled(MadieFeatureFlag.STU6_TEST_CASE_VALIDATION) + && StringUtils.deleteWhitespace(Objects.requireNonNull(request.getBody()).trim()) + .contains("\"resourceType\":\"Patient\"")) { + return noValidationResponse(parser); + } + + FhirContext fhirContext = validatorFactory.getContextForModel(modelType); FhirValidator fhirValidator = validatorFactory.getValidatorForModel(modelType); IBaseBundle bundle; try { @@ -93,4 +110,17 @@ public HapiOperationOutcome validateBundleByModel( throw new HapiJsonException("An error occurred processing the validation results", ex); } } + + private HapiOperationOutcome noValidationResponse(IParser parser) { + try { + return HapiOperationOutcome.builder() + .code(HttpStatus.OK.value()) + .successful(true) + .outcomeResponse( + mapper.readValue(parser.encodeResourceToString(new OperationOutcome()), Object.class)) + .build(); + } catch (JsonProcessingException e) { + throw new HapiJsonException("An error occurred processing the validation results", e); + } + } } diff --git a/src/test/java/gov/cms/madie/madiefhirservice/resources/ValidationControllerMvcTest.java b/src/test/java/gov/cms/madie/madiefhirservice/resources/ValidationControllerMvcTest.java index bfe8182b..0134d8d1 100644 --- a/src/test/java/gov/cms/madie/madiefhirservice/resources/ValidationControllerMvcTest.java +++ b/src/test/java/gov/cms/madie/madiefhirservice/resources/ValidationControllerMvcTest.java @@ -5,6 +5,7 @@ import ca.uhn.fhir.parser.StrictErrorHandler; import ca.uhn.fhir.validation.FhirValidator; import gov.cms.madie.madiefhirservice.factories.ModelAwareFhirFactory; +import gov.cms.madie.madiefhirservice.services.AppConfigService; import gov.cms.madie.madiefhirservice.services.ResourceValidationService; import gov.cms.madie.madiefhirservice.utils.ResourceFileUtil; import gov.cms.madie.models.common.ModelType; @@ -48,6 +49,7 @@ class ValidationControllerMvcTest implements ResourceFileUtil { @Autowired private MockMvc mockMvc; @Autowired FhirValidator qicoreNpmFhirValidator; @MockBean private ModelAwareFhirFactory validatorFactory; + @MockBean private AppConfigService appConfigService; private IParser r4Parser; @BeforeEach