Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cost of delay kpi cache changes #1892

Merged
merged 3 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public final class CommonConstant {
public static final String CACHE_BOARD_META_DATA_MAP = "boardMetaDataMap";
public static final String CACHE_PROJECT_CONFIG_MAP = "projectConfigMap";
public static final String CACHE_PROJECT_TOOL_CONFIG_MAP = "projectToolConfigMap";
public static final String CACHE_PROJECT_KPI_DATA = "project_kpi_data_cache";

public static final String PARAM1 = "param1";
public static final String PARAM2 = "param2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
import java.util.List;
import java.util.Map;

import com.publicissapient.kpidashboard.apis.constant.Constant;
import com.publicissapient.kpidashboard.apis.model.KpiRequest;
import com.publicissapient.kpidashboard.common.model.application.Build;
import org.bson.types.ObjectId;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

/**
Expand Down Expand Up @@ -133,4 +135,7 @@ Map<String, Object> fetchScopeChurnData(KpiRequest kpiRequest, ObjectId basicPro
*/
Map<String, Object> fetchCommitmentReliabilityData(KpiRequest kpiRequest, ObjectId basicProjectConfigId,
List<String> sprintList, String kpiId);

@Cacheable(value = Constant.CACHE_PROJECT_KPI_DATA, key = "#basicProjectConfigId.toString().concat('_').concat(#kpiId)")
Map<String, Object> fetchCostOfDelayData(ObjectId basicProjectConfigId, String kpiId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ public List<String> getKpiBasedOnSource(String source) {
Map<String, List<String>> kpiMap = new HashMap<>();
kpiMap.put(KPISource.JIRA.name(),
List.of(KPICode.ISSUE_COUNT.getKpiId(), KPICode.COMMITMENT_RELIABILITY.getKpiId(),
KPICode.SPRINT_CAPACITY_UTILIZATION.getKpiId(), KPICode.SCOPE_CHURN.getKpiId()));
KPICode.SPRINT_CAPACITY_UTILIZATION.getKpiId(), KPICode.SCOPE_CHURN.getKpiId(),
KPICode.COST_OF_DELAY.getKpiId()));
kpiMap.put(KPISource.JIRAKANBAN.name(), new ArrayList<>());
kpiMap.put(KPISource.SONAR.name(), new ArrayList<>());
kpiMap.put(KPISource.SONARKANBAN.name(), new ArrayList<>());
Expand Down Expand Up @@ -158,4 +159,11 @@ public Map<String, Object> fetchCommitmentReliabilityData(KpiRequest kpiRequest,
return kpiDataProvider.fetchCommitmentReliabilityData(kpiRequest, basicProjectConfigId, sprintList);
}

@Cacheable(value = Constant.CACHE_PROJECT_KPI_DATA, key = "#basicProjectConfigId.toString().concat('_').concat(#kpiId)")
@Override
public Map<String, Object> fetchCostOfDelayData(ObjectId basicProjectConfigId, String kpiId) {
log.info("Fetching Cost of Delay KPI Data for Project {} and KPI {}", basicProjectConfigId.toString(), kpiId);
return kpiDataProvider.fetchCostOfDelayData(basicProjectConfigId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import com.publicissapient.kpidashboard.apis.enums.KPISource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.bson.types.ObjectId;
Expand Down Expand Up @@ -47,6 +46,9 @@ public class KpiDataProvider {
public static final String SPRINT_DETAILS = "sprintDetails";
public static final String SCOPE_CHANGE_ISSUE_HISTORY = "scopeChangeIssuesHistories";
private static final String PROJECT_WISE_TOTAL_ISSUE = "projectWiseTotalIssues";
private static final String COD_DATA = "costOfDelayData";
private static final String COD_DATA_HISTORY = "costOfDelayDataHistory";
private static final String FIELD_MAPPING = "fieldMapping";

@Autowired
private ConfigHelperService configHelperService;
Expand Down Expand Up @@ -369,4 +371,40 @@ public Map<String, Object> fetchCommitmentReliabilityData(KpiRequest kpiRequest,
}
return resultListMap;
}

public Map<String, Object> fetchCostOfDelayData(ObjectId basicProjectConfigId) {
Map<String, Object> resultListMap = new HashMap<>();
Map<String, Map<String, Object>> uniqueProjectMap = new HashMap<>();
Map<ObjectId, FieldMapping> fieldMappingMap = configHelperService.getFieldMappingMap();
Map<String, List<String>> closedStatusMap = new HashMap<>();
Map<String, Object> mapOfFilters = new LinkedHashMap<>();
List<String> basicProjectConfigIds = List.of(basicProjectConfigId.toString());

FieldMapping fieldMapping = fieldMappingMap.get(basicProjectConfigId);
List<String> jiraCloseStatuses = new ArrayList<>();
if(CollectionUtils.isNotEmpty(fieldMapping.getClosedIssueStatusToConsiderKpi113())) {
jiraCloseStatuses.addAll(fieldMapping.getClosedIssueStatusToConsiderKpi113());
}
List<String> jiraIssueType = new ArrayList<>();
if(CollectionUtils.isNotEmpty(fieldMapping.getIssueTypesToConsiderKpi113())) {
jiraIssueType.addAll(fieldMapping.getIssueTypesToConsiderKpi113());
}
closedStatusMap.put(basicProjectConfigId.toString(),
jiraCloseStatuses.stream().map(String::toLowerCase).toList());
mapOfFilters.put(JiraFeature.ISSUE_TYPE.getFieldValueInFeature(),jiraIssueType);
mapOfFilters.put(JiraFeature.STATUS.getFieldValueInFeature(), jiraCloseStatuses);
mapOfFilters.put(JiraFeature.BASIC_PROJECT_CONFIG_ID.getFieldValueInFeature(),
basicProjectConfigIds.stream().distinct().toList());
uniqueProjectMap.put(basicProjectConfigId.toString(), mapOfFilters);

List<JiraIssue> codList = jiraIssueRepository.findIssuesByFilterAndProjectMapFilter(new HashMap<>(), uniqueProjectMap);
List<JiraIssueCustomHistory> codHistory = jiraIssueCustomHistoryRepository
.findByStoryIDInAndBasicProjectConfigIdIn(
codList.stream().map(JiraIssue::getNumber).toList(), new ArrayList<>(uniqueProjectMap.keySet()));
resultListMap.put(COD_DATA, codList);
resultListMap.put(COD_DATA_HISTORY, codHistory);
resultListMap.put(FIELD_MAPPING, closedStatusMap);

return resultListMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.requestMatchers("/actuator**").permitAll().requestMatchers("/forgotPassword").permitAll()
.requestMatchers("/validateEmailToken**").permitAll().requestMatchers("/resetPassword").permitAll()
.requestMatchers("/cache/clearAllCache").permitAll()
.requestMatchers(HttpMethod.GET, "/cache/clearCache/**").permitAll()
.requestMatchers(HttpMethod.GET, "/cache/**").permitAll()
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers(HttpMethod.GET, "/analytics/switch").permitAll()
.requestMatchers("/stringShortener/shorten").permitAll()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import com.publicissapient.kpidashboard.apis.appsetting.service.ConfigHelperService;
import com.publicissapient.kpidashboard.apis.common.service.CacheService;
import com.publicissapient.kpidashboard.apis.common.service.KpiDataCacheService;
import com.publicissapient.kpidashboard.apis.filter.service.FilterHelperService;
import com.publicissapient.kpidashboard.common.model.jira.JiraIssueCustomHistory;
import com.publicissapient.kpidashboard.common.repository.jira.JiraIssueCustomHistoryRepository;
Expand Down Expand Up @@ -72,18 +73,15 @@ public class CostOfDelayServiceImpl extends JiraKPIService<Double, List<Object>,
private static final String COD_DATA = "costOfDelayData";
private static final String COD_DATA_HISTORY = "costOfDelayDataHistory";
private static final String FIELD_MAPPING = "fieldMapping";
@Autowired
private JiraIssueRepository jiraIssueRepository;

@Autowired
private CustomApiConfig customApiConfig;
@Autowired
private FilterHelperService flterHelperService;
@Autowired
private CacheService cacheService;
@Autowired
private JiraIssueCustomHistoryRepository jiraIssueCustomHistoryRepository;
@Autowired
private ConfigHelperService configHelperService;
private KpiDataCacheService kpiDataCacheService;

@Override
public Double calculateKPIMetrics(Map<String, Object> subCategoryMap) {
Expand Down Expand Up @@ -132,39 +130,24 @@ public Map<String, Object> fetchKPIDataFromDb(List<Node> leafNodeList, String st
KpiRequest kpiRequest) {

Map<String, Object> resultListMap = new HashMap<>();
Map<String, Map<String, Object>> uniqueProjectMap = new HashMap<>();
Map<ObjectId, FieldMapping> fieldMappingMap = configHelperService.getFieldMappingMap();
Map<String, List<String>> closedStatusMap = new HashMap<>();
List<ObjectId> basicProjectConfigIds = new ArrayList<>();
if (CollectionUtils.isNotEmpty(leafNodeList)) {

leafNodeList.forEach(leaf -> {
List<String> basicProjectConfigIds = new ArrayList<>();
Map<String, Object> mapOfFilters = new LinkedHashMap<>();
ObjectId basicProjectConfigId = leaf.getProjectFilter().getBasicProjectConfigId();
basicProjectConfigIds.add(leaf.getProjectFilter().getBasicProjectConfigId().toString());
FieldMapping fieldMapping = fieldMappingMap.get(basicProjectConfigId);
List<String> jiraCloseStatuses = new ArrayList<>();
if(CollectionUtils.isNotEmpty(fieldMapping.getClosedIssueStatusToConsiderKpi113())) {
jiraCloseStatuses.addAll(fieldMapping.getClosedIssueStatusToConsiderKpi113());
}
List<String> jiraIssueType = new ArrayList<>();
if(CollectionUtils.isNotEmpty(fieldMapping.getIssueTypesToConsiderKpi113())) {
jiraIssueType.addAll(fieldMapping.getIssueTypesToConsiderKpi113());
}
closedStatusMap.put(basicProjectConfigId.toString(),
jiraCloseStatuses.stream().map(String::toLowerCase).toList());
mapOfFilters.put(JiraFeature.ISSUE_TYPE.getFieldValueInFeature(),jiraIssueType);
mapOfFilters.put(JiraFeature.STATUS.getFieldValueInFeature(), jiraCloseStatuses);
mapOfFilters.put(JiraFeature.BASIC_PROJECT_CONFIG_ID.getFieldValueInFeature(),
basicProjectConfigIds.stream().distinct().toList());
uniqueProjectMap.put(basicProjectConfigId.toString(), mapOfFilters);
basicProjectConfigIds.add(basicProjectConfigId);
});

}
List<JiraIssue> codList = jiraIssueRepository.findIssuesByFilterAndProjectMapFilter(new HashMap<>(), uniqueProjectMap);
List<JiraIssueCustomHistory> codHistory = jiraIssueCustomHistoryRepository
.findByStoryIDInAndBasicProjectConfigIdIn(
codList.stream().map(JiraIssue::getNumber).toList(), new ArrayList<>(uniqueProjectMap.keySet()));
List<JiraIssue> codList = new ArrayList<>();
List<JiraIssueCustomHistory> codHistory = new ArrayList<>();
Map<String, List<String>> closedStatusMap = new HashMap<>();
basicProjectConfigIds.forEach(basicProjectConfigId -> {
Map<String, Object> result = kpiDataCacheService.fetchCostOfDelayData(basicProjectConfigId,
KPICode.COST_OF_DELAY.getKpiId());
codList.addAll((List<JiraIssue>) result.get(COD_DATA));
codHistory.addAll((List<JiraIssueCustomHistory>) result.get(COD_DATA_HISTORY));
closedStatusMap.putAll((Map<String, List<String>>) result.get(FIELD_MAPPING));
});
resultListMap.put(COD_DATA, codList);
resultListMap.put(COD_DATA_HISTORY, codHistory);
resultListMap.put(FIELD_MAPPING, closedStatusMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.publicissapient.kpidashboard.common.model.application.FieldMapping;
import com.publicissapient.kpidashboard.common.model.application.ProjectBasicConfig;
import com.publicissapient.kpidashboard.common.model.jira.JiraIssue;
import com.publicissapient.kpidashboard.common.model.jira.JiraIssueCustomHistory;
import com.publicissapient.kpidashboard.common.model.jira.SprintDetails;
import com.publicissapient.kpidashboard.common.repository.application.BuildRepository;
import com.publicissapient.kpidashboard.common.repository.excel.CapacityKpiDataRepository;
Expand All @@ -33,6 +34,7 @@
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

import java.time.LocalDateTime;
import java.util.*;

import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -231,4 +233,44 @@ public void testFetchCommitmentReliabilityData() {
assertNotNull(result);
}

@Test
public void testFetchCostOfDelayData() {
JiraIssueDataFactory jiraIssueDataFactory = JiraIssueDataFactory.newInstance();
JiraIssueHistoryDataFactory jiraIssueHistoryDataFactory = JiraIssueHistoryDataFactory.newInstance();
List<JiraIssue> codList = jiraIssueDataFactory.getJiraIssues();
List<JiraIssueCustomHistory> codHistoryList = jiraIssueHistoryDataFactory.getJiraIssueCustomHistory();
codHistoryList.stream().map(JiraIssueCustomHistory::getStatusUpdationLog).forEach(f -> {
f.forEach(g -> g.setUpdatedOn(LocalDateTime.now().minusDays(2)));
});

when(jiraIssueRepository.findIssuesByFilterAndProjectMapFilter(Mockito.any(), Mockito.any())).thenReturn(codList);
when(jiraIssueCustomHistoryRepository.findByStoryIDInAndBasicProjectConfigIdIn(Mockito.any(), Mockito.any()))
.thenReturn(codHistoryList);

Map<String, Object> result = kpiDataProvider.fetchCostOfDelayData(new ObjectId("6335363749794a18e8a4479b"));
assertThat("Data : ", result.size(), equalTo(3));
}

@Test
public void testFetchCostOfDelayData2() {
JiraIssueDataFactory jiraIssueDataFactory = JiraIssueDataFactory.newInstance();
JiraIssueHistoryDataFactory jiraIssueHistoryDataFactory = JiraIssueHistoryDataFactory.newInstance();
List<JiraIssue> codList = jiraIssueDataFactory.getJiraIssues();
List<JiraIssueCustomHistory> codHistoryList = jiraIssueHistoryDataFactory.getJiraIssueCustomHistory();
codHistoryList.stream().map(JiraIssueCustomHistory::getStatusUpdationLog).forEach(f -> {
f.forEach(g -> g.setUpdatedOn(LocalDateTime.now().minusDays(2)));
});
fieldMappingMap.forEach((key, value) -> {
value.setClosedIssueStatusToConsiderKpi113(List.of("Closed"));
value.setIssueTypesToConsiderKpi113(List.of("Story"));
});

when(jiraIssueRepository.findIssuesByFilterAndProjectMapFilter(Mockito.any(), Mockito.any())).thenReturn(codList);
when(jiraIssueCustomHistoryRepository.findByStoryIDInAndBasicProjectConfigIdIn(Mockito.any(), Mockito.any()))
.thenReturn(codHistoryList);

Map<String, Object> result = kpiDataProvider.fetchCostOfDelayData(new ObjectId("6335363749794a18e8a4479b"));
assertThat("Data : ", result.size(), equalTo(3));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,10 @@ public void testFetchCommitmentReliabilityData() {
assertNotNull(kpiDataCacheService.fetchCommitmentReliabilityData(new KpiRequest(), new ObjectId(), new ArrayList<>(), "kpi1"));
}

@Test
public void testFetchCostOfDelayData() {
when(kpiDataProvider.fetchCostOfDelayData(any())).thenReturn(new HashMap<>());
assertNotNull(kpiDataCacheService.fetchCostOfDelayData(new ObjectId(), KPICode.COST_OF_DELAY.getKpiId()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.List;
import java.util.Map;

import com.publicissapient.kpidashboard.apis.common.service.KpiDataCacheService;
import com.publicissapient.kpidashboard.apis.data.JiraIssueHistoryDataFactory;
import com.publicissapient.kpidashboard.apis.filter.service.FilterHelperService;
import com.publicissapient.kpidashboard.common.model.jira.JiraIssueCustomHistory;
Expand Down Expand Up @@ -76,8 +77,6 @@ public class CostOfDelayServiceImplTest {
public Map<String, ProjectBasicConfig> projectConfigMap = new HashMap<>();
public Map<ObjectId, FieldMapping> fieldMappingMap = new HashMap<>();
@Mock
JiraIssueRepository jiraIssueRepository;
@Mock
CacheService cacheService;
@Mock
ConfigHelperService configHelperService;
Expand All @@ -94,14 +93,19 @@ public class CostOfDelayServiceImplTest {
@Mock
FilterHelperService filterHelperService;
@Mock
JiraIssueCustomHistoryRepository jiraIssueCustomHistoryRepository;
private KpiDataCacheService kpiDataCacheService;

private Map<String, Object> filterLevelMap;
private List<JiraIssue> codList = new ArrayList<>();
private List<JiraIssueCustomHistory> codHistoryList = new ArrayList<>();
private Map<String, String> kpiWiseAggregation = new HashMap<>();
private KpiRequest kpiRequest;
private List<AccountHierarchyData> accountHierarchyDataList = new ArrayList<>();

private static final String COD_DATA = "costOfDelayData";
private static final String COD_DATA_HISTORY = "costOfDelayDataHistory";
private static final String FIELD_MAPPING = "fieldMapping";

@Before
public void setup() {
KpiRequestFactory kpiRequestFactory = KpiRequestFactory.newInstance("");
Expand Down Expand Up @@ -141,7 +145,6 @@ public void setup() {

@After
public void cleanup() {
jiraIssueRepository.deleteAll();

}

Expand All @@ -154,6 +157,12 @@ public void testFetchKPIDataFromDbData() throws ApplicationException {
String startDate = leafNodeList.get(0).getSprintFilter().getStartDate();
String endDate = leafNodeList.get(leafNodeList.size() - 1).getSprintFilter().getEndDate();

Map<String, Object> resultListMap = new HashMap<>();
resultListMap.put(COD_DATA, codList);
resultListMap.put(COD_DATA_HISTORY, codHistoryList);
resultListMap.put(FIELD_MAPPING, new HashMap<>());
when(kpiDataCacheService.fetchCostOfDelayData(Mockito.any(), Mockito.any())).thenReturn(resultListMap);

Map<String, Object> dataList = costOfDelayServiceImpl.fetchKPIDataFromDb(leafNodeList, startDate, endDate,
kpiRequest);
assertThat("Total Release : ", dataList.size(), equalTo(3));
Expand All @@ -164,14 +173,19 @@ public void testGetKPIList() throws ApplicationException {
TreeAggregatorDetail treeAggregatorDetail = KPIHelperUtil.getTreeLeafNodesGroupedByFilter(kpiRequest,
accountHierarchyDataList, new ArrayList<>(), "hierarchyLevelOne", 5);

when(jiraIssueRepository.findIssuesByFilterAndProjectMapFilter(Mockito.any(), Mockito.any())).thenReturn(codList);
String kpiRequestTrackerId = "Excel-Jira-5be544de025de212549176a9";
when(cacheService.getFromApplicationCache(Constant.KPI_REQUEST_TRACKER_ID_KEY + KPISource.JIRA.name()))
.thenReturn(kpiRequestTrackerId);
when(customApiSetting.getJiraXaxisMonthCount()).thenReturn(5);
when(costOfDelayServiceImpl.getRequestTrackerId()).thenReturn(kpiRequestTrackerId);
when(jiraIssueCustomHistoryRepository.findByStoryIDInAndBasicProjectConfigIdIn(Mockito.any(), Mockito.any()))
.thenReturn(codHistoryList);

Map<String, List<String>> closedStatusMap = new HashMap<>();
closedStatusMap.put("6335363749794a18e8a4479b", List.of("closed"));
Map<String, Object> resultListMap = new HashMap<>();
resultListMap.put(COD_DATA, codList);
resultListMap.put(COD_DATA_HISTORY, codHistoryList);
resultListMap.put(FIELD_MAPPING, closedStatusMap);
when(kpiDataCacheService.fetchCostOfDelayData(Mockito.any(), Mockito.any())).thenReturn(resultListMap);

try {
KpiElement kpiElement = costOfDelayServiceImpl.getKpiData(kpiRequest, kpiRequest.getKpiList().get(0),
Expand All @@ -193,6 +207,15 @@ public void testGetStoryList() throws ApplicationException {
when(cacheService.getFromApplicationCache(Constant.KPI_REQUEST_TRACKER_ID_KEY + KPISource.JIRA.name()))
.thenReturn(kpiRequestTrackerId);
when(costOfDelayServiceImpl.getRequestTrackerId()).thenReturn(kpiRequestTrackerId);

Map<String, List<String>> closedStatusMap = new HashMap<>();
closedStatusMap.put("6335363749794a18e8a4479b", List.of("closed"));
Map<String, Object> resultListMap = new HashMap<>();
resultListMap.put(COD_DATA, codList);
resultListMap.put(COD_DATA_HISTORY, codHistoryList);
resultListMap.put(FIELD_MAPPING, closedStatusMap);
when(kpiDataCacheService.fetchCostOfDelayData(Mockito.any(), Mockito.any())).thenReturn(resultListMap);

try {
KpiElement kpiElement = costOfDelayServiceImpl.getKpiData(kpiRequest, kpiRequest.getKpiList().get(0),
treeAggregatorDetail);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ private boolean fetchIssueDetail(boolean executionStatus, List<ProjectBasicConfi
azureRestClientFactory.cacheRestClient(CommonConstant.CACHE_CLEAR_ENDPOINT,
CommonConstant.CACHE_PROJECT_TOOL_CONFIG);
azureRestClientFactory.cacheRestClient(CommonConstant.CACHE_CLEAR_ENDPOINT, CommonConstant.JIRA_KPI_CACHE);
azureRestClientFactory.cacheRestClient(CommonConstant.CACHE_CLEAR_SOURCE_ENDPOINT, CommonConstant.JIRA_KPI,
"");
azureRestClientFactory.cacheRestClient(CommonConstant.CACHE_CLEAR_ENDPOINT, CommonConstant.CACHE_PROJECT_KPI_DATA);
}
if (kanbanIssueCount.get() > 0) {
azureRestClientFactory.cacheRestClient(CommonConstant.CACHE_CLEAR_ENDPOINT,
Expand Down
Loading
Loading