Skip to content

Commit

Permalink
Merge pull request #230 from MeasureAuthoringTool/feature/MAT-6470
Browse files Browse the repository at this point in the history
MAT-6470 Added app config to fetch feature flags
  • Loading branch information
RohitKandimalla authored Jul 24, 2024
2 parents bf66527 + 92c6311 commit 5794f09
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package gov.cms.madie.madiefhirservice.config;

import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Getter
@Configuration
public class AppConfigServiceConfig {

@Value("${madie.service-config.json-url}")
private String serviceConfigJsonUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package gov.cms.madie.madiefhirservice.dto;

/** Feature flags relevant to the measure-service */
public enum MadieFeatureFlag {
QiCore_STU4_UPDATES("qiCoreStu4Updates");

private final String flag;

MadieFeatureFlag(String flag) {
this.flag = flag;
}

@Override
public String toString() {
return this.flag;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package gov.cms.madie.madiefhirservice.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Map;

@Data
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
public class ServiceConfig {
private String madieVersion;
private Map<String, Boolean> features;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package gov.cms.madie.madiefhirservice.services;

import gov.cms.madie.madiefhirservice.config.AppConfigServiceConfig;
import gov.cms.madie.madiefhirservice.dto.MadieFeatureFlag;
import gov.cms.madie.madiefhirservice.dto.ServiceConfig;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@Slf4j
@Service
public class AppConfigService {
private final AppConfigServiceConfig appConfigServiceConfig;
private final RestTemplate appConfigRestTemplate;
private Map<String, Boolean> featureFlags;

@Autowired
public AppConfigService(
RestTemplate appConfigRestTemplate, AppConfigServiceConfig appConfigServiceConfig) {
this.appConfigRestTemplate = appConfigRestTemplate;
this.appConfigServiceConfig = appConfigServiceConfig;
}

@PostConstruct
@Scheduled(cron = "0 */5 * * * *")
public void refreshAppConfig() {
try {
ServiceConfig serviceConfig =
appConfigRestTemplate.getForObject(
appConfigServiceConfig.getServiceConfigJsonUrl(), ServiceConfig.class);
log.info("Initializing measure-service with serviceConfig: {}", serviceConfig);
featureFlags = serviceConfig.getFeatures();
} catch (Exception ex) {
log.error("An error occurred while initializing feature flags from serviceConfig.json!", ex);
}
}

public boolean isFlagEnabled(MadieFeatureFlag flag) {
return featureFlags.getOrDefault(flag.toString(), false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import gov.cms.madie.madiefhirservice.dto.MadieFeatureFlag;
import gov.cms.madie.madiefhirservice.constants.ValueConstants;
import gov.cms.madie.madiefhirservice.utils.FhirResourceHelpers;
import gov.cms.madie.models.common.Organization;
Expand Down Expand Up @@ -32,7 +32,6 @@
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import gov.cms.madie.madiefhirservice.constants.UriConstants;
Expand All @@ -44,9 +43,7 @@
@RequiredArgsConstructor
public class MeasureTranslatorService {
public static final String UNKNOWN = "UNKNOWN";

@Value("${madie.useMultipleStratAssociation}")
private boolean useMultipleStratAssociation;
private final AppConfigService appConfigService;

public org.hl7.fhir.r4.model.Measure createFhirMeasureForMadieMeasure(Measure madieMeasure) {
Organization steward = madieMeasure.getMeasureMetaData().getSteward();
Expand Down Expand Up @@ -389,7 +386,7 @@ private List<MeasureGroupStratifierComponent> buildStratifications(Group madieGr
.map(
strat -> {
List<PopulationType> associations = strat.getAssociations();
if (!useMultipleStratAssociation) {
if (!appConfigService.isFlagEnabled(MadieFeatureFlag.QiCore_STU4_UPDATES)) {
associations = new ArrayList<>();
if (strat.getAssociation() != null) {
associations.add(strat.getAssociation());
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ madie:
url: ${MADIE_URL:https://madie.cms.gov}
resource:
url: https://madie.cms.gov
useMultipleStratAssociation: ${USE_MULTIPLE_STRAT_ASSOCIATION:true}
service-config:
json-url: ${SERVICE_CONFIG_JSON_URL:http://localhost:9000/env-config/serviceConfig.json}

#springdoc:
# swagger-ui:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package gov.cms.madie.madiefhirservice.services;

import gov.cms.madie.madiefhirservice.config.AppConfigServiceConfig;
import gov.cms.madie.madiefhirservice.dto.MadieFeatureFlag;
import gov.cms.madie.madiefhirservice.dto.ServiceConfig;
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 org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class AppConfigServiceTest {
@Mock AppConfigServiceConfig appConfigServiceConfig;

@Mock RestTemplate appConfigRestTemplate;

@InjectMocks AppConfigService appConfigService;

@Test
public void isFlagEnabled() {
final Map<String, Boolean> flagMap =
Map.of(MadieFeatureFlag.QiCore_STU4_UPDATES.toString(), false);
ReflectionTestUtils.setField(appConfigService, "featureFlags", flagMap);
assertThat(appConfigService.isFlagEnabled(MadieFeatureFlag.QiCore_STU4_UPDATES), is(false));
}

@Test
public void isFlagEnabledMissingFlag() {
final Map<String, Boolean> flagMap = Map.of("NOT_REAL", true);
ReflectionTestUtils.setField(appConfigService, "featureFlags", flagMap);
assertThat(appConfigService.isFlagEnabled(MadieFeatureFlag.QiCore_STU4_UPDATES), is(false));
}

@Test
public void testFetchServicConfig() {
when(appConfigServiceConfig.getServiceConfigJsonUrl())
.thenReturn("test.aws/serviceConfig.json");

final Map<String, Boolean> flagMap =
Map.of(MadieFeatureFlag.QiCore_STU4_UPDATES.toString(), true);
when(appConfigRestTemplate.getForObject(anyString(), any(Class.class)))
.thenReturn(ServiceConfig.builder().features(flagMap).build());
appConfigService.refreshAppConfig();
assertThat(appConfigService.isFlagEnabled(MadieFeatureFlag.QiCore_STU4_UPDATES), is(true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;

import com.fasterxml.jackson.core.JsonProcessingException;
import gov.cms.madie.madiefhirservice.constants.UriConstants;
import gov.cms.madie.madiefhirservice.dto.MadieFeatureFlag;
import gov.cms.madie.madiefhirservice.utils.FhirResourceHelpers;
import gov.cms.madie.madiefhirservice.utils.MeasureTestHelper;
import gov.cms.madie.madiefhirservice.utils.ResourceFileUtil;
Expand Down Expand Up @@ -60,8 +62,8 @@
@ExtendWith(MockitoExtension.class)
public class MeasureTranslatorServiceTest implements ResourceFileUtil {
@InjectMocks private MeasureTranslatorService measureTranslatorService;

@Mock private FhirResourceHelpers fhirResourceHelpers;
@Mock private AppConfigService appConfigService;

private Measure madieMeasure;
private Measure madieRatioMeasure;
Expand Down Expand Up @@ -711,7 +713,7 @@ public void testBuildFhirPopulationGroupsWithStratifications() {

@Test
public void testBuildFhirPopulationGroupsWithStratificationsOfMultipleAssociations() {
ReflectionTestUtils.setField(measureTranslatorService, "useMultipleStratAssociation", true);
when(appConfigService.isFlagEnabled(MadieFeatureFlag.QiCore_STU4_UPDATES)).thenReturn(true);

Population ip1 = new Population();
ip1.setName(PopulationType.INITIAL_POPULATION);
Expand Down Expand Up @@ -782,7 +784,7 @@ public void testBuildFhirPopulationGroupsWithStratificationsOfMultipleAssociatio

@Test
public void testBuildFhirPopulationGroupsWithStratificationsOfNoAssociations() {
ReflectionTestUtils.setField(measureTranslatorService, "useMultipleStratAssociation", false);
when(appConfigService.isFlagEnabled(MadieFeatureFlag.QiCore_STU4_UPDATES)).thenReturn(false);

Population ip1 = new Population();
ip1.setName(PopulationType.INITIAL_POPULATION);
Expand Down

0 comments on commit 5794f09

Please sign in to comment.