Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ public class RallyProcessorConfig {
@Value("${kafka.mailtopic}")
private String kafkaMailTopic;

public List<String> getDomainNames() {
return domainNames;
}

public void setDomainNames(List<String> domainNames) {
this.domainNames = domainNames;
}
@Value("${rally.userstory.baseurl}")
private String rallyUserStoryBaseUrl;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,21 @@
package com.publicissapient.kpidashboard.rally.listener;

import com.publicissapient.kpidashboard.common.constant.CommonConstant;
import com.publicissapient.kpidashboard.common.model.ProcessorExecutionTraceLog;
import com.publicissapient.kpidashboard.common.model.application.FieldMapping;
import com.publicissapient.kpidashboard.common.model.application.ProjectBasicConfig;
import com.publicissapient.kpidashboard.common.repository.application.FieldMappingRepository;
import com.publicissapient.kpidashboard.common.repository.application.ProjectBasicConfigRepository;
import com.publicissapient.kpidashboard.common.repository.tracelog.ProcessorExecutionTraceLogRepository;
import com.publicissapient.kpidashboard.rally.cache.RallyProcessorCacheEvictor;
import com.publicissapient.kpidashboard.rally.config.FetchProjectConfiguration;
import com.publicissapient.kpidashboard.rally.config.RallyProcessorConfig;
import com.publicissapient.kpidashboard.rally.constant.RallyConstants;
import com.publicissapient.kpidashboard.rally.service.NotificationHandler;
import com.publicissapient.kpidashboard.rally.service.OngoingExecutionsService;
import com.publicissapient.kpidashboard.rally.service.ProjectHierarchySyncService;
import com.publicissapient.kpidashboard.rally.service.RallyCommonService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.bson.types.ObjectId;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
Expand All @@ -43,6 +44,9 @@
import org.springframework.stereotype.Component;

import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static com.publicissapient.kpidashboard.rally.helper.RallyHelper.convertDateToCustomFormat;
import static com.publicissapient.kpidashboard.rally.util.RallyProcessorUtil.generateLogMessage;
Expand All @@ -55,6 +59,14 @@
@JobScope
public class JobListenerScrum implements JobExecutionListener {

/**
* Enum to represent the execution status of a job
*/
private enum ExecutionStatus {
SUCCESS,
FAILURE
}

@Autowired
private NotificationHandler handler;

Expand All @@ -79,8 +91,12 @@ public class JobListenerScrum implements JobExecutionListener {


@Autowired
@Getter
private ProjectHierarchySyncService projectHierarchySyncService;

@Autowired
private ProcessorExecutionTraceLogRepository processorExecutionTraceLogRepo;


@Override
public void beforeJob(JobExecution jobExecution) {
Expand Down Expand Up @@ -118,9 +134,12 @@ public void afterJob(JobExecution jobExecution) {
break;
}
}
setExecutionInfoInTraceLog(ExecutionStatus.FAILURE, stepFaliureException);
final String failureReasonMsg = generateLogMessage(stepFaliureException);
sendNotification(failureReasonMsg, RallyConstants.ERROR_NOTIFICATION_SUBJECT_KEY,
RallyConstants.ERROR_MAIL_TEMPLATE_KEY);
} else {
setExecutionInfoInTraceLog(ExecutionStatus.SUCCESS, null);
}
} catch (Exception e) {
log.error("An Exception has occured in scrum jobListener", e);
Expand Down Expand Up @@ -150,4 +169,21 @@ private static String getProjectName(ProjectBasicConfig projectBasicConfig) {
return projectBasicConfig == null ? "" : projectBasicConfig.getProjectName();
}

private void setExecutionInfoInTraceLog(ExecutionStatus executionStatus, Throwable stepFailureException) {
List<ProcessorExecutionTraceLog> procExecTraceLogs = processorExecutionTraceLogRepo
.findByProcessorNameAndBasicProjectConfigIdIn(RallyConstants.RALLY, Collections.singletonList(projectId));
if (CollectionUtils.isNotEmpty(procExecTraceLogs)) {
for (ProcessorExecutionTraceLog processorExecutionTraceLog : procExecTraceLogs) {
processorExecutionTraceLog.setExecutionEndedAt(System.currentTimeMillis());
processorExecutionTraceLog.setExecutionSuccess(executionStatus == ExecutionStatus.SUCCESS);
if (stepFailureException != null && processorExecutionTraceLog.isProgressStats()) {
processorExecutionTraceLog.setErrorMessage(generateLogMessage(stepFailureException));
processorExecutionTraceLog.setFailureLog(stepFailureException.getMessage());
}
}
processorExecutionTraceLogRepo.saveAll(procExecTraceLogs);
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ private void processProject(Map.Entry<String, List<JiraIssue>> entry, StepContex
List<ProcessorExecutionTraceLog> processorExecutionToSave) {
String basicProjectConfigId = entry.getKey();
List<ProcessorExecutionTraceLog> procTraceLogList = processorExecutionTraceLogRepo
.findByProcessorNameAndBasicProjectConfigIdIn(ProcessorConstants.JIRA,
.findByProcessorNameAndBasicProjectConfigIdIn(ProcessorConstants.RALLY,
Collections.singletonList(basicProjectConfigId));
ProcessorExecutionTraceLog progressStatsTraceLog = procTraceLogList.stream()
.filter(ProcessorExecutionTraceLog::isProgressStats).findFirst().orElse(new ProcessorExecutionTraceLog());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
******************************************************************************/
package com.publicissapient.kpidashboard.rally.processor;

import com.atlassian.jira.rest.client.api.domain.Issue;
import com.publicissapient.kpidashboard.common.model.jira.JiraHistoryChangeLog;
import com.publicissapient.kpidashboard.common.util.DateUtil;
import com.publicissapient.kpidashboard.rally.constant.RallyConstants;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.publicissapient.kpidashboard.common.model.application.FieldMapping;
import com.publicissapient.kpidashboard.common.model.jira.JiraIssue;
import com.publicissapient.kpidashboard.common.repository.jira.JiraIssueRepository;
import com.publicissapient.kpidashboard.rally.config.RallyProcessorConfig;
import com.publicissapient.kpidashboard.rally.constant.RallyConstants;
import com.publicissapient.kpidashboard.rally.model.HierarchicalRequirement;
import com.publicissapient.kpidashboard.rally.model.ProjectConfFieldMapping;
Expand Down Expand Up @@ -51,6 +52,8 @@ public class RallyIssueProcessorImpl implements RallyIssueProcessor {
@Autowired
private JiraIssueRepository jiraIssueRepository;

@Autowired
private RallyProcessorConfig rallyProcessorConfig;

private JiraIssue getJiraIssue(ProjectConfFieldMapping projectConfig, String issueId) {
String basicProjectConfigId = projectConfig.getBasicProjectConfigId().toString();
Expand Down Expand Up @@ -116,7 +119,7 @@ public JiraIssue convertToJiraIssue(HierarchicalRequirement hierarchicalRequirem
jiraIssue.setProcessorId(processorId);
jiraIssue.setJiraStatus(hierarchicalRequirement.getScheduleState());
jiraIssue.setTypeId(hierarchicalRequirement.getObjectID());
jiraIssue.setIssueId(hierarchicalRequirement.getFormattedID());
jiraIssue.setIssueId(hierarchicalRequirement.getObjectID());
if (hierarchicalRequirement.getType().equalsIgnoreCase("HierarchicalRequirement"))
jiraIssue.setTypeName(NormalizedJira.USER_STORY_TYPE.getValue());
else
Expand All @@ -135,10 +138,21 @@ public JiraIssue convertToJiraIssue(HierarchicalRequirement hierarchicalRequirem
+ projectConfig.getProjectBasicConfig().getProjectNodeId());
jiraIssue.setSprintAssetState(hierarchicalRequirement.getIteration().getState());
}
setURL(hierarchicalRequirement.getObjectID(), jiraIssue);
jiraIssue.setBoardId(boardId);
return jiraIssue;
}

private void setURL(String ticketNumber, JiraIssue jiraIssue) {
String baseUrl = rallyProcessorConfig.getRallyUserStoryBaseUrl();
if (baseUrl != null) {
jiraIssue.setUrl(baseUrl + ticketNumber);
} else {
// Set a default URL or just the ticket number if base URL is not available
jiraIssue.setUrl("https://rally.example.com/" + ticketNumber);
}
}


/**
* Sets the story links for defects in the JiraIssue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,38 +97,43 @@ private Set<SprintDetails> createSprintDetails(Iteration iteration, ProjectConfF
}

private static void initializeSprintDetails(List<JiraIssue> jiraIssueList,
List<JiraIssueCustomHistory> jiraIssueCustomHistoryList, List<SprintDetails> sprintDetailsList) {
List<JiraIssueCustomHistory> jiraIssueCustomHistoryList, List<SprintDetails> sprintDetailsList) {

Map<String, JiraIssue> jiraIssueMap = jiraIssueList.stream()
.collect(Collectors.toMap(JiraIssue::getNumber, issue -> issue));

Map<String, Set<JiraIssue>> issuesBySprintName = jiraIssueList.stream()
.filter(issue -> issue.getSprintName() != null)
.collect(Collectors.groupingBy(JiraIssue::getSprintName, Collectors.toSet()));
Map<String, JiraIssue> jiraIssueMap = jiraIssueList.stream()
.collect(Collectors.toMap(
JiraIssue::getNumber,
issue -> issue,
(existing, replacement) -> existing // Keep the first occurrence when duplicates found
));

for (SprintDetails sprintDetails : sprintDetailsList) {
String sprintName = sprintDetails.getSprintName();
Map<String, Set<JiraIssue>> issuesBySprintName = jiraIssueList.stream()
.filter(issue -> issue.getSprintName() != null)
.collect(Collectors.groupingBy(JiraIssue::getSprintName, Collectors.toSet()));

Set<SprintIssue> totalIssues = convertToSprintIssues(
issuesBySprintName.getOrDefault(sprintName, new HashSet<>()));
for (SprintDetails sprintDetails : sprintDetailsList) {
String sprintName = sprintDetails.getSprintName();

Pair<Set<SprintIssue>, Set<SprintIssue>> addedAndRemovedIssues = processSprintHistory(
jiraIssueCustomHistoryList, jiraIssueMap, sprintName);
Set<SprintIssue> totalIssues = convertToSprintIssues(
issuesBySprintName.getOrDefault(sprintName, new HashSet<>()));

Set<SprintIssue> addedIssues = addedAndRemovedIssues.getLeft();
Set<SprintIssue> removedIssues = addedAndRemovedIssues.getRight();
Pair<Set<SprintIssue>, Set<SprintIssue>> addedAndRemovedIssues = processSprintHistory(
jiraIssueCustomHistoryList, jiraIssueMap, sprintName);

setTotalIssues(sprintDetails, totalIssues);
Set<SprintIssue> addedIssues = addedAndRemovedIssues.getLeft();
Set<SprintIssue> removedIssues = addedAndRemovedIssues.getRight();

setAddedAndRemovedIssues(sprintDetails,
addedIssues.stream().map(SprintIssue::getNumber).collect(Collectors.toSet()), removedIssues);
setTotalIssues(sprintDetails, totalIssues);

addedIssues.removeAll(removedIssues);
totalIssues.addAll(addedIssues);
setTotalIssues(sprintDetails, totalIssues);
setAddedAndRemovedIssues(sprintDetails,
addedIssues.stream().map(SprintIssue::getNumber).collect(Collectors.toSet()), removedIssues);

separateAndSetIssuesByCompletionStatus(sprintDetails, totalIssues);
}
addedIssues.removeAll(removedIssues);
totalIssues.addAll(addedIssues);
setTotalIssues(sprintDetails, totalIssues);

separateAndSetIssuesByCompletionStatus(sprintDetails, totalIssues);
}
}

private static void setBasicSprintDetails(Iteration iteration, ProjectConfFieldMapping projectConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ public List<HierarchicalRequirement> getHierarchicalRequirements(int pageStart)


// Fetch fields for each artifact type, including Defects for hierarchical requirements
String fetchFields = "FormattedID,Name,Owner,PlanEstimate,ScheduleState,Iteration,CreationDate,LastUpdateDate,RevisionHistory";
String fetchFields = "FormattedID,Name,Owner,PlanEstimate,ScheduleState,Iteration,CreationDate,LastUpdateDate,RevisionHistory,ObjectID";
String hierarchicalRequirementFetchFields = fetchFields + ",Defects";
List<HierarchicalRequirement> allArtifacts = new ArrayList<>();
Map<String, Iteration> iterationMap = new HashMap<>();
Expand Down
Loading