Skip to content

Commit

Permalink
Merge pull request #62 from jjudd/add-monitoring-priority
Browse files Browse the repository at this point in the history
Adding monitoring priority to all triggers.
  • Loading branch information
jjudd authored Nov 8, 2016
2 parents 25df15a + 33380c4 commit 452486f
Show file tree
Hide file tree
Showing 22 changed files with 317 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package com.lucidchart.piezo.admin.controllers

import com.lucidchart.piezo.TriggerMonitoringPriority
import com.lucidchart.piezo.TriggerMonitoringPriority.TriggerMonitoringPriority
import org.quartz._
import scala.Some
import scala.Some
import scala.Some
import java.text.ParseException
import play.api.data.validation.{Valid, ValidationError, Invalid, Constraint}
import play.api.data.validation.{Constraint, Invalid, Valid}
import play.api.data.Form
import play.api.data.Forms._
import scala.Some
import play.api.data.validation.ValidationError


class TriggerFormHelper(scheduler: Scheduler) extends JobDataHelper {

private def simpleScheduleFormApply(repeatCount: Int, repeatInterval: Int): SimpleScheduleBuilder = {
Expand All @@ -35,7 +32,8 @@ class TriggerFormHelper(scheduler: Scheduler) extends JobDataHelper {
}

private def triggerFormApply(triggerType: String, group: String, name: String, jobGroup: String, jobName: String, description: String,
simple: Option[SimpleScheduleBuilder], cron: Option[CronScheduleBuilder], jobDataMap: Option[JobDataMap]): Trigger = {
simple: Option[SimpleScheduleBuilder], cron: Option[CronScheduleBuilder], jobDataMap: Option[JobDataMap],
triggerMonitoringPriority: String): (Trigger, TriggerMonitoringPriority) = {
val newTrigger: Trigger = TriggerBuilder.newTrigger()
.withIdentity(name, group)
.withDescription(description)
Expand All @@ -47,19 +45,22 @@ class TriggerFormHelper(scheduler: Scheduler) extends JobDataHelper {
.forJob(jobName, jobGroup)
.usingJobData(jobDataMap.getOrElse(new JobDataMap()))
.build()
newTrigger
(newTrigger, TriggerMonitoringPriority.withName(triggerMonitoringPriority))
}

private def triggerFormUnapply(trigger: Trigger):
Option[(String, String, String, String, String, String, Option[SimpleScheduleBuilder], Option[CronScheduleBuilder], Option[JobDataMap])] = {
private def triggerFormUnapply(tp: (Trigger, TriggerMonitoringPriority)):
Option[(String, String, String, String, String, String, Option[SimpleScheduleBuilder], Option[CronScheduleBuilder], Option[JobDataMap], String)] = {
val trigger = tp._1
val triggerMonitoringPriority = tp._2
val (triggerType: String, simple, cron) = trigger match {
case cron: CronTrigger => ("cron", None, Some(cron.getScheduleBuilder))
case simple: SimpleTrigger => ("simple", Some(simple.getScheduleBuilder), None)
}
val description = if (trigger.getDescription() == null) "" else trigger.getDescription()
Some((triggerType, trigger.getKey.getGroup(), trigger.getKey.getName(),
trigger.getJobKey.getGroup(), trigger.getJobKey.getName(), description,
simple.asInstanceOf[Option[SimpleScheduleBuilder]], cron.asInstanceOf[Option[CronScheduleBuilder]], Some(trigger.getJobDataMap)))
simple.asInstanceOf[Option[SimpleScheduleBuilder]], cron.asInstanceOf[Option[CronScheduleBuilder]], Some(trigger.getJobDataMap),
triggerMonitoringPriority.toString))
}

private def getCronParseError(cronExpression: String): String = {
Expand Down Expand Up @@ -87,7 +88,7 @@ class TriggerFormHelper(scheduler: Scheduler) extends JobDataHelper {
}
}

def buildTriggerForm() = Form[Trigger](
def buildTriggerForm() = Form[(Trigger, TriggerMonitoringPriority)](
mapping(
"triggerType" -> nonEmptyText(),
"group" -> nonEmptyText(),
Expand All @@ -102,9 +103,10 @@ class TriggerFormHelper(scheduler: Scheduler) extends JobDataHelper {
"cron" -> optional(mapping(
"cronExpression" -> nonEmptyText().verifying(validCronExpression)
)(cronScheduleFormApply)(cronScheduleFormUnapply)),
"job-data-map" -> jobDataMap
)(triggerFormApply)(triggerFormUnapply) verifying("Job does not exist", trigger => {
scheduler.checkExists(trigger.getJobKey)
"job-data-map" -> jobDataMap,
"triggerMonitoringPriority" -> nonEmptyText()
)(triggerFormApply)(triggerFormUnapply) verifying("Job does not exist", fields => {
scheduler.checkExists(fields._1.getJobKey)
})
)
}
86 changes: 53 additions & 33 deletions admin/app/com/lucidchart/piezo/admin/controllers/Triggers.scala
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
package com.lucidchart.piezo.admin.controllers

import com.lucidchart.piezo.{TriggerHistoryModel, TriggerMonitoringPriority, TriggerMonitoringPriorityModel, WorkerSchedulerFactory}
import java.util.Date
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.{TriggerHistoryModel, WorkerSchedulerFactory}
import org.quartz._
import impl.matchers.GroupMatcher

import scala.collection.JavaConverters._
import scala.collection.mutable
import play.api.data.{Form, FormError}
import play.api.data.Forms._
import play.api.data.validation.Constraints._

import java.util.{Date, TimeZone}
import org.quartz.impl.triggers.{CronTriggerImpl, SimpleTriggerImpl}

import play.api.data.format.Formatter
import java.text.ParseException

import org.quartz.Trigger.TriggerTimeComparator
import play.api.data.validation.{Constraint, Invalid, Valid, ValidationError}
import play.api.libs.json._
import scala.util.Try

object Triggers extends Triggers(new WorkerSchedulerFactory())

Expand All @@ -30,6 +19,7 @@ class Triggers(schedulerFactory: WorkerSchedulerFactory) extends Controller {
val scheduler = logExceptions(schedulerFactory.getScheduler())
val properties = schedulerFactory.props
val triggerHistoryModel = logExceptions(new TriggerHistoryModel(properties))
val triggerMonitoringPriorityModel = logExceptions(new TriggerMonitoringPriorityModel(properties))
val triggerFormHelper = new TriggerFormHelper(scheduler)

def firesFirst(time: Date)(trigger1: Trigger, trigger2: Trigger): Boolean = {
Expand Down Expand Up @@ -57,7 +47,7 @@ class Triggers(schedulerFactory: WorkerSchedulerFactory) extends Controller {
NotFound(com.lucidchart.piezo.admin.views.html.trigger(mutable.Buffer(), None, None, errorMsg)(request))
} else {
try {
val triggerDetail: Option[Trigger] = Some(scheduler.getTrigger(triggerKey))
val triggerDetail = scheduler.getTrigger(triggerKey)

val history = {
try {
Expand All @@ -70,7 +60,24 @@ class Triggers(schedulerFactory: WorkerSchedulerFactory) extends Controller {
}
}

Ok(com.lucidchart.piezo.admin.views.html.trigger(TriggerHelper.getTriggersByGroup(scheduler), triggerDetail, history)(request))
val triggerMonitoringPriority = Try {
triggerMonitoringPriorityModel.getTriggerMonitoringPriority(
triggerDetail
).getOrElse(TriggerMonitoringPriority.Off)
}.getOrElse {
logger.error("Failed to get trigger monitoring priority")
TriggerMonitoringPriority.Off
}

Ok(
com.lucidchart.piezo.admin.views.html.trigger(
TriggerHelper.getTriggersByGroup(scheduler),
Some(triggerDetail),
history,
None,
Some(triggerMonitoringPriority)
)(request)
)
} catch {
case e: Exception => {
val errorMsg = "Exception caught getting trigger " + group + " " + name + ". -- " + e.getLocalizedMessage()
Expand All @@ -90,6 +97,7 @@ class Triggers(schedulerFactory: WorkerSchedulerFactory) extends Controller {
} else {
try {
scheduler.unscheduleJob(triggerKey)
triggerMonitoringPriorityModel.deleteTriggerMonitoringPriority(triggerKey)
Ok(com.lucidchart.piezo.admin.views.html.trigger(TriggerHelper.getTriggersByGroup(scheduler), None, None)(request))
} catch {
case e: Exception => {
Expand All @@ -104,16 +112,16 @@ class Triggers(schedulerFactory: WorkerSchedulerFactory) extends Controller {
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 =>
def getNewTriggerForm(triggerType: String = "cron", jobGroup: String = "", jobName: String = "", templateGroup: Option[String] = None, templateName: Option[String] = None, triggerMonitoringPriority: TriggerMonitoringPriority.Value = TriggerMonitoringPriority.Off) = 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)
Ok(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), newTriggerForm, formNewAction, false, false)(request))
val newTriggerForm = triggerFormHelper.buildTriggerForm().fill((dummyTrigger, TriggerMonitoringPriority.Off))
Ok(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), newTriggerForm, triggerMonitoringPriority, formNewAction, false, false)(request))
}
}

Expand All @@ -125,9 +133,17 @@ class Triggers(schedulerFactory: WorkerSchedulerFactory) extends Controller {
NotFound(com.lucidchart.piezo.admin.views.html.trigger(mutable.Buffer(), None, None, errorMsg)(request))
} else {
val triggerDetail: Trigger = scheduler.getTrigger(triggerKey)
val editTriggerForm = triggerFormHelper.buildTriggerForm().fill(triggerDetail)
if (isTemplate) Ok(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), editTriggerForm, formNewAction, false, isTemplate)(request))
else Ok(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), editTriggerForm, formEditAction(group, name), true, isTemplate)(request))
val triggerMonitoringPriority = Try {
triggerMonitoringPriorityModel.getTriggerMonitoringPriority(
triggerDetail
).getOrElse(TriggerMonitoringPriority.Off)
}.getOrElse {
logger.error("Failed to get trigger monitoring priority")
TriggerMonitoringPriority.Off
}
val editTriggerForm = triggerFormHelper.buildTriggerForm().fill((triggerDetail, triggerMonitoringPriority))
if (isTemplate) Ok(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), editTriggerForm, triggerMonitoringPriority, formNewAction, false, isTemplate)(request))
else Ok(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), editTriggerForm, triggerMonitoringPriority, formEditAction(group, name), true, isTemplate)(request))
}
}

Expand All @@ -136,10 +152,12 @@ class Triggers(schedulerFactory: WorkerSchedulerFactory) extends Controller {
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)),
BadRequest(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), formWithErrors, TriggerMonitoringPriority.Off, formEditAction(group, name), true, false)),
value => {
scheduler.rescheduleJob(value.getKey(), value)
Redirect(routes.Triggers.getTrigger(value.getKey.getGroup(), value.getKey.getName()))
val (trigger, triggerMonitoringPriority) = value
scheduler.rescheduleJob(trigger.getKey(), trigger)
triggerMonitoringPriorityModel.setTriggerMonitoringPriority(trigger, triggerMonitoringPriority)
Redirect(routes.Triggers.getTrigger(trigger.getKey.getGroup(), trigger.getKey.getName()))
.flashing("message" -> "Successfully added trigger.", "class" -> "")
}
)
Expand All @@ -148,16 +166,18 @@ class Triggers(schedulerFactory: WorkerSchedulerFactory) extends Controller {
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)),
BadRequest(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), formWithErrors, TriggerMonitoringPriority.Off, formNewAction, false, false)),
value => {
val (trigger, triggerMonitoringPriority) = value
try {
scheduler.scheduleJob(value)
Redirect(routes.Triggers.getTrigger(value.getKey.getGroup(), value.getKey.getName()))
scheduler.scheduleJob(trigger)
triggerMonitoringPriorityModel.setTriggerMonitoringPriority(trigger, triggerMonitoringPriority)
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(value)
Ok(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), form, formNewAction, false, false, errorMessage = Some("Please provide unique group-name pair"))(request))
val form = triggerFormHelper.buildTriggerForm.fill((trigger, triggerMonitoringPriority))
Ok(com.lucidchart.piezo.admin.views.html.editTrigger(TriggerHelper.getTriggersByGroup(scheduler), form, triggerMonitoringPriority, formNewAction, false, false, errorMessage = Some("Please provide unique group-name pair"))(request))
}
}
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@(
triggersByGroup: scala.collection.mutable.Buffer[(String, scala.collection.immutable.List[org.quartz.TriggerKey])],
triggerForm: Form[org.quartz.Trigger],
triggerForm: Form[(org.quartz.Trigger, com.lucidchart.piezo.TriggerMonitoringPriority.Value)],
triggerMonitoringPriority: com.lucidchart.piezo.TriggerMonitoringPriority.TriggerMonitoringPriority = com.lucidchart.piezo.TriggerMonitoringPriority.Off,
formAction: play.api.mvc.Call,
existing: Boolean,
isTemplate: Boolean,
Expand All @@ -11,6 +12,7 @@
request: play.api.mvc.Request[AnyContent]
)

@import com.lucidchart.piezo.TriggerMonitoringPriority
@import com.lucidchart.piezo.admin.controllers.{routes=>piezoRoutes}
@import com.lucidchart.piezo.admin.views
@import java.net.URLEncoder
Expand Down Expand Up @@ -64,6 +66,8 @@ <h4 class="text-danger">@triggerForm.errors.filter(_.key == "").map(_.message).m
<input type="text" class="job-name-type-ahead form-control form-inline-control " name="@name" id="@id" @toHtmlArgs(args)>
}
}
@helper.select(triggerForm("triggerMonitoringPriority"), TriggerMonitoringPriority.values.toList.map(tp => tp.toString -> tp.toString), '_label -> "Monitoring Priority", 'labelClass -> "col-sm-2 text-right", 'inputDivClass -> "col-sm-4", 'class -> "form-control", 'placeholder -> TriggerMonitoringPriority.Off)

@helper.input(triggerForm("description"), '_label -> "Description", 'labelClass -> "col-sm-2 text-right", 'inputDivClass -> "col-sm-10", 'placeholder -> "Description", 'value-> triggerForm.data.get("description").getOrElse("")) { (id, name, value, args) =>
<input type="text" class="form-control form-inline-control " name="@name" id="@id" @toHtmlArgs(args)>
}
Expand Down
10 changes: 9 additions & 1 deletion admin/app/com/lucidchart/piezo/admin/views/trigger.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
triggersByGroup: scala.collection.mutable.Buffer[(String, scala.collection.immutable.List[org.quartz.TriggerKey])],
currentTrigger: Option[org.quartz.Trigger],
triggerHistory: Option[List[com.lucidchart.piezo.TriggerRecord]],
errorMessage: Option[String] = None
errorMessage: Option[String] = None,
triggerMonitoringPriority: Option[com.lucidchart.piezo.TriggerMonitoringPriority.Value] = None
)(
implicit
request: play.api.mvc.Request[AnyContent]
)

@import com.lucidchart.piezo.TriggerMonitoringPriority
@import com.lucidchart.piezo.admin.controllers.{routes=>piezoRoutes}
@import com.lucidchart.piezo.admin.views
@import java.net.URLEncoder
Expand Down Expand Up @@ -117,6 +119,12 @@ <h4>This will permanently delete the trigger!</h4>
}
case _ => { }
}
@triggerMonitoringPriority.map { triggerMonitoringPriority =>
<tr>
<td class="text-right">Monitoring priority:</td>
<td>@triggerMonitoringPriority</td>
</tr>
}
<tr>
<td class="text-right">Description:</td>
<td>
Expand Down
2 changes: 1 addition & 1 deletion admin/project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ object ApplicationBuild extends Build {
jdbc,
anorm,
"org.quartz-scheduler" % "quartz" % "2.1.7",
"com.lucidchart" %% "piezo-worker" % "1.14"
"com.lucidchart" %% "piezo-worker" % "1.15"
)

val main = Project(appName, file(".")).enablePlugins(play.PlayScala).settings(
Expand Down
2 changes: 1 addition & 1 deletion worker/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name := "piezo-worker"

organization := "com.lucidchart"

version := "1.14"
version := "1.15"

scalaVersion := "2.11.7"

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions worker/src/main/resources/piezo_mysql_3.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

ALTER TABLE `job_history`
MODIFY COLUMN trigger_name VARCHAR(100) NOT NULL,
MODIFY COLUMN trigger_group VARCHAR(100) NOT NULL,
MODIFY COLUMN job_name VARCHAR(100) NOT NULL,
MODIFY COLUMN job_group VARCHAR(100) NOT NULL,
DROP KEY job_key,
ADD KEY job_key (job_group, job_name, start);

ALTER TABLE `trigger_history`
MODIFY COLUMN trigger_name VARCHAR(100) NOT NULL,
MODIFY COLUMN trigger_group VARCHAR(100) NOT NULL;
8 changes: 8 additions & 0 deletions worker/src/main/resources/piezo_mysql_4.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE trigger_monitoring_priority(
trigger_name VARCHAR(190) NOT NULL,
trigger_group VARCHAR(190) NOT NULL,
priority TINYINT DEFAULT NULL,
created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(trigger_group, trigger_name)
);
3 changes: 3 additions & 0 deletions worker/src/main/resources/piezo_mysql_5.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
INSERT INTO trigger_monitoring_priority (trigger_name, trigger_group, priority)
SELECT TRIGGER_NAME, TRIGGER_GROUP, 3 from QRTZ_TRIGGERS;

1 change: 1 addition & 0 deletions worker/src/main/resources/quartz.properties
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ org.quartz.dataSource.jobs.validationQuery: select 0
org.quartz.plugin.triggHistory.class: org.quartz.plugins.history.LoggingJobHistoryPlugin

com.lucidchart.piezo.heartbeatFile: /tmp/piezo/workerHeartbeatFile
com.lucidchart.piezo.monitoringPriorityStyle: new
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 452486f

Please sign in to comment.