Skip to content

Commit

Permalink
[NU-1772] Refactor ScenarioActivity state handling (#7007)
Browse files Browse the repository at this point in the history
  • Loading branch information
mgoworko authored Oct 15, 2024
1 parent 150f95c commit ce844d3
Show file tree
Hide file tree
Showing 22 changed files with 499 additions and 343 deletions.
Original file line number Diff line number Diff line change
@@ -1,41 +1,19 @@
package pl.touk.nussknacker.engine.api.deployment

import pl.touk.nussknacker.engine.api.deployment.ScenarioActivityManager.ModificationResult

import scala.concurrent.Future

trait ScenarioActivityManager {

def saveActivity(
scenarioActivity: ScenarioActivity
activity: DeploymentRelatedActivity
): Future[Unit]

def modifyActivity(
scenarioActivityId: ScenarioActivityId,
modify: ScenarioActivity => ScenarioActivity,
): Future[ModificationResult]

}

object ScenarioActivityManager {
sealed trait ModificationResult

object ModificationResult {
case object Success extends ModificationResult
case object Failure extends ModificationResult
}

}

object NoOpScenarioActivityManager extends ScenarioActivityManager {

def saveActivity(
scenarioActivity: ScenarioActivity
activity: DeploymentRelatedActivity
): Future[Unit] = Future.unit

def modifyActivity(
scenarioActivityId: ScenarioActivityId,
modify: ScenarioActivity => ScenarioActivity,
): Future[ModificationResult] = Future.successful(ModificationResult.Success)

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ import pl.touk.nussknacker.engine.api.deployment.ScenarioActivityHandling.{
AllScenarioActivitiesStoredByNussknacker,
ManagerSpecificScenarioActivitiesStoredByManager
}
import pl.touk.nussknacker.engine.api.deployment.{
ScenarioActivity,
ScenarioActivityId,
ScenarioAttachment,
ScenarioComment
}
import pl.touk.nussknacker.engine.api.deployment.{ScenarioActivity, _}
import pl.touk.nussknacker.engine.api.process.{ProcessId, ProcessIdWithName, ProcessName}
import pl.touk.nussknacker.security.Permission
import pl.touk.nussknacker.security.Permission.Permission
Expand Down Expand Up @@ -233,9 +228,22 @@ class ScenarioActivityApiHttpService(
case None =>
Future.successful(List.empty)
}
combinedActivities = (generalActivities ++ deploymentManagerSpecificActivities).map(toDto)
sortedCombinedActivities = combinedActivities.toList.sortBy(_.date)
} yield sortedCombinedActivities
combinedActivities = generalActivities ++ deploymentManagerSpecificActivities
// The API endpoint returning scenario activities does not yet have support for filtering. We made a decision to:
// - for activities not related to deployments: always display them on FE
// - for activities related to batch deployments: always display them on FE
// - for activities related to non-batch deployments: display on FE only those, that represent successful operations
combinedSuccessfulActivities = combinedActivities.filter {
case _: BatchDeploymentRelatedActivity => true
case activity: DeploymentRelatedActivity =>
activity.result match {
case _: DeploymentResult.Success => true
case _: DeploymentResult.Failure => false
}
case _ => true
}
sortedResult = combinedSuccessfulActivities.map(toDto).toList.sortBy(_.date)
} yield sortedResult
}

private def toDto(scenarioComment: ScenarioComment): Dtos.ScenarioActivityComment = {
Expand Down Expand Up @@ -297,36 +305,37 @@ class ScenarioActivityApiHttpService(
date = date,
scenarioVersionId = scenarioVersionId.map(_.value)
)
case ScenarioActivity.ScenarioDeployed(_, scenarioActivityId, user, date, scenarioVersionId, comment) =>
case ScenarioActivity.ScenarioDeployed(_, scenarioActivityId, user, date, scenarioVersionId, comment, _) =>
Dtos.ScenarioActivity.forScenarioDeployed(
id = scenarioActivityId.value,
user = user.name.value,
date = date,
scenarioVersionId = scenarioVersionId.map(_.value),
comment = toDto(comment),
)
case ScenarioActivity.ScenarioPaused(_, scenarioActivityId, user, date, scenarioVersionId, comment) =>
case ScenarioActivity.ScenarioPaused(_, scenarioActivityId, user, date, scenarioVersionId, comment, _) =>
Dtos.ScenarioActivity.forScenarioPaused(
id = scenarioActivityId.value,
user = user.name.value,
date = date,
scenarioVersionId = scenarioVersionId.map(_.value),
comment = toDto(comment),
)
case ScenarioActivity.ScenarioCanceled(_, scenarioActivityId, user, date, scenarioVersionId, comment) =>
case ScenarioActivity.ScenarioCanceled(_, scenarioActivityId, user, date, scenarioVersionId, comment, _) =>
Dtos.ScenarioActivity.forScenarioCanceled(
id = scenarioActivityId.value,
user = user.name.value,
date = date,
scenarioVersionId = scenarioVersionId.map(_.value),
comment = toDto(comment),
)
case ScenarioActivity.ScenarioModified(_, scenarioActivityId, user, date, scenarioVersionId, comment) =>
case ScenarioActivity.ScenarioModified(_, scenarioActivityId, user, date, oldVersionId, newVersionId, comment) =>
Dtos.ScenarioActivity.forScenarioModified(
id = scenarioActivityId.value,
user = user.name.value,
date = date,
scenarioVersionId = scenarioVersionId.map(_.value),
previousScenarioVersionId = oldVersionId.map(_.value),
scenarioVersionId = newVersionId.map(_.value),
comment = toDto(comment),
)
case ScenarioActivity.ScenarioNameChanged(_, id, user, date, version, oldName, newName) =>
Expand Down Expand Up @@ -406,29 +415,29 @@ class ScenarioActivityApiHttpService(
date,
scenarioVersionId,
comment,
dateFinished,
status,
errorMessage,
result,
) =>
Dtos.ScenarioActivity.forPerformedSingleExecution(
id = scenarioActivityId.value,
user = user.name.value,
date = date,
scenarioVersionId = scenarioVersionId.map(_.value),
comment = toDto(comment),
dateFinished = dateFinished,
status = status,
errorMessage = errorMessage,
dateFinished = result.dateFinished,
errorMessage = result match {
case DeploymentResult.Success(_) => None
case DeploymentResult.Failure(_, errorMessage) => errorMessage
},
)
case ScenarioActivity.PerformedScheduledExecution(
_,
scenarioActivityId,
user,
date,
scenarioVersionId,
scheduledExecutionStatus,
dateFinished,
scheduleName,
status,
createdAt,
nextRetryAt,
retriesLeft,
Expand All @@ -440,7 +449,7 @@ class ScenarioActivityApiHttpService(
scenarioVersionId = scenarioVersionId.map(_.value),
dateFinished = dateFinished,
scheduleName = scheduleName,
status = status,
scheduledExecutionStatus = scheduledExecutionStatus,
createdAt = createdAt,
retriesLeft = retriesLeft,
nextRetryAt = nextRetryAt,
Expand All @@ -452,17 +461,24 @@ class ScenarioActivityApiHttpService(
date,
scenarioVersionId,
changes,
errorMessage,
) =>
Dtos.ScenarioActivity.forAutomaticUpdate(
id = scenarioActivityId.value,
user = user.name.value,
date = date,
scenarioVersionId = scenarioVersionId.map(_.value),
changes = changes,
errorMessage = errorMessage,
)
case ScenarioActivity.CustomAction(_, scenarioActivityId, user, date, scenarioVersionId, actionName, comment) =>
case ScenarioActivity.CustomAction(
_,
scenarioActivityId,
user,
date,
scenarioVersionId,
actionName,
comment,
result,
) =>
Dtos.ScenarioActivity.forCustomAction(
id = scenarioActivityId.value,
user = user.name.value,
Expand All @@ -471,6 +487,10 @@ class ScenarioActivityApiHttpService(
actionName = actionName,
comment = toDto(comment),
customIcon = None,
errorMessage = result match {
case DeploymentResult.Success(_) => None
case DeploymentResult.Failure(_, errorMessage) => errorMessage
},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ object Dtos {
}

case object ScenarioModified extends ScenarioActivityType {
override def displayableName: String = "New version saved"
override def displayableName: String = "Scenario modified"
override def icon: String = "/assets/activities/scenarioModified.svg"
override def supportedActions: List[String] = commentRelatedActions ::: "compare" :: Nil
}
Expand Down Expand Up @@ -442,6 +442,7 @@ object Dtos {
id: UUID,
user: String,
date: Instant,
previousScenarioVersionId: Option[Long],
scenarioVersionId: Option[Long],
comment: ScenarioActivityComment,
): ScenarioActivity = ScenarioActivity(
Expand All @@ -453,9 +454,19 @@ object Dtos {
comment = Some(comment),
attachment = None,
additionalFields = List.empty,
overrideDisplayableName = scenarioVersionId.map(version => s"Version $version saved"),
overrideDisplayableName = updatedVersionId(previousScenarioVersionId, scenarioVersionId).map(updatedVersion =>
s"Version $updatedVersion saved"
)
)

private def updatedVersionId(oldVersionIdOpt: Option[Long], newVersionIdOpt: Option[Long]) = {
for {
newVersionId <- newVersionIdOpt
oldVersionIdOrZero = oldVersionIdOpt.getOrElse(0L)
updatedVersionId <- if (newVersionId > oldVersionIdOrZero) Some(newVersionId) else None
} yield updatedVersionId
}

def forScenarioNameChanged(
id: UUID,
user: String,
Expand Down Expand Up @@ -586,8 +597,7 @@ object Dtos {
date: Instant,
scenarioVersionId: Option[Long],
comment: ScenarioActivityComment,
dateFinished: Option[Instant],
status: Option[String],
dateFinished: Instant,
errorMessage: Option[String],
): ScenarioActivity = ScenarioActivity(
id = id,
Expand All @@ -598,8 +608,7 @@ object Dtos {
comment = Some(comment),
attachment = None,
additionalFields = List(
status.map(AdditionalField("status", _)),
dateFinished.map(date => AdditionalField("dateFinished", date.toString)),
Some(AdditionalField("dateFinished", dateFinished.toString)),
errorMessage.map(e => AdditionalField("errorMessage", e)),
).flatten
)
Expand All @@ -609,16 +618,14 @@ object Dtos {
user: String,
date: Instant,
scenarioVersionId: Option[Long],
dateFinished: Option[Instant],
dateFinished: Instant,
scheduleName: String,
status: ScheduledExecutionStatus,
scheduledExecutionStatus: ScheduledExecutionStatus,
createdAt: Instant,
nextRetryAt: Option[Instant],
retriesLeft: Option[Int],
): ScenarioActivity = {
val humanReadableStatus = status match {
case ScheduledExecutionStatus.Scheduled => "Scheduled"
case ScheduledExecutionStatus.Deployed => "Deployed"
val humanReadableStatus = scheduledExecutionStatus match {
case ScheduledExecutionStatus.Finished => "Execution finished"
case ScheduledExecutionStatus.Failed => "Execution failed"
case ScheduledExecutionStatus.DeploymentWillBeRetried => "Deployment will be retried"
Expand All @@ -635,7 +642,7 @@ object Dtos {
additionalFields = List(
Some(AdditionalField("status", humanReadableStatus)),
Some(AdditionalField("createdAt", createdAt.toString)),
dateFinished.map(date => AdditionalField("dateFinished", date.toString)),
Some(AdditionalField("dateFinished", dateFinished.toString)),
Some(AdditionalField("scheduleName", scheduleName)),
Some(AdditionalField("retriesLeft", retriesLeft.toString)),
nextRetryAt.map(nra => AdditionalField("nextRetryAt", nra.toString)),
Expand All @@ -651,7 +658,6 @@ object Dtos {
date: Instant,
scenarioVersionId: Option[Long],
changes: String,
errorMessage: Option[String],
): ScenarioActivity = ScenarioActivity(
id = id,
`type` = ScenarioActivityType.AutomaticUpdate,
Expand All @@ -661,9 +667,8 @@ object Dtos {
comment = None,
attachment = None,
additionalFields = List(
Some(AdditionalField("changes", changes)),
errorMessage.map(e => AdditionalField("errorMessage", e)),
).flatten
AdditionalField("changes", changes),
),
)

def forCustomAction(
Expand All @@ -674,6 +679,7 @@ object Dtos {
comment: ScenarioActivityComment,
actionName: String,
customIcon: Option[String],
errorMessage: Option[String],
): ScenarioActivity = ScenarioActivity(
id = id,
`type` = ScenarioActivityType.CustomAction,
Expand All @@ -683,8 +689,9 @@ object Dtos {
comment = Some(comment),
attachment = None,
additionalFields = List(
AdditionalField("actionName", actionName),
),
Some(AdditionalField("actionName", actionName)),
errorMessage.map(e => AdditionalField("errorMessage", e)),
).flatten,
overrideIcon = customIcon,
)

Expand Down
Loading

0 comments on commit ce844d3

Please sign in to comment.