Skip to content

Commit ba47268

Browse files
MAT-8732 admin api to restart validations
1 parent 52960c8 commit ba47268

3 files changed

Lines changed: 198 additions & 4 deletions

File tree

src/main/java/cms/gov/madie/measure/resources/AdminController.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
public class AdminController {
4747
private final MeasureService measureService;
4848
private final TestCaseService testCaseService;
49+
private final TestCaseValidationService testCaseValidationService;
4950
private final MeasureSetService measureSetService;
5051
private final ActionLogService actionLogService;
5152
private final VersionService versionService;
@@ -123,6 +124,60 @@ public ResponseEntity<MeasureTestCaseValidationReportSummary> validateAllMeasure
123124
.build());
124125
}
125126

127+
// This endpoint is used to reset the validation queue for QI Core v6 measures test cases
128+
// that are in validating state
129+
@PutMapping("/measures/test-cases/restart-validation")
130+
@PreAuthorize("#request.getHeader('api-key') == #apiKey")
131+
public void resetTestCaseValidationQueue(
132+
HttpServletRequest request,
133+
@Value("${admin-api-key}") String apiKey,
134+
Principal principal,
135+
@RequestHeader("Authorization") String accessToken) {
136+
137+
log.info(
138+
"User [{}] - Starting admin task to place QI Core v6 testcases back on the validation queue",
139+
principal.getName());
140+
List<Measure> measureList =
141+
measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue());
142+
143+
if (CollectionUtils.isNotEmpty(measureList)) {
144+
measureList.forEach(
145+
measure -> {
146+
if (CollectionUtils.isNotEmpty(measure.getTestCases())) {
147+
measure
148+
.getTestCases()
149+
.forEach(
150+
testCase -> {
151+
if (TestCaseValidationStatus.VALIDATING
152+
.toString()
153+
.equalsIgnoreCase(testCase.getValidationStatus())) {
154+
testCase.setValidationStatus(TestCaseValidationStatus.PENDING.toString());
155+
// submit the test case after updating its status
156+
testCaseValidationService.submitOnSaveValidationTask(
157+
measure.getId(),
158+
testCase,
159+
accessToken,
160+
ModelType.valueOfName(measure.getModel()));
161+
} else if (TestCaseValidationStatus.PENDING
162+
.toString()
163+
.equalsIgnoreCase(testCase.getValidationStatus())) {
164+
// Submit test cases already in PENDING status
165+
testCaseValidationService.submitOnSaveValidationTask(
166+
measure.getId(),
167+
testCase,
168+
accessToken,
169+
ModelType.valueOfName(measure.getModel()));
170+
}
171+
});
172+
}
173+
});
174+
log.info(
175+
"User [{}] - Successfully placed QI Core v6 test cases back on the validation queue",
176+
principal.getName());
177+
measureRepository.saveAll(measureList);
178+
}
179+
}
180+
126181
@DeleteMapping("/measures/{id}")
127182
@PreAuthorize("#request.getHeader('api-key') == #apiKey")
128183
public ResponseEntity<Measure> permDeleteMeasure(

src/main/java/cms/gov/madie/measure/services/TestCaseValidationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public void populateValidationQueue() {
6666
// as "Pending" in the database.
6767
}
6868

69-
void submitOnSaveValidationTask(
69+
public void submitOnSaveValidationTask(
7070
String measureId, TestCase testCase, String accessToken, ModelType modelType) {
7171
UUID taskId = UUID.randomUUID();
7272
log.info(

src/test/java/cms/gov/madie/measure/resources/AdminControllerMvcTest.java

Lines changed: 142 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
import gov.cms.madie.models.access.RoleEnum;
1313
import gov.cms.madie.models.common.ModelType;
1414
import gov.cms.madie.models.common.Version;
15-
import gov.cms.madie.models.measure.Measure;
16-
import gov.cms.madie.models.measure.MeasureMetaData;
17-
import gov.cms.madie.models.measure.MeasureSet;
15+
import gov.cms.madie.models.measure.*;
1816
import org.junit.jupiter.api.Test;
1917
import org.springframework.beans.factory.annotation.Autowired;
2018
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
@@ -24,11 +22,13 @@
2422
import org.springframework.test.web.servlet.MockMvc;
2523
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
2624

25+
import java.util.Collections;
2726
import java.util.List;
2827
import java.util.Set;
2928

3029
import static org.hamcrest.Matchers.empty;
3130
import static org.hamcrest.Matchers.equalTo;
31+
import static org.junit.jupiter.api.Assertions.assertEquals;
3232
import static org.mockito.ArgumentMatchers.any;
3333
import static org.mockito.ArgumentMatchers.anyString;
3434
import static org.mockito.ArgumentMatchers.eq;
@@ -49,6 +49,7 @@ public class AdminControllerMvcTest {
4949
@MockitoBean private MeasureService measureService;
5050
@MockitoBean private MeasureSetService measureSetService;
5151
@MockitoBean private TestCaseService testCaseService;
52+
@MockitoBean private TestCaseValidationService testCaseValidationService;
5253
@MockitoBean private ActionLogService actionLogService;
5354
@MockitoBean private VersionService versionService;
5455

@@ -722,4 +723,142 @@ public void testAdminMeasureChangeVersionSuccessfully() throws Exception {
722723
.findAllByMeasureSetIdInAndActiveAndMeasureMetaDataDraft(List.of("ms-123"), true, true);
723724
verify(measureRepository, times(1)).findAllByMeasureSetIdAndActive("ms-123", true);
724725
}
726+
727+
@Test
728+
public void updateTestCaseValidationStatusProcessesValidatingTestCases() throws Exception {
729+
Measure measure =
730+
Measure.builder()
731+
.id("M1")
732+
.model(ModelType.QI_CORE_6_0_0.getValue())
733+
.testCases(
734+
List.of(
735+
TestCase.builder()
736+
.id("TC1")
737+
.validationStatus(TestCaseValidationStatus.VALIDATING.toString())
738+
.build()))
739+
.build();
740+
741+
when(measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue()))
742+
.thenReturn(List.of(measure));
743+
744+
mockMvc
745+
.perform(
746+
MockMvcRequestBuilders.put("/admin/measures/test-cases/restart-validation")
747+
.with(csrf())
748+
.with(user(TEST_USER_ID))
749+
.header(ADMIN_TEST_API_KEY_HEADER, ADMIN_TEST_API_KEY_HEADER_VALUE)
750+
.header("Authorization", "test-okta"))
751+
.andExpect(status().isOk());
752+
753+
verify(testCaseValidationService, times(1))
754+
.submitOnSaveValidationTask(
755+
eq("M1"), any(TestCase.class), eq("test-okta"), eq(ModelType.QI_CORE_6_0_0));
756+
assertEquals(
757+
TestCaseValidationStatus.PENDING.toString(),
758+
measure.getTestCases().get(0).getValidationStatus());
759+
}
760+
761+
@Test
762+
public void updateTestCaseValidationStatusProcessesPendingTestCases() throws Exception {
763+
Measure measure =
764+
Measure.builder()
765+
.id("M1")
766+
.model(ModelType.QI_CORE_6_0_0.getValue())
767+
.testCases(
768+
List.of(
769+
TestCase.builder()
770+
.id("TC1")
771+
.validationStatus(TestCaseValidationStatus.PENDING.toString())
772+
.build()))
773+
.build();
774+
775+
when(measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue()))
776+
.thenReturn(List.of(measure));
777+
778+
mockMvc
779+
.perform(
780+
MockMvcRequestBuilders.put("/admin/measures/test-cases/restart-validation")
781+
.with(csrf())
782+
.with(user(TEST_USER_ID))
783+
.header(ADMIN_TEST_API_KEY_HEADER, ADMIN_TEST_API_KEY_HEADER_VALUE)
784+
.header("Authorization", "test-okta"))
785+
.andExpect(status().isOk());
786+
787+
verify(testCaseValidationService, times(1))
788+
.submitOnSaveValidationTask(
789+
eq("M1"), any(TestCase.class), eq("test-okta"), eq(ModelType.QI_CORE_6_0_0));
790+
}
791+
792+
@Test
793+
public void updateTestCaseValidationStatusSkipsNonValidatingOrPendingTestCases()
794+
throws Exception {
795+
Measure measure =
796+
Measure.builder()
797+
.id("M1")
798+
.model(ModelType.QI_CORE_6_0_0.getValue())
799+
.testCases(
800+
List.of(
801+
TestCase.builder()
802+
.id("TC1")
803+
.validationStatus(TestCaseValidationStatus.INVALID.toString())
804+
.build()))
805+
.build();
806+
807+
when(measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue()))
808+
.thenReturn(List.of(measure));
809+
810+
mockMvc
811+
.perform(
812+
MockMvcRequestBuilders.put("/admin/measures/test-cases/restart-validation")
813+
.with(csrf())
814+
.with(user(TEST_USER_ID))
815+
.header(ADMIN_TEST_API_KEY_HEADER, ADMIN_TEST_API_KEY_HEADER_VALUE)
816+
.header("Authorization", "test-okta"))
817+
.andExpect(status().isOk());
818+
819+
verify(testCaseValidationService, never())
820+
.submitOnSaveValidationTask(
821+
anyString(), any(TestCase.class), anyString(), any(ModelType.class));
822+
}
823+
824+
@Test
825+
public void updateTestCaseValidationStatusHandlesEmptyMeasureList() throws Exception {
826+
when(measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue()))
827+
.thenReturn(Collections.emptyList());
828+
829+
mockMvc
830+
.perform(
831+
MockMvcRequestBuilders.put("/admin/measures/test-cases/restart-validation")
832+
.with(csrf())
833+
.with(user(TEST_USER_ID))
834+
.header(ADMIN_TEST_API_KEY_HEADER, ADMIN_TEST_API_KEY_HEADER_VALUE)
835+
.header("Authorization", "test-okta"))
836+
.andExpect(status().isOk());
837+
838+
verifyNoInteractions(testCaseValidationService);
839+
}
840+
841+
@Test
842+
public void updateTestCaseValidationStatusHandlesMeasuresWithoutTestCases() throws Exception {
843+
Measure measure =
844+
Measure.builder()
845+
.id("M1")
846+
.model(ModelType.QI_CORE_6_0_0.getValue())
847+
.testCases(Collections.emptyList())
848+
.build();
849+
850+
when(measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue()))
851+
.thenReturn(List.of(measure));
852+
853+
mockMvc
854+
.perform(
855+
MockMvcRequestBuilders.put("/admin/measures/test-cases/restart-validation")
856+
.with(csrf())
857+
.with(user(TEST_USER_ID))
858+
.header(ADMIN_TEST_API_KEY_HEADER, ADMIN_TEST_API_KEY_HEADER_VALUE)
859+
.header("Authorization", "test-okta"))
860+
.andExpect(status().isOk());
861+
862+
verifyNoInteractions(testCaseValidationService);
863+
}
725864
}

0 commit comments

Comments
 (0)