com.lucidchart.piezo.admin.controllers.Triggers.scala Maven / Gradle / Ivy
The newest version!
package com.lucidchart.piezo.admin.controllers
import com.lucidchart.piezo.{TriggerHistoryModel, TriggerMonitoringModel, TriggerMonitoringPriority, WorkerSchedulerFactory}
import java.util.Date
import org.quartz.Trigger.TriggerState
import org.quartz._
import org.quartz.impl.triggers.{CronTriggerImpl, SimpleTriggerImpl}
import play.api._
import play.api.libs.json._
import play.api.mvc._
import com.lucidchart.piezo.admin.models._
import scala.collection.mutable
import scala.jdk.CollectionConverters._
import scala.util.Try
import play.api.Logging
import play.api.i18n.I18nSupport
class Triggers(schedulerFactory: WorkerSchedulerFactory, cc: ControllerComponents) extends AbstractController(cc) with Logging with ErrorLogging with play.api.i18n.I18nSupport {
val scheduler = logExceptions(schedulerFactory.getScheduler())
val properties = schedulerFactory.props
val triggerHistoryModel = logExceptions(new TriggerHistoryModel(properties))
val triggerMonitoringPriorityModel = logExceptions(new TriggerMonitoringModel(properties))
val triggerFormHelper = new TriggerFormHelper(scheduler)
def firesFirst(time: Date)(trigger1: Trigger, trigger2: Trigger): Boolean = {
val time1 = trigger1.getFireTimeAfter(time)
val time2 = trigger2.getFireTimeAfter(time)
if (time2 == null) true
else if (time1 == null) false
else if (time1 != time2) time1 before time2
else trigger1.getPriority > trigger2.getPriority
}
def getIndex = Action { implicit request =>
val now = new Date()
val allTriggers: List[Trigger] = TriggerHelper.getTriggersByGroup(scheduler).flatMap { case (group, triggerKeys) =>
triggerKeys.map(triggerKey => scheduler.getTrigger(triggerKey))
}.toList.sortWith(firesFirst(now))
Ok(
com.lucidchart.piezo.admin.views.html.triggers(
TriggerHelper.getTriggersByGroup(scheduler),
None,
allTriggers,
scheduler.getMetaData
)(request)
)
}
def getTrigger(group: String, name: String) = Action { implicit request =>
val triggerKey = new TriggerKey(name, group)
val triggerExists = scheduler.checkExists(triggerKey)
if (!triggerExists) {
val errorMsg = Some("Trigger " + group + " " + name + " not found")
NotFound(com.lucidchart.piezo.admin.views.html.trigger(mutable.Buffer(), None, None, errorMsg)(request))
} else {
try {
val triggerDetail = scheduler.getTrigger(triggerKey)
val history = {
try {
Some(triggerHistoryModel.getTrigger(triggerKey))
} catch {
case e: Exception => {
logger.error("Failed to get trigger history")
None
}
}
}
val (triggerMonitoringPriority, triggerMaxErrorTime, triggerMonitoringTeam) = Try {
triggerMonitoringPriorityModel.getTriggerMonitoringRecord(
triggerDetail.getKey
).map { triggerMonitoringRecord =>
(triggerMonitoringRecord.priority, triggerMonitoringRecord.maxSecondsInError, triggerMonitoringRecord.monitoringTeam)
}.getOrElse((TriggerMonitoringPriority.Low, 300, None))
}.getOrElse {
logger.error("Failed to get trigger monitoring info")
(TriggerMonitoringPriority.Low, 300, None)
}
Ok(
com.lucidchart.piezo.admin.views.html.trigger(
TriggerHelper.getTriggersByGroup(scheduler),
Some(triggerDetail),
history,
None,
Some(triggerMonitoringPriority),
triggerMaxErrorTime,
triggerMonitoringTeam,
triggerState = Some(scheduler.getTriggerState(triggerKey))
)(request)
)
} catch {
case e: Exception => {
val errorMsg = "Exception caught getting trigger " + group + " " + name + ". -- " + e.getLocalizedMessage()
logger.error(errorMsg, e)
InternalServerError(
com.lucidchart.piezo.admin.views.html.trigger(
mutable.Buffer(),
None,
None,
Some(errorMsg)
)(request)
)
}
}
}
}
def deleteTrigger(group: String, name: String) = Action { implicit request =>
val triggerKey = new TriggerKey(name, group)
val triggerExists = scheduler.checkExists(triggerKey)
if (!triggerExists) {
val errorMsg = Some("Trigger " + group + " " + name + " not found")
NotFound(com.lucidchart.piezo.admin.views.html.trigger(mutable.Buffer(), None, None, errorMsg)(request))
} else {
try {
scheduler.unscheduleJob(triggerKey)
triggerMonitoringPriorityModel.deleteTriggerMonitoringRecord(triggerKey)
Ok(
com.lucidchart.piezo.admin.views.html.trigger(
TriggerHelper.getTriggersByGroup(scheduler),
None,
None
)(request)
)
} catch {
case e: Exception => {
val errorMsg = "Exception caught deleting trigger " + group + " " + name + ". -- " + e.getLocalizedMessage()
logger.error(errorMsg, e)
InternalServerError(
com.lucidchart.piezo.admin.views.html.trigger(
mutable.Buffer(),
None,
None,
Some(errorMsg)
)(request)
)
}
}
}
}
val formNewAction = routes.Triggers.postTrigger()
def formEditAction(group: String, name: String): Call = routes.Triggers.putTrigger(group, name)
def getNewTriggerForm(
triggerType: String = "cron",
jobGroup: String = "",
jobName: String = "",
templateGroup: Option[String] = None,
templateName: Option[String] = None
) = Action { implicit request =>
templateGroup match {
case Some(group) => getEditTrigger(group, templateName.get, true)
case None =>
val dummyTrigger = triggerType match {
case "cron" => new DummyCronTrigger(jobGroup, jobName)
case "simple" => new DummySimpleTrigger(jobGroup, jobName)
}
val newTriggerForm = triggerFormHelper.buildTriggerForm.fill(
(dummyTrigger, TriggerMonitoringPriority.Low, 300, None)
)
Ok(
com.lucidchart.piezo.admin.views.html.editTrigger(
TriggerHelper.getTriggersByGroup(scheduler),
newTriggerForm,
formNewAction,
false,
false
)
(request, implicitly)
)
}
}
def getEditTrigger(group: String, name: String, isTemplate: Boolean)(implicit request: Request[AnyContent]) = {
val triggerKey = new TriggerKey(name, group)
val triggerExists = scheduler.checkExists(triggerKey)
if (!triggerExists) {
val errorMsg = Some("Trigger " + group + " " + name + " not found")
NotFound(com.lucidchart.piezo.admin.views.html.trigger(mutable.Buffer(), None, None, errorMsg)(request))
} else {
val triggerDetail: Trigger = scheduler.getTrigger(triggerKey)
val (triggerMonitoringPriority, triggerMaxErrorTime, triggerMonitoringTeam) = Try {
triggerMonitoringPriorityModel.getTriggerMonitoringRecord(
triggerDetail.getKey,
).map { triggerMonitoringRecord =>
(triggerMonitoringRecord.priority, triggerMonitoringRecord.maxSecondsInError, triggerMonitoringRecord.monitoringTeam)
}.getOrElse((TriggerMonitoringPriority.Low, 300, None))
}.getOrElse {
logger.error("Failed to get trigger monitoring info")
(TriggerMonitoringPriority.Low, 300, None)
}
val editTriggerForm = triggerFormHelper.buildTriggerForm.fill(
(triggerDetail, triggerMonitoringPriority, triggerMaxErrorTime, triggerMonitoringTeam)
)
if (isTemplate) {
Ok(
com.lucidchart.piezo.admin.views.html.editTrigger(
TriggerHelper.getTriggersByGroup(scheduler),
editTriggerForm,
formNewAction,
false,
isTemplate
)(request, implicitly)
)
}
else {
Ok(
com.lucidchart.piezo.admin.views.html.editTrigger(
TriggerHelper.getTriggersByGroup(scheduler),
editTriggerForm,
formEditAction(group, name),
true,
isTemplate
)(request, implicitly)
)
}
}
}
def getEditTriggerAction(group: String, name: String) = Action { implicit request =>
getEditTrigger(group, name, false)
}
def putTrigger(group: String, name: String) = Action { implicit request =>
triggerFormHelper.buildTriggerForm.bindFromRequest().fold(
formWithErrors =>
BadRequest(
com.lucidchart.piezo.admin.views.html.editTrigger(
TriggerHelper.getTriggersByGroup(scheduler),
formWithErrors,
formEditAction(group, name),
true,
false
)
),
value => {
val (trigger, triggerMonitoringPriority, triggerMaxErrorTime, triggerMonitoringTeam) = value
scheduler.rescheduleJob(trigger.getKey(), trigger)
triggerMonitoringPriorityModel.setTriggerMonitoringRecord(
trigger.getKey,
triggerMonitoringPriority,
triggerMaxErrorTime,
triggerMonitoringTeam
)
Redirect(routes.Triggers.getTrigger(trigger.getKey.getGroup(), trigger.getKey.getName()))
.flashing("message" -> "Successfully added trigger.", "class" -> "")
}
)
}
def postTrigger() = Action { implicit request =>
triggerFormHelper.buildTriggerForm.bindFromRequest().fold(
formWithErrors =>
BadRequest(
com.lucidchart.piezo.admin.views.html.editTrigger(
TriggerHelper.getTriggersByGroup(scheduler),
formWithErrors,
formNewAction,
false,
false
)
),
value => {
val (trigger, triggerMonitoringPriority, triggerMaxErrorTime, triggerMonitoringTeam) = value
try {
scheduler.scheduleJob(trigger)
triggerMonitoringPriorityModel.setTriggerMonitoringRecord(
trigger.getKey,
triggerMonitoringPriority,
triggerMaxErrorTime,
triggerMonitoringTeam
)
Redirect(routes.Triggers.getTrigger(trigger.getKey.getGroup(), trigger.getKey.getName()))
.flashing("message" -> "Successfully added trigger.", "class" -> "")
} catch {
case alreadyExists: ObjectAlreadyExistsException =>
val form = triggerFormHelper.buildTriggerForm.fill(
(trigger, triggerMonitoringPriority, triggerMaxErrorTime, triggerMonitoringTeam)
)
Ok(
com.lucidchart.piezo.admin.views.html.editTrigger(
TriggerHelper.getTriggersByGroup(scheduler),
form,
formNewAction,
false,
false,
errorMessage = Some("Please provide unique group-name pair")
)(request, implicitly)
)
}
}
)
}
def triggerGroupTypeAhead(sofar: String) = Action { implicit request =>
val groups = scheduler.getTriggerGroupNames().asScala.toList
Ok(Json.obj("groups" -> groups.filter{ group =>
group.toLowerCase.contains(sofar.toLowerCase)
}))
}
def triggerJob(group: String, name: String) = Action { implicit request =>
val jobKey = new JobKey(name, group)
if (scheduler.checkExists(jobKey)) {
try {
scheduler.triggerJob(jobKey)
Ok
} catch {
case e: SchedulerException => {
logger.error("Exception caught triggering job %s %s. -- %s".format(group, name, e.getLocalizedMessage), e)
InternalServerError
}
}
} else {
NotFound
}
}
def patchTrigger(group: String, name: String) = Action { implicit request =>
val triggerKey = new TriggerKey(name, group)
val triggerExists = scheduler.checkExists(triggerKey)
if (!triggerExists) {
NotFound(com.lucidchart.piezo.admin.views.html.trigger(
mutable.Buffer(),
None,
None,
errorMessage = Some(s"Trigger $group:$name not found"))(request)
)
} else {
request.body.asJson.map { json =>
(json \ "state").asOpt[String].map { state =>
if(state.equalsIgnoreCase(TriggerState.PAUSED.toString)) {
scheduler.pauseTrigger(triggerKey)
} else {
val currentState = scheduler.getTriggerState(triggerKey).toString
if(currentState == TriggerState.ERROR.toString) {
val trigger = scheduler.getTrigger(triggerKey)
scheduler.rescheduleJob(triggerKey, trigger)
} else {
scheduler.resumeTrigger(triggerKey)
}
}
Ok(Json.obj("state" -> scheduler.getTriggerState(triggerKey).toString))
}.getOrElse {
BadRequest("Missing parameter [state]")
}
}.getOrElse {
BadRequest("Expecting Json data")
}
}
}
private trait DummyTrigger extends Trigger {
override def getKey() = { new TriggerKey("", "") }
override def getJobKey() = { new JobKey("", "") }
override def getDescription() = ""
}
private class DummyCronTrigger(jobGroup: String, jobName: String) extends CronTriggerImpl with DummyTrigger {
override def getCronExpression() = "7 7 7 * * ?"
override def getJobKey() = { new JobKey(jobName, jobGroup)}
}
private class DummySimpleTrigger(jobGroup: String, jobName: String) extends SimpleTriggerImpl with DummyTrigger {
override def getJobKey() = { new JobKey(jobName, jobGroup)}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy