All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.touk.nussknacker.ui.process.newdeployment.DeploymentRepository.scala Maven / Gradle / Ivy

There is a newer version: 1.17.0
Show newest version
package pl.touk.nussknacker.ui.process.newdeployment

import cats.implicits.{toFoldableOps, toTraverseOps}
import db.util.DBIOActionInstances._
import pl.touk.nussknacker.engine.api.deployment.{DeploymentStatus, DeploymentStatusName, ProblemDeploymentStatus}
import pl.touk.nussknacker.engine.api.process.{ProcessId, ProcessingType}
import pl.touk.nussknacker.engine.newdeployment.DeploymentId
import pl.touk.nussknacker.ui.db.entity.ProcessEntityData
import pl.touk.nussknacker.ui.db.{DbRef, NuTables, SqlStates}
import pl.touk.nussknacker.ui.process.newdeployment.DeploymentEntityFactory.DeploymentEntityData
import pl.touk.nussknacker.ui.process.newdeployment.DeploymentRepository.{
  ConflictingDeploymentIdError,
  DeploymentWithScenarioMetadata
}
import slick.jdbc.JdbcProfile

import java.sql.{SQLException, Timestamp}
import java.time.Clock
import scala.concurrent.ExecutionContext

class DeploymentRepository(dbRef: DbRef, clock: Clock)(implicit ec: ExecutionContext) extends NuTables {

  override protected val profile: JdbcProfile = dbRef.profile

  import profile.api._

  def getProcessingTypeDeploymentsIdsInNotMatchingStatus(
      processingType: ProcessingType,
      statusNames: Set[DeploymentStatusName]
  ): DB[Set[DeploymentId]] = {
    toEffectAll(
      deploymentsTable
        .join(processesTable)
        .on(_.scenarioId === _.id)
        .filter { case (deployment, scenarioMetadata) =>
          scenarioMetadata.processingType === processingType && !(deployment.statusName inSet statusNames)
        }
        .map(_._1.id)
        .result
        .map(_.toSet)
    )
  }

  def getScenarioDeploymentsInNotMatchingStatus(
      scenarioId: ProcessId,
      statusNames: Set[DeploymentStatusName]
  ): DB[Seq[DeploymentEntityData]] = {
    toEffectAll(deploymentsTable.filter(d => d.scenarioId === scenarioId && !(d.statusName inSet statusNames)).result)
  }

  def saveDeployment(deployment: DeploymentEntityData): DB[Either[ConflictingDeploymentIdError, Unit]] = {
    toEffectAll(deploymentsTable += deployment).asTry.map(
      _.map(_ => Right(()))
        .recover {
          case e: SQLException if e.getSQLState == SqlStates.UniqueViolation =>
            Left(ConflictingDeploymentIdError(deployment.id))
        }
        .get
    )
  }

  def getDeploymentById(id: DeploymentId): DB[Option[DeploymentWithScenarioMetadata]] = {
    toEffectAll(
      deploymentsTable
        .filter(_.id === id)
        .join(processesTable)
        .on(_.scenarioId === _.id)
        .take(1)
        .result
        .headOption
        .map(_.map(DeploymentWithScenarioMetadata.apply _ tupled))
    )
  }

  def updateDeploymentStatuses(statusesToUpdate: Map[DeploymentId, DeploymentStatus]): DB[Set[DeploymentId]] = {
    statusesToUpdate.toList
      .map { case (id, status) =>
        toEffectAll(
          updateDeploymentStatus(id, status).map(updated => if (updated) Set(id) else Set.empty[DeploymentId])
        )
      }
      .sequence
      .map(_.combineAll)
  }

  def updateDeploymentStatus(id: DeploymentId, status: DeploymentStatus): DB[Boolean] = {
    val problemDescription = ProblemDeploymentStatus.extractDescription(status)
    toEffectAll(
      deploymentsTable
        .filter(d => d.id === id && (d.statusName =!= status.name || d.statusProblemDescription =!= problemDescription))
        .map(d => (d.statusName, d.statusProblemDescription, d.statusModifiedAt))
        .update((status.name, problemDescription, Timestamp.from(clock.instant())))
        .map(_ > 0)
    )
  }

}

object DeploymentRepository {

  final case class ConflictingDeploymentIdError(id: DeploymentId)

  final case class DeploymentWithScenarioMetadata(deployment: DeploymentEntityData, scenarioMetadata: ProcessEntityData)

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy