diff --git a/.env b/.env index cda12081a..1e6578827 100644 --- a/.env +++ b/.env @@ -41,3 +41,6 @@ USE_SYNC_EXECUTOR= # Sets the last date that CPC+ files should be accepted by the converter. CPC_END_DATE= + +# If set, the CPC+ APIs are disabled. +NO_CPC_PLUS_API= diff --git a/rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v1/CpcFileControllerV1.java b/rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v1/CpcFileControllerV1.java index 9f9e9eb9d..edcde0b3b 100644 --- a/rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v1/CpcFileControllerV1.java +++ b/rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v1/CpcFileControllerV1.java @@ -3,8 +3,7 @@ import gov.cms.qpp.conversion.api.model.Constants; import gov.cms.qpp.conversion.api.model.UnprocessedCpcFileData; import gov.cms.qpp.conversion.api.services.CpcFileService; -import java.io.IOException; -import java.util.List; +import gov.cms.qpp.conversion.util.EnvironmentHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -18,6 +17,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import java.io.IOException; +import java.util.List; + /** * Controller to handle cpc file data */ @@ -37,9 +39,14 @@ public class CpcFileControllerV1 { */ @RequestMapping(method = RequestMethod.GET, value = "/unprocessed-files", headers = {"Accept=" + Constants.V1_API_ACCEPT}) - public ResponseEntity getUnprocessedCpcPlusFiles() throws IOException { + public ResponseEntity> getUnprocessedCpcPlusFiles() { API_LOG.info("CPC+ unprocessed files request received"); + if (blockCpcPlusApi()) { + API_LOG.info("CPC+ unprocessed files request blocked by feature flag"); + return new ResponseEntity<>(null, null, HttpStatus.FORBIDDEN); + } + List unprocessedCpcFileDataList = cpcFileService.getUnprocessedCpcPlusFiles(); API_LOG.info("CPC+ unprocessed files request succeeded"); @@ -63,6 +70,11 @@ public ResponseEntity getFileById(@PathVariable("fileId") S throws IOException { API_LOG.info("CPC+ file request received"); + if (blockCpcPlusApi()) { + API_LOG.info("CPC+ file request blocked by feature flag"); + return new ResponseEntity<>(null, null, HttpStatus.FORBIDDEN); + } + InputStreamResource content = cpcFileService.getFileById(fileId); API_LOG.info("CPC+ file request succeeded"); @@ -72,4 +84,13 @@ public ResponseEntity getFileById(@PathVariable("fileId") S return new ResponseEntity<>(content, httpHeaders, HttpStatus.OK); } + + /** + * Checks whether the the CPC+ APIs should not be allowed to execute. + * + * @return Whether the CPC+ APIs should be blocked. + */ + private boolean blockCpcPlusApi() { + return EnvironmentHelper.isPresent(Constants.NO_CPC_PLUS_API_ENV_VARIABLE); + } } diff --git a/rest-api/src/main/java/gov/cms/qpp/conversion/api/model/Constants.java b/rest-api/src/main/java/gov/cms/qpp/conversion/api/model/Constants.java index f9eabaa0c..eb9288492 100644 --- a/rest-api/src/main/java/gov/cms/qpp/conversion/api/model/Constants.java +++ b/rest-api/src/main/java/gov/cms/qpp/conversion/api/model/Constants.java @@ -12,6 +12,7 @@ public class Constants { public static final String SUBMISSION_API_TOKEN_ENV_VARIABLE = "SUBMISSION_API_TOKEN"; public static final String VALIDATION_URL_ENV_VARIABLE = "VALIDATION_URL"; public static final String USE_SYNC_EXECUTOR = "USE_SYNC_EXECUTOR"; + public static final String NO_CPC_PLUS_API_ENV_VARIABLE = "NO_CPC_PLUS_API"; public static final String V1_API_ACCEPT = "application/vnd.qpp.cms.gov.v1+json"; /** diff --git a/rest-api/src/test/java/gov/cms/qpp/conversion/api/controllers/v1/CpcFileControllerV1Test.java b/rest-api/src/test/java/gov/cms/qpp/conversion/api/controllers/v1/CpcFileControllerV1Test.java index b9849ff35..091210208 100644 --- a/rest-api/src/test/java/gov/cms/qpp/conversion/api/controllers/v1/CpcFileControllerV1Test.java +++ b/rest-api/src/test/java/gov/cms/qpp/conversion/api/controllers/v1/CpcFileControllerV1Test.java @@ -1,24 +1,28 @@ package gov.cms.qpp.conversion.api.controllers.v1; +import gov.cms.qpp.conversion.api.model.Constants; import gov.cms.qpp.conversion.api.model.Metadata; import gov.cms.qpp.conversion.api.model.UnprocessedCpcFileData; import gov.cms.qpp.conversion.api.services.CpcFileService; import gov.cms.qpp.test.MockitoExtension; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.springframework.core.io.InputStreamResource; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; @@ -40,11 +44,16 @@ void setUp() { expectedUnprocessedCpcFileDataList = createMockedUnprocessedDataList(); } + @AfterEach + void turnOffFeatureFlag() { + System.clearProperty(Constants.NO_CPC_PLUS_API_ENV_VARIABLE); + } + @Test - void testGetUnprocessedFileList() throws IOException { + void testGetUnprocessedFileList() { when(cpcFileService.getUnprocessedCpcPlusFiles()).thenReturn(expectedUnprocessedCpcFileDataList); - ResponseEntity qppResponse = cpcFileControllerV1.getUnprocessedCpcPlusFiles(); + ResponseEntity> qppResponse = cpcFileControllerV1.getUnprocessedCpcPlusFiles(); verify(cpcFileService).getUnprocessedCpcPlusFiles(); @@ -62,6 +71,26 @@ void testGetFileById() throws IOException { .isEqualTo("1234"); } + @Test + void testEndpoint1WithFeatureFlagDisabled() { + System.setProperty(Constants.NO_CPC_PLUS_API_ENV_VARIABLE, "trueOrWhatever"); + + ResponseEntity> cpcResponse = cpcFileControllerV1.getUnprocessedCpcPlusFiles(); + + assertThat(cpcResponse.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); + assertThat(cpcResponse.getBody()).isNull(); + } + + @Test + void testEndpoint2WithFeatureFlagDisabled() throws IOException { + System.setProperty(Constants.NO_CPC_PLUS_API_ENV_VARIABLE, "trueOrWhatever"); + + ResponseEntity cpcResponse = cpcFileControllerV1.getFileById("meep"); + + assertThat(cpcResponse.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); + assertThat(cpcResponse.getBody()).isNull(); + } + List createMockedUnprocessedDataList() { Metadata metadata = new Metadata(); metadata.setSubmissionLocator("Test");