Skip to content

Commit

Permalink
Added renaming of configs and a button to stop all running jobs at once
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikTromp committed Oct 16, 2016
1 parent 0414398 commit 68d023d
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 13 deletions.
56 changes: 45 additions & 11 deletions app/controllers/Monitor.scala
Expand Up @@ -33,8 +33,8 @@ object Monitor extends Controller {
// Get the monitor overview result
val fut = (Akka.system.actorSelection("user/TuktuMonitor") ? new MonitorOverviewRequest).asInstanceOf[Future[MonitorOverviewResult]]
fut.map(res => {
val sortedRunningJobs = res.runningJobs.toList.sortWith((a,b) => a._2.startTime > b._2.startTime)
val sortedFinishedJobs = res.finishedJobs.toList.sortWith((a,b) => a._2.endTime.getOrElse(a._2.startTime) > b._2.endTime.getOrElse(b._2.startTime))
val sortedRunningJobs = res.runningJobs.toList.sortWith((a, b) => a._2.startTime > b._2.startTime)
val sortedFinishedJobs = res.finishedJobs.toList.sortWith((a, b) => a._2.endTime.getOrElse(a._2.startTime) > b._2.endTime.getOrElse(b._2.startTime))
// If we are out of range, go back into range
if (runningPage < 1 || runningPage > math.max(math.ceil(sortedRunningJobs.size / 100.0), 1) || finishedPage < 1 || finishedPage > math.max(math.ceil(sortedFinishedJobs.size / 100.0), 1))
Redirect(routes.Monitor.fetchLocalInfo(
Expand Down Expand Up @@ -84,6 +84,23 @@ object Monitor extends Controller {
Ok(Json.arr(res._1, res._2))
})
}

/**
* Renames a config file
*/
def rename() = Action { implicit request =>
// Get the variables we need
val data = request.body.asFormUrlEncoded.getOrElse(Map[String, Seq[String]]())
val oldPath = data("old").head + ".json"
val newName = data("new").head + ".json"

// Rename old file to new
val configsRepo = Cache.getOrElse[String]("configRepo")("configs")
val path = Paths.get(configsRepo + "/" + oldPath).toAbsolutePath.normalize
Files.move(path, path.resolveSibling(newName))

Ok("")
}

/**
* Terminates a Tuktu job
Expand All @@ -102,6 +119,22 @@ object Monitor extends Controller {
} + " job " + uuid))
}

/**
* Terminates all jobs currently running
*/
def terminateAll() = Action.async {
// Get all the runnign jobs
val jobsFut = (Akka.system.actorSelection("user/TuktuMonitor") ? new MonitorOverviewRequest)
.asInstanceOf[Future[MonitorOverviewResult]]
jobsFut map {
case jobs: MonitorOverviewResult => {
for (job <- jobs.runningJobs) yield Akka.system.actorSelection("user/TuktuMonitor") ! new AppMonitorUUIDPacket(job._1, "stop")

Redirect(routes.Monitor.fetchLocalInfo(1, 1)).flashing("success" -> ("Successfully stopped all flows"))
}
}
}

/**
* Shows the form for getting configs
*/
Expand Down Expand Up @@ -154,9 +187,11 @@ object Monitor extends Controller {
/**
* Shows the start-job view
*/
def browseConfigs() = Action { implicit request => {
def browseConfigs() = Action { implicit request =>
{
Ok(views.html.monitor.browseConfigs(util.flashMessagesToMap(request)))
}}
}
}

case class job(
name: String)
Expand Down Expand Up @@ -222,14 +257,14 @@ object Monitor extends Controller {
// Get config repo
val configsRepo = Cache.getOrElse[String]("configRepo")("configs")
val configsPath = Paths.get(configsRepo).toAbsolutePath.normalize

// Get file
val filename = request.body.asFormUrlEncoded("path").headOption.getOrElse("") + "/" + fName.filename
val contentType = fName.contentType

// Get path, determine proper name
val withEnding = if (filename.endsWith(".json")) filename else filename + ".json"

// Check if absolute normalized path starts with configs repo and new file doesnt exist yet
val path = Paths.get(configsRepo, withEnding).toAbsolutePath.normalize
if (!path.startsWith(configsPath) || Files.exists(path))
Expand All @@ -240,7 +275,7 @@ object Monitor extends Controller {
else {
// First move the file
fName.ref.moveTo(new File(path.toString))

// Check for validity
val valid = try {
// Parse JSON into a JSObject
Expand All @@ -249,11 +284,10 @@ object Monitor extends Controller {
val generators = (json \ "generators").as[List[JsObject]]
val processors = (json \ "processors").as[List[JsObject]]
true
}
catch {
} catch {
case e: Exception => false
}

// Return properly, or not
if (valid) Redirect(routes.Monitor.browseConfigs)
else {
Expand Down
5 changes: 5 additions & 0 deletions app/views/monitor/showApps.scala.html
Expand Up @@ -5,6 +5,11 @@
} {
<h2>
The following jobs are currently running on Tuktu
@if(running.size > 1) {
<a href="@routes.Monitor.terminateAll">
<button class="pull-right btn btn-danger">Stop all jobs</button>
</a>
}
</h2>

@if(running.size > 100) {
Expand Down
35 changes: 33 additions & 2 deletions app/views/monitor/showConfigs.scala.html
Expand Up @@ -67,15 +67,15 @@ <h4 class="modal-title" id="uploadModalLabel">Upload Tuktu Config File</h4>
</div>

<table class="table table-hover" id="configTable">
@for(config <- configs) {
@for((config, idx) <- configs.zipWithIndex) {
<tr>
<td width="20px">
<input type="checkbox" value="@path.mkString("/")/@config">
</td>
<td>
<span aria-hidden="true" class="glyphicon glyphicon-file"> </span>
&nbsp;
@config
<span id="jobName_@idx" onclick="renameInitiate('jobName_@idx', '@path.mkString("/")/@config', '@config')">@config</span>
</td>
<td width="10%">
<form method="post" action="@routes.Monitor.startJob">
Expand All @@ -101,6 +101,37 @@ <h4 class="modal-title" id="uploadModalLabel">Upload Tuktu Config File</h4>
}

<script type="text/javascript">
function renameInitiate(elem, path, name) {
$("#" + elem).removeAttr('onclick');
$("#" + elem).html("<input type='text' value='" + name + "' onblur='renameComplete(\"" + elem + "\", this, \"" + path + "\", \"" + name + "\")'>");
}

function renameComplete(parent, elem, oldPath, oldName) {
var newName = $(elem).val();
console.log($('#' + parent));

$.ajax({
method : "POST",
url : "@routes.Monitor.rename",
data : {
old : oldPath,
new: newName
},
success: function() {
var arr = oldPath.split("/");
arr.pop();
var newPath = arr.join("/") + "/" + newName;

$("#" + parent).attr('onclick', "renameInitiate('" + parent + "', '" + newPath + "', '" + newName + "')");
$("#" + parent).html(newName);
},
error: function() {
$("#" + parent).attr('onclick', "renameInitiate('" + parent + "', '" + oldPath + "', '" + oldName + "')");
$("#" + parent).html(oldName);
}
});
}

function navigateFolder(folder) {
$.ajax({
method : "POST",
Expand Down
2 changes: 2 additions & 0 deletions conf/routes
Expand Up @@ -17,6 +17,8 @@ POST /sync controllers.Synchronous.loadJsonPost

# Monitoring
GET /terminate/:id/:force/:r/:f controllers.Monitor.terminate(id, force: Boolean, r: Int, f: Int)
GET /terminateAll controllers.Monitor.terminateAll
POST /rename controllers.Monitor.rename
POST /showConfigs controllers.Monitor.showConfigs
GET /browseConfigs controllers.Monitor.browseConfigs
POST /startJob controllers.Monitor.startJob
Expand Down

0 comments on commit 68d023d

Please sign in to comment.