From df3d4a04300a6cde18ce1e434ecc2ed6202eaa2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=94=D0=BE=D1=98=D0=BA?= =?UTF-8?q?=D0=B8=D1=9B?= Date: Sat, 17 Aug 2024 14:40:58 +0200 Subject: [PATCH] Correction of jira timings --- .../DeveloperImpl.java | 118 ++++++++---------- .../ProjectManagerImpl.java | 61 +++++---- .../enums/Priority.java | 13 +- .../util/DataProvider.java | 12 +- 4 files changed, 105 insertions(+), 99 deletions(-) diff --git a/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/DeveloperImpl.java b/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/DeveloperImpl.java index 1647e36..864d970 100644 --- a/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/DeveloperImpl.java +++ b/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/DeveloperImpl.java @@ -3,13 +3,10 @@ import com.diogonunes.jcolor.Attribute; import com.google.common.util.concurrent.Uninterruptibles; import dev.markodojkic.softwaredevelopmentsimulation.model.TechnicalTask; -import jakarta.annotation.PostConstruct; import org.springframework.integration.annotation.MessageEndpoint; import org.springframework.integration.annotation.ServiceActivator; import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; -import java.time.temporal.Temporal; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -20,39 +17,19 @@ @MessageEndpoint public class DeveloperImpl { private static final Logger logger = Logger.getLogger(DeveloperImpl.class.getName()); - private static final String CREATED_TASK_FORMAT = "\033[1m%s\033[21m\033[24m created TASK: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$"; - private static final String CHANGED_THE_ASSIGNEE_TO_FORMAT = "\033[1m%s\033[21m\033[24m changed the Assignee to '\033[1m%s\033[21m\033[24m' on TASK: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$"; - private static final String CHANGED_STATUS_TO_IN_PROGRESS_FORMAT = "\033[1m%s\033[21m\033[24m changed the status to In progress on TASK: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$"; - - private Long trivialTaskTypicalResolutionTimeCoefficient; - private Long normalTaskTypicalResolutionTimeCoefficient; - private Long minorTaskTypicalResolutionTimeCoefficient; - private Long majorTaskTypicalResolutionTimeCoefficient; - private Long criticalTaskTypicalResolutionTimeCoefficient; - private Long blockerTaskTypicalResolutionTimeCoefficient; - - private long getArtificialOffsetInSeconds(Temporal createdTaskOn){ - return ChronoUnit.SECONDS.between(ZonedDateTime.now(), createdTaskOn); - } - - @PostConstruct - public void init(){ - trivialTaskTypicalResolutionTimeCoefficient = 1600L; - normalTaskTypicalResolutionTimeCoefficient = 1420L; - minorTaskTypicalResolutionTimeCoefficient = 1240L; - majorTaskTypicalResolutionTimeCoefficient = 860L; - criticalTaskTypicalResolutionTimeCoefficient = 540L; - blockerTaskTypicalResolutionTimeCoefficient = 220L; - } @ServiceActivator(inputChannel = "trivialTechnicalTask.intermediate", outputChannel = "doneTechnicalTasks.output") public TechnicalTask trivialTaskHandler(TechnicalTask technicalTask) { - sendToJiraCreatedTaskInfo(technicalTask); - Uninterruptibles.sleepUninterruptibly(SECURE_RANDOM.nextLong(technicalTask.getAssignee().getExperienceCoefficient(), technicalTask.getAssignee().getExperienceCoefficient() * 2), TimeUnit.MILLISECONDS); sendToJiraSetStatusToInProgressInfo(technicalTask); - logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s started working on trivial technical task %s", - technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); - Uninterruptibles.sleepUninterruptibly(trivialTaskTypicalResolutionTimeCoefficient / technicalTask.getAssignee().getExperienceCoefficient(), TimeUnit.MILLISECONDS); + Uninterruptibles.sleepUninterruptibly( + (long) + (((technicalTask.getReporter().getExperienceCoefficient() + technicalTask.getAssignee().getExperienceCoefficient()) / 2.0) + * ((technicalTask.getReporter().getDeveloperType().getSeniorityCoefficient() + technicalTask.getAssignee().getDeveloperType().getSeniorityCoefficient()) / 2.0) + * technicalTask.getPriority().getResolutionTimeCoefficient() + * (6 - technicalTask.getPriority().getUrgency()) / 5.0 + * 0.01 + + 1500) + , TimeUnit.MILLISECONDS); logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s finished working on trivial technical task %s", technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); return technicalTask; @@ -60,12 +37,16 @@ public TechnicalTask trivialTaskHandler(TechnicalTask technicalTask) { @ServiceActivator(inputChannel = "normalTechnicalTask.intermediate", outputChannel = "doneTechnicalTasks.output") public TechnicalTask normalTaskHandler(TechnicalTask technicalTask) { - sendToJiraCreatedTaskInfo(technicalTask); - Uninterruptibles.sleepUninterruptibly(SECURE_RANDOM.nextLong(technicalTask.getAssignee().getExperienceCoefficient(), technicalTask.getAssignee().getExperienceCoefficient() * 4), TimeUnit.MILLISECONDS); sendToJiraSetStatusToInProgressInfo(technicalTask); - logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s started working on normal technical task %s", - technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); - Uninterruptibles.sleepUninterruptibly(technicalTask.getAssignee().getExperienceCoefficient() / normalTaskTypicalResolutionTimeCoefficient, TimeUnit.MILLISECONDS); + Uninterruptibles.sleepUninterruptibly( + (long) + (((technicalTask.getReporter().getExperienceCoefficient() + technicalTask.getAssignee().getExperienceCoefficient()) / 2.0) + * ((technicalTask.getReporter().getDeveloperType().getSeniorityCoefficient() + technicalTask.getAssignee().getDeveloperType().getSeniorityCoefficient()) / 2.0) + * technicalTask.getPriority().getResolutionTimeCoefficient() + * (6 - technicalTask.getPriority().getUrgency()) / 5.0 + * 0.02 + + 1500) + , TimeUnit.MILLISECONDS); logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s finished working on normal technical task %s", technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); return technicalTask; @@ -73,12 +54,16 @@ public TechnicalTask normalTaskHandler(TechnicalTask technicalTask) { @ServiceActivator(inputChannel = "minorTechnicalTask.intermediate", outputChannel = "doneTechnicalTasks.output") public TechnicalTask minorTaskHandler(TechnicalTask technicalTask) { - sendToJiraCreatedTaskInfo(technicalTask); - Uninterruptibles.sleepUninterruptibly(SECURE_RANDOM.nextLong(technicalTask.getAssignee().getExperienceCoefficient(), technicalTask.getAssignee().getExperienceCoefficient() * 6), TimeUnit.MILLISECONDS); sendToJiraSetStatusToInProgressInfo(technicalTask); - logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s started working on minor technical task %s", - technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); - Uninterruptibles.sleepUninterruptibly(technicalTask.getAssignee().getExperienceCoefficient() / minorTaskTypicalResolutionTimeCoefficient, TimeUnit.MILLISECONDS); + Uninterruptibles.sleepUninterruptibly( + (long) + (((technicalTask.getReporter().getExperienceCoefficient() + technicalTask.getAssignee().getExperienceCoefficient()) / 2.0) + * ((technicalTask.getReporter().getDeveloperType().getSeniorityCoefficient() + technicalTask.getAssignee().getDeveloperType().getSeniorityCoefficient()) / 2.0) + * technicalTask.getPriority().getResolutionTimeCoefficient() + * (6 - technicalTask.getPriority().getUrgency()) / 5.0 + * 0.03 + + 1500) + , TimeUnit.MILLISECONDS); logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s finished working on minor technical task %s", technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); return technicalTask; @@ -86,12 +71,16 @@ public TechnicalTask minorTaskHandler(TechnicalTask technicalTask) { @ServiceActivator(inputChannel = "majorTechnicalTask.intermediate", outputChannel = "doneTechnicalTasks.output") public TechnicalTask majorTaskHandler(TechnicalTask technicalTask) { - sendToJiraCreatedTaskInfo(technicalTask); - Uninterruptibles.sleepUninterruptibly(SECURE_RANDOM.nextLong(technicalTask.getAssignee().getExperienceCoefficient(), technicalTask.getAssignee().getExperienceCoefficient() * 8), TimeUnit.MILLISECONDS); sendToJiraSetStatusToInProgressInfo(technicalTask); - logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s started working on major technical task %s", - technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); - Uninterruptibles.sleepUninterruptibly(technicalTask.getAssignee().getExperienceCoefficient() / majorTaskTypicalResolutionTimeCoefficient , TimeUnit.MILLISECONDS); + Uninterruptibles.sleepUninterruptibly( + (long) + (((technicalTask.getReporter().getExperienceCoefficient() + technicalTask.getAssignee().getExperienceCoefficient()) / 2.0) + * ((technicalTask.getReporter().getDeveloperType().getSeniorityCoefficient() + technicalTask.getAssignee().getDeveloperType().getSeniorityCoefficient()) / 2.0) + * technicalTask.getPriority().getResolutionTimeCoefficient() + * (6 - technicalTask.getPriority().getUrgency()) / 5.0 + * 0.04 + + 1500) + , TimeUnit.MILLISECONDS); logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s finished working on major technical task %s", technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); return technicalTask; @@ -99,12 +88,16 @@ public TechnicalTask majorTaskHandler(TechnicalTask technicalTask) { @ServiceActivator(inputChannel = "criticalTechnicalTask.intermediate", outputChannel = "doneTechnicalTasks.output") public TechnicalTask criticalTaskHandler(TechnicalTask technicalTask) { - sendToJiraCreatedTaskInfo(technicalTask); - Uninterruptibles.sleepUninterruptibly(SECURE_RANDOM.nextLong(technicalTask.getAssignee().getExperienceCoefficient(), technicalTask.getAssignee().getExperienceCoefficient() * 10), TimeUnit.MILLISECONDS); sendToJiraSetStatusToInProgressInfo(technicalTask); - logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s started working on critical technical task %s", - technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); - Uninterruptibles.sleepUninterruptibly(technicalTask.getAssignee().getExperienceCoefficient() / criticalTaskTypicalResolutionTimeCoefficient, TimeUnit.MILLISECONDS); + Uninterruptibles.sleepUninterruptibly( + (long) + (((technicalTask.getReporter().getExperienceCoefficient() + technicalTask.getAssignee().getExperienceCoefficient()) / 2.0) + * ((technicalTask.getReporter().getDeveloperType().getSeniorityCoefficient() + technicalTask.getAssignee().getDeveloperType().getSeniorityCoefficient()) / 2.0) + * technicalTask.getPriority().getResolutionTimeCoefficient() + * (6 - technicalTask.getPriority().getUrgency()) / 5.0 + * 0.05 + + 1500) + , TimeUnit.MILLISECONDS); logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s finished working on critical technical task %s", technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); return technicalTask; @@ -112,25 +105,24 @@ public TechnicalTask criticalTaskHandler(TechnicalTask technicalTask) { @ServiceActivator(inputChannel = "blockerTechnicalTask.intermediate", outputChannel = "doneTechnicalTasks.output") public TechnicalTask blockerTaskHandler(TechnicalTask technicalTask) { - sendToJiraCreatedTaskInfo(technicalTask); - Uninterruptibles.sleepUninterruptibly(SECURE_RANDOM.nextLong(technicalTask.getAssignee().getExperienceCoefficient(), technicalTask.getAssignee().getExperienceCoefficient() * 12), TimeUnit.MILLISECONDS); sendToJiraSetStatusToInProgressInfo(technicalTask); - logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s started working on blocker technical task %s", - technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); - Uninterruptibles.sleepUninterruptibly(technicalTask.getAssignee().getExperienceCoefficient() / blockerTaskTypicalResolutionTimeCoefficient, TimeUnit.MILLISECONDS); + Uninterruptibles.sleepUninterruptibly( + (long) + (((technicalTask.getReporter().getExperienceCoefficient() + technicalTask.getAssignee().getExperienceCoefficient()) / 2.0) + * ((technicalTask.getReporter().getDeveloperType().getSeniorityCoefficient() + technicalTask.getAssignee().getDeveloperType().getSeniorityCoefficient()) / 2.0) + * technicalTask.getPriority().getResolutionTimeCoefficient() + * (6 - technicalTask.getPriority().getUrgency()) / 5.0 + * 0.06 + + 1500) + , TimeUnit.MILLISECONDS); logger.log(Level.INFO, () -> colorize(String.format("%n###Developer %s finished working on blocker technical task %s", technicalTask.getAssignee().getDisplayName(), technicalTask.getId()), Attribute.TEXT_COLOR(0), Attribute.BACK_COLOR(technicalTask.getPriority().getAnsiColorCode()))); return technicalTask; } - private void sendToJiraCreatedTaskInfo(TechnicalTask technicalTask) { - getIGateways().sendToJiraActivityStream(String.format(CHANGED_THE_ASSIGNEE_TO_FORMAT, - technicalTask.getReporter().getDisplayName(), technicalTask.getAssignee().getDisplayName(), technicalTask.getId(), technicalTask.getName(), technicalTask.getCreatedOn().plusSeconds(getArtificialOffsetInSeconds(technicalTask.getCreatedOn()) + 10).format(DATE_TIME_FORMATTER)).concat(String.format(CREATED_TASK_FORMAT, - technicalTask.getReporter().getDisplayName(), technicalTask.getId(), technicalTask.getName(), technicalTask.getCreatedOn().plusSeconds(getArtificialOffsetInSeconds(technicalTask.getCreatedOn())).format(DATE_TIME_FORMATTER))).replaceFirst(".$", "")); - } private void sendToJiraSetStatusToInProgressInfo(TechnicalTask technicalTask) { - getIGateways().sendToJiraActivityStream(String.format(CHANGED_STATUS_TO_IN_PROGRESS_FORMAT, + getIGateways().sendToJiraActivityStream(String.format("\033[1m%s\033[21m\033[24m changed the status to In progress on TASK: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", technicalTask.getAssignee().getDisplayName(), technicalTask.getId(), technicalTask.getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER)).replaceFirst(".$", "")); } } \ No newline at end of file diff --git a/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/ProjectManagerImpl.java b/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/ProjectManagerImpl.java index c5be8dd..3a693e1 100755 --- a/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/ProjectManagerImpl.java +++ b/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/ProjectManagerImpl.java @@ -1,14 +1,13 @@ package dev.markodojkic.softwaredevelopmentsimulation; -import java.nio.charset.StandardCharsets; import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; import java.util.logging.Logger; import com.google.common.collect.Streams; +import dev.markodojkic.softwaredevelopmentsimulation.enums.Priority; import dev.markodojkic.softwaredevelopmentsimulation.model.*; import dev.markodojkic.softwaredevelopmentsimulation.util.DataProvider; import dev.markodojkic.softwaredevelopmentsimulation.util.EpicNotDoneException; @@ -46,28 +45,24 @@ public List assignUserStoriesAndPrepareTechnicalTasks(Message e Epic epic = epicMessage.getPayload(); List assignedDevelopmentTeams = DataProvider.getCurrentDevelopmentTeamsSetup().get((Integer) epicMessage.getHeaders().getOrDefault(ASSIGNED_DEVELOPMENT_TEAM_POSITION_NUMBER, 0)); epic.setAssignee(assignedDevelopmentTeams.getFirst()); - List userStoryList = epic.getUserStories(); - long artificialOffsetSeconds = ChronoUnit.SECONDS.between(ZonedDateTime.now(), userStoryList.getFirst().getCreatedOn()); - AtomicReference jiraEpicCreatedOutput = new AtomicReference<>(""); + AtomicReference jiraAccumulatedOutput = new AtomicReference<>(""); - jiraEpicCreatedOutput.set(String.format("\033[1m%s\033[21m\033[24m changed the Assignee to '\033[1m%s\033[21m\033[24m' on EPIC: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", - epic.getReporter().getDisplayName(), epic.getAssignee().getDisplayName(), epic.getId(), epic.getName(), epic.getCreatedOn().plusSeconds(10).format(DATE_TIME_FORMATTER))); - jiraEpicCreatedOutput.set(String.format("\033[1m%s\033[21m\033[24m changed the status to In progress on EPIC: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", - epic.getAssignee().getDisplayName(), epic.getId(), epic.getName(), epic.getCreatedOn().plusSeconds(35).format(DATE_TIME_FORMATTER)).concat(jiraEpicCreatedOutput.get())); - jiraEpicCreatedOutput.set(String.format("\033[1m%s\033[21m\033[24m started sprint for EPIC: \033[3m\033[1m%s\033[21m\033[24m \033[23m ◴ %s$", - epic.getAssignee().getDisplayName(), String.valueOf(userStoryList.getFirst().getEpicId().hashCode()).replaceFirst("-", ""), userStoryList.getFirst().getCreatedOn().plusSeconds(artificialOffsetSeconds).minusSeconds(10).format(DATE_TIME_FORMATTER)).concat(jiraEpicCreatedOutput.get())); + jiraAccumulatedOutput.set(String.format("\033[1m%s\033[21m\033[24m changed the Assignee to '\033[1m%s\033[21m\033[24m' on EPIC: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + epic.getReporter().getDisplayName(), epic.getAssignee().getDisplayName(), epic.getId(), epic.getName(), epic.getCreatedOn().plusSeconds(SECURE_RANDOM.nextInt(10,25)).format(DATE_TIME_FORMATTER))); epic.setUserStories(Streams.mapWithIndex(epic.getUserStories().stream(), (userStory, userStoryIndex) -> { userStory.setReporter(epic.getAssignee()); userStory.setAssignee(assignedDevelopmentTeams.get(userStoryIndex == 0 ? 0 : (((int) userStoryIndex) + assignedDevelopmentTeams.size()) % (assignedDevelopmentTeams.size()))); - jiraEpicCreatedOutput.set(String.format("\033[1m%s\033[21m\033[24m created US: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", - userStory.getReporter().getDisplayName(), userStory.getId(), userStory.getName(), userStory.getCreatedOn().plusSeconds(artificialOffsetSeconds).format(DATE_TIME_FORMATTER)).concat(jiraEpicCreatedOutput.get())); - jiraEpicCreatedOutput.set(String.format("\033[1m%s\033[21m\033[24m changed the Assignee to '\033[1m%s\033[21m\033[24m' on US: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", - userStory.getReporter().getDisplayName(), userStory.getAssignee().getDisplayName(), userStory.getId(), userStory.getName(), userStory.getCreatedOn().plusSeconds(artificialOffsetSeconds + 10).format(DATE_TIME_FORMATTER)).concat(jiraEpicCreatedOutput.get())); + jiraAccumulatedOutput.set(String.format("\033[1m%s\033[21m\033[24m created US: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + userStory.getReporter().getDisplayName(), userStory.getId(), userStory.getName(), userStory.getCreatedOn().plusSeconds(SECURE_RANDOM.nextInt(25,35)).format(DATE_TIME_FORMATTER)).concat(jiraAccumulatedOutput.get())); + jiraAccumulatedOutput.set(String.format("\033[1m%s\033[21m\033[24m changed the Assignee to '\033[1m%s\033[21m\033[24m' on US: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + userStory.getReporter().getDisplayName(), userStory.getAssignee().getDisplayName(), userStory.getId(), userStory.getName(), userStory.getCreatedOn().plusSeconds(SECURE_RANDOM.nextInt(35,45)).format(DATE_TIME_FORMATTER)).concat(jiraAccumulatedOutput.get())); currentSprintUserStoriesMap.put(userStory.getId().concat("@").concat(epic.getId()), false); - jiraEpicCreatedOutput.set(String.format("\033[1m%s\033[21m\033[24m changed the status to In progress on US: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", - userStory.getAssignee().getDisplayName(), userStory.getId(), userStory.getName(), userStory.getCreatedOn().plusSeconds(artificialOffsetSeconds + 10 + 25).format(DATE_TIME_FORMATTER)).concat(jiraEpicCreatedOutput.get())); userStory.setTechnicalTasks(Streams.mapWithIndex(userStory.getTechnicalTasks().stream(), (technicalTask,technicalTaskIndex) -> { + jiraAccumulatedOutput.set(String.format("\033[1m%s\033[21m\033[24m created TASK: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + technicalTask.getReporter().getDisplayName(), technicalTask.getId(), technicalTask.getName(), technicalTask.getCreatedOn().plusSeconds(SECURE_RANDOM.nextInt(45, 55)).format(DATE_TIME_FORMATTER)).concat(jiraAccumulatedOutput.get())); + jiraAccumulatedOutput.set(String.format("\033[1m%s\033[21m\033[24m changed the Assignee to '\033[1m%s\033[21m\033[24m' on TASK: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + technicalTask.getReporter().getDisplayName(), technicalTask.getAssignee().getDisplayName(), technicalTask.getId(), technicalTask.getName(), technicalTask.getCreatedOn().plusSeconds(SECURE_RANDOM.nextInt(55, 60)).format(DATE_TIME_FORMATTER)).concat(jiraAccumulatedOutput.get())); technicalTask.setReporter(userStory.getAssignee()); technicalTask.setAssignee(assignedDevelopmentTeams.get(technicalTaskIndex == 0 ? 0 : (((int) technicalTaskIndex) + assignedDevelopmentTeams.size()) % (assignedDevelopmentTeams.size()))); return technicalTask; @@ -75,7 +70,12 @@ public List assignUserStoriesAndPrepareTechnicalTasks(Message e return userStory; }).toList()); - getIGateways().sendToJiraActivityStream(jiraEpicCreatedOutput.get().replaceFirst(".$", "")); + jiraAccumulatedOutput.set(String.format("\033[1m%s\033[21m\033[24m started sprint for EPIC: \033[3m\033[1m%s\033[21m\033[24m \033[23m ◴ %s$", + epic.getAssignee().getDisplayName(), String.valueOf(epic.getId().hashCode()).replaceFirst("-", ""), ZonedDateTime.now().plusSeconds(SECURE_RANDOM.nextInt(5, 10)).format(DATE_TIME_FORMATTER)).concat(jiraAccumulatedOutput.get())); + jiraAccumulatedOutput.set(String.format("\033[1m%s\033[21m\033[24m changed the status to In progress on EPIC: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + epic.getAssignee().getDisplayName(), epic.getId(), epic.getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER)).concat(jiraAccumulatedOutput.get())); + + getIGateways().sendToJiraActivityStream(jiraAccumulatedOutput.get().replaceFirst(".$", "")); new Thread(() -> inProgressEpic.send(epicMessage)).start(); @@ -90,7 +90,11 @@ public List assignUserStoriesAndPrepareTechnicalTasks(Message e @Splitter(inputChannel = "currentSprintUserStories.preIntermediate", outputChannel = "toDoTechnicalTasks.input") public List assignTechnicalTasks(UserStory userStory){ - new Thread(() -> inProgressUserStory.send(MessageBuilder.withPayload(userStory).build())).start(); + new Thread(() -> { + getIGateways().sendToJiraActivityStream(String.format("\033[1m%s\033[21m\033[24m changed the status to In progress on US: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + userStory.getAssignee().getDisplayName(), userStory.getId(), userStory.getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER)).replaceFirst(".$", "")); + inProgressUserStory.send(MessageBuilder.withPayload(userStory).build()); + }).start(); return userStory.getTechnicalTasks(); } @@ -118,7 +122,7 @@ public UserStory sendToDoneUserStory(UserStory userStory) throws UserStoryNotDon public void printDoneEpic(Message epicMessage) { if(epicMessage != null) { getIGateways().sendToJiraActivityStream(String.format("\033[1m%s\033[21m\033[24m changed the status to Done on EPIC: \033[3m\033[1m\033[9m%s\033[21m\033[24m\033[29m - %s\033[23m with resolution \033[1mDone\033[21m\033[24m ◴ %s$", - epicMessage.getPayload().getAssignee().getDisplayName(), epicMessage.getPayload().getId(), epicMessage.getPayload().getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER)).replaceFirst(".$", "")); // 9 - STRIKE-THROUGH, 29 - RESET STRIKE-THROUGH + epicMessage.getPayload().getAssignee().getDisplayName(), epicMessage.getPayload().getId(), epicMessage.getPayload().getName(), ZonedDateTime.now().plusSeconds(SECURE_RANDOM.nextInt(10, 20)).format(DATE_TIME_FORMATTER)).replaceFirst(".$", "")); // 9 - STRIKE-THROUGH, 29 - RESET STRIKE-THROUGH logger.log(Level.INFO, "{0} finished - Current count: {1}", new String[]{epicMessage.getPayload().getId(), String.valueOf(IN_PROGRESS_EPICS_COUNT.decrementAndGet())}); DataProvider.getAvailableDevelopmentTeamIds().push(epicMessage.getHeaders().get(ASSIGNED_DEVELOPMENT_TEAM_POSITION_NUMBER, Integer.class)); if(IN_PROGRESS_EPICS_COUNT.get() < getTotalDevelopmentTeamsPresent()) controlBusInput.send(MessageBuilder.withPayload("@assignEpicFlow.start()").build()); @@ -129,8 +133,9 @@ public void printDoneEpic(Message epicMessage) { public void updateUserStoryStatus(UserStory userStory){ if(userStory != null) { getIGateways().sendToJiraActivityStream(String.format("\033[1m%s\033[21m\033[24m changed the status to Done on US: \033[3m\033[1m\033[9m%s\033[21m\033[24m\033[29m - %s\033[23m with resolution \033[1mDONE\033[21m\033[24m ◴ %s$", - userStory.getAssignee().getDisplayName(), userStory.getId(), userStory.getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER)).concat(String.format("\033[1m%s\033[21m\033[24m logged '%.0fh' on US: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", - userStory.getAssignee().getDisplayName(), Math.abs(Math.ceil((double) (UUID.nameUUIDFromBytes(userStory.getId().getBytes(StandardCharsets.UTF_8)).hashCode() % 1000) / userStory.getAssignee().getExperienceCoefficient())), userStory.getId(), userStory.getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER))).replaceFirst(".$", "")); + userStory.getAssignee().getDisplayName(), userStory.getId(), userStory.getName(), ZonedDateTime.now().plusSeconds(SECURE_RANDOM.nextInt(10)).format(DATE_TIME_FORMATTER)).concat(String.format("\033[1m%s\033[21m\033[24m logged '%dh' on US: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + userStory.getAssignee().getDisplayName(), calculateTotalLoggedTimeInHours(userStory.getReporter(), userStory.getAssignee(), userStory.getPriority()) / 10, userStory.getId(), userStory.getName(), ZonedDateTime.now().plusSeconds(SECURE_RANDOM.nextInt(25 + ,45)).format(DATE_TIME_FORMATTER))).replaceFirst(".$", "")); currentSprintUserStoriesMap.put(userStory.getId().concat("@").concat(userStory.getEpicId()), true); } @@ -140,8 +145,8 @@ public void updateUserStoryStatus(UserStory userStory){ public void updateTechnicalTaskStatus(TechnicalTask technicalTask){ if(technicalTask != null) { getIGateways().sendToJiraActivityStream(String.format("\033[1m%s\033[21m\033[24m changed the status to Done on TASK: \033[3m\033[1m\033[9m%s\033[21m\033[24m\033[29m - %s\033[23m with resolution \033[1mDONE\033[21m\033[24m ◴ %s$", - technicalTask.getAssignee().getDisplayName(), technicalTask.getId(), technicalTask.getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER)).concat(String.format("\033[1m%s\033[21m\033[24m logged '%.0fh' on TASK: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", - technicalTask.getAssignee().getDisplayName(), Math.ceil((double) Math.abs(ChronoUnit.SECONDS.between(ZonedDateTime.now(), technicalTask.getCreatedOn())) / technicalTask.getAssignee().getExperienceCoefficient()), technicalTask.getId(), technicalTask.getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER))).replaceFirst(".$", Strings.EMPTY)); + technicalTask.getAssignee().getDisplayName(), technicalTask.getId(), technicalTask.getName(), ZonedDateTime.now().plusSeconds(SECURE_RANDOM.nextInt(10)).format(DATE_TIME_FORMATTER)).concat(String.format("\033[1m%s\033[21m\033[24m logged '%dh' on TASK: \033[3m\033[1m%s\033[21m\033[24m - %s\033[23m ◴ %s$", + technicalTask.getAssignee().getDisplayName(), calculateTotalLoggedTimeInHours(technicalTask.getReporter(), technicalTask.getAssignee(), technicalTask.getPriority()), technicalTask.getId(), technicalTask.getName(), ZonedDateTime.now().format(DATE_TIME_FORMATTER))).replaceFirst(".$", Strings.EMPTY)); userStoriesTechnicalTasksMap.put(technicalTask.getId().concat("@").concat(technicalTask.getUserStoryId()), true); } @@ -154,4 +159,12 @@ private boolean markEpicAsDone(Epic epic){ private boolean markUserStoryAsDone(UserStory userStory){ return !userStoriesTechnicalTasksMap.isEmpty() && userStoriesTechnicalTasksMap.entrySet().stream().anyMatch(value -> value.getKey().contains(Objects.requireNonNull(userStory.getId()))) && userStoriesTechnicalTasksMap.entrySet().stream().filter(value -> value.getKey().contains(userStory.getId())).allMatch(value -> value.getValue().equals(Boolean.TRUE)); } + + private int calculateTotalLoggedTimeInHours(Developer reporter, Developer assignee, Priority taskPriority){ + double reporterExpertise = reporter.getExperienceCoefficient() * reporter.getDeveloperType().getSeniorityCoefficient(); + double assigneeExpertise = assignee.getExperienceCoefficient() * assignee.getDeveloperType().getSeniorityCoefficient(); + double averageExpertise = (reporterExpertise + assigneeExpertise) / 2.0; + + return (int) Math.round(Math.clamp(1.0, 240.0 * (taskPriority.getResolutionTimeCoefficient() / averageExpertise) * (1.0 / (1 + taskPriority.getUrgency())), 240.0)); + } } \ No newline at end of file diff --git a/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/enums/Priority.java b/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/enums/Priority.java index 5bfc6e7..f91a669 100644 --- a/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/enums/Priority.java +++ b/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/enums/Priority.java @@ -6,13 +6,14 @@ @AllArgsConstructor @Getter public enum Priority { - TRIVIAL(0, 7), - NORMAL(1, 15), - MINOR(2, 50), - MAJOR(3, 37), - CRITICAL(4, 124), - BLOCKER(5, 160); + TRIVIAL(2.45 , 0, 7), + NORMAL(4.00, 1, 15), + MINOR(5.78, 2, 50), + MAJOR(7.13578, 3, 37), + CRITICAL(11.1545, 4, 124), + BLOCKER(14.1216, 5, 160); + private final double resolutionTimeCoefficient; private final int urgency; private final int ansiColorCode; } \ No newline at end of file diff --git a/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/util/DataProvider.java b/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/util/DataProvider.java index 9d11f85..980db1d 100755 --- a/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/util/DataProvider.java +++ b/src/main/java/dev/markodojkic/softwaredevelopmentsimulation/util/DataProvider.java @@ -27,7 +27,7 @@ public class DataProvider { @Getter static List> currentDevelopmentTeamsSetup = Collections.emptyList(); @Getter - static Deque availableDevelopmentTeamIds = new ArrayDeque<>(); + static LinkedList availableDevelopmentTeamIds = new LinkedList<>(); static final String PLACE_OF_BIRTH_MAPS_DEFAULT_VALUE = "Unknown"; static NavigableMap countryMap; @@ -59,11 +59,11 @@ public static void replaceDevelopmentTeamsSetup(List> newDevelop public static void updateDevelopmentTeamsSetup(DevelopmentTeamCreationParameters parameters){ if(!parameters.isRetainOld()) currentDevelopmentTeamsSetup = Collections.emptyList(); currentDevelopmentTeamsSetup = Stream.concat(currentDevelopmentTeamsSetup.stream(), Lists.partition(Stream.generate(() -> { - boolean isFemale = SECURE_RANDOM.nextInt(100) % 100 < parameters.getFemaleDevelopersPercentage(); - return new Developer((isFemale ? LOREM.getNameFemale() : LOREM.getNameMale()), Strings.EMPTY, Arrays.stream(DeveloperType.values()).skip(SECURE_RANDOM.nextInt(1, DeveloperType.values().length)).findAny().orElse(DeveloperType.INTERN_DEVELOPER), isFemale, SECURE_RANDOM.nextLong(1, 10)); - }).limit(SECURE_RANDOM.nextInt(parameters.getMinimalDevelopersCount(), parameters.getMaximalDevelopersCount())).toList(), SECURE_RANDOM.nextInt(parameters.getMinimalDevelopersInTeamCount(), parameters.getMaximalDevelopersInTeamCount())).stream()).collect(Collectors.toCollection(ArrayList::new)); - availableDevelopmentTeamIds.addAll(IntStream.rangeClosed(0, currentDevelopmentTeamsSetup.size() - 1).boxed().collect(Collectors.toCollection(ArrayList::new))); - } //Generate between and developers ('Developer' class objects) and group them evenly in groups of anywhere between and and developers ('Developer' class objects) and group them evenly in groups of anywhere between and developmentTeam = new ArrayList<>(currentDevelopmentTeamsSetup.get(developmentTeamIndex));