Skip to content

Commit

Permalink
Merge pull request #28 from MeasureAuthoringTool/MAT-4754_saveElmJson…
Browse files Browse the repository at this point in the history
…4ImportedMeasure

Mat 4754 save elm json4 imported measure
  • Loading branch information
sb-cecilialiu authored Sep 29, 2022
2 parents 52c15c4 + 3132c49 commit 39aa64a
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gov.cms.mat.cql_elm_translation.config.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
Expand All @@ -9,15 +10,26 @@
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private static final String[] AUTH_WHITELIST = {
"/v3/api-docs/**", "/swagger/**", "/swagger-ui/**", "/actuator/**"
"/v3/api-docs/**",
"/swagger/**",
"/swagger-ui/**",
"/actuator/**",
"/mat/translator/cqlToElm/**"
// other public endpoints of your API may be appended to this array
};

private static final String[] CSRF_WHITELIST = {"/mat/translator/cqlToElm/**"};

@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.csrf()
.ignoringAntMatchers(CSRF_WHITELIST)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.PUT, "/mat/translator/cqlToElm/**")
.permitAll()
.antMatchers(AUTH_WHITELIST)
.permitAll()
.and()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package gov.cms.mat.cql_elm_translation.controllers;

import javax.servlet.http.HttpServletRequest;

import org.cqframework.cql.cql2elm.LibraryBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import gov.cms.mat.cql.dto.CqlConversionPayload;
import gov.cms.mat.cql_elm_translation.controllers.CqlConversionController.TranslatorOptionsRemover;
import gov.cms.mat.cql_elm_translation.data.RequestData;
import gov.cms.mat.cql_elm_translation.service.CqlConversionService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping(path = "/mat/translator")
@Tag(name = "Transfer-Translator", description = "API for translating MAT transferred measure CQL to ELM.")
@Slf4j
@RequiredArgsConstructor
public class MatMeasureController {

private final CqlConversionService cqlConversionService;

@PutMapping(path = "/cqlToElm", consumes = "text/plain", produces = "application/elm+json")
@PreAuthorize("#request.getHeader('api-key') == #apiKey")
public CqlConversionPayload cqlToElmJsonForMatTransferredMeasure(
@RequestBody String cqlData,
@RequestParam(required = false) LibraryBuilder.SignatureLevel signatures,
@RequestParam(defaultValue = "false") Boolean showWarnings,
@RequestParam(defaultValue = "true") Boolean annotations,
@RequestParam(defaultValue = "true") Boolean locators,
@RequestParam(value = "disable-list-demotion", defaultValue = "true")
Boolean disableListDemotion,
@RequestParam(value = "disable-list-promotion", defaultValue = "true")
Boolean disableListPromotion,
@RequestParam(value = "disable-method-invocation", defaultValue = "false")
Boolean disableMethodInvocation,
@RequestParam(value = "validate-units", defaultValue = "true") Boolean validateUnits,
@RequestParam(value = "result-types", defaultValue = "true") Boolean resultTypes,
HttpServletRequest request,
@Value("${lambda-api-key}") String apiKey) {

log.debug("Entering cqlToElmJsonForMatTransferredMeasure()");
String apikey = request.getHeader("api-key");
String harpid = request.getHeader("harp-id");
if (apikey == null || harpid == null || !apiKey.equals(request.getHeader("api-key"))) {
return CqlConversionPayload.builder()
.json("{\"errorExceptions\": [{\"Error\":\"UNAUTHORIZED\"}]}")
.build();
}

RequestData requestData =
RequestData.builder()
.cqlData(cqlData)
.showWarnings(showWarnings)
.signatures(signatures)
.annotations(annotations)
.locators(locators)
.disableListDemotion(disableListDemotion)
.disableListPromotion(disableListPromotion)
.disableMethodInvocation(disableMethodInvocation)
.validateUnits(validateUnits)
.resultTypes(resultTypes)
.build();

cqlConversionService.setUpLibrarySourceProvider(cqlData, apiKey.concat("-" + harpid));

CqlConversionPayload cqlConversionPayload =
cqlConversionService.processCqlDataWithErrors(requestData);
// Todo Do we need to remove empty annotations from library object, Also why are we removing
// translatorOptions from annotations, Could be MAT specific.
TranslatorOptionsRemover remover = new TranslatorOptionsRemover(cqlConversionPayload.getJson());
String cleanedJson = remover.clean();
cqlConversionPayload.setJson(cleanedJson);
return cqlConversionPayload;
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ okta:
oauth2:
issuer: ${OKTA_ISSUER:https://dev-18092578.okta.com/oauth2/default}
audience: ${OKTA_AUDIENCE:api://default}

lambda-api-key: ${LAMBDA_API_KEY:9202c9fa}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package gov.cms.mat.cql_elm_translation.controllers;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import javax.servlet.http.HttpServletRequest;

import org.cqframework.cql.cql2elm.CqlTranslator;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import gov.cms.mat.cql.dto.CqlConversionPayload;
import gov.cms.mat.cql_elm_translation.ResourceFileUtil;
import gov.cms.mat.cql_elm_translation.data.RequestData;
import gov.cms.mat.cql_elm_translation.service.CqlConversionService;

@ExtendWith(MockitoExtension.class)
public class MatMeasureControllerTest implements ResourceFileUtil {

@Mock private CqlConversionService cqlConversionService;
@Mock private CqlTranslator cqlTranslator;
@Mock private HttpServletRequest request;
@InjectMocks private MatMeasureController matMeasureController;

@Test
public void testCqlToElmJsonForMatTransferredMeasureSuccess() {
String cqlData = getData("/cv_populations.cql");
String result = getData("/cv_populations.json");
CqlConversionPayload payload = CqlConversionPayload.builder().json(result).build();
when(cqlConversionService.processCqlDataWithErrors(any(RequestData.class))).thenReturn(payload);

when(request.getHeader("api-key")).thenReturn("key4api");
when(request.getHeader("harp-id")).thenReturn("test");
CqlConversionPayload cqlConversionPayload =
matMeasureController.cqlToElmJsonForMatTransferredMeasure(
cqlData, null, true, true, true, true, true, true, true, true, request, "key4api");

assertEquals(result, cqlConversionPayload.getJson());
verify(cqlConversionService).processCqlDataWithErrors(any());
}

@Test
public void testCqlToElmJsonForMatTransferredMeasureFail() {
String cqlData = getData("/cv_populations.cql");
String result = getData("/cv_populations.json");

when(request.getHeader("api-key")).thenReturn("key4api");
when(request.getHeader("harp-id")).thenReturn("test2");
CqlConversionPayload cqlConversionPayload =
matMeasureController.cqlToElmJsonForMatTransferredMeasure(
cqlData, null, true, true, true, true, true, true, true, true, request, "test3");

assertNotEquals(result, cqlConversionPayload.getJson());
assertTrue(cqlConversionPayload.getJson().contains("UNAUTHORIZED"));
}
}

0 comments on commit 39aa64a

Please sign in to comment.