#region License Information
/* HeuristicLab
* Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommandLine;
using HeuristicLab.Clients.Hive;
namespace HiveStatus {
class Program {
public const int EXIT_OK = 0;
public const int EXIT_ERR = 1;
public const int EXIT_FAILED = 2;
public const int EXIT_NOTFOUND = 3;
static void Main(string[] args) {
//AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "HiveStatus.exe.config");
var result = Parser.Default.ParseArguments(args)
.WithParsed(x => {
try {
Environment.Exit(Run(x));
} catch { Environment.Exit(EXIT_ERR); }
})
.WithNotParsed(x => Environment.Exit(EXIT_ERR));
}
private static int Run(Options opts) {
#if __DRY_RUN__
Console.WriteLine("DONE");
return EXIT_OK;
#endif
if (string.IsNullOrEmpty(opts.Username) && HeuristicLab.Clients.Common.Properties.Settings.Default.UserName.ToLower() == "anonymous") {
Console.Write("Username: ");
opts.Username = Console.ReadLine();
}
if (!string.IsNullOrEmpty(opts.Username)) {
HiveServiceLocator.Instance.Username = opts.Username;
var password = opts.Password;
if (string.IsNullOrEmpty(password)) {
Console.Error.Write("Password for " + opts.Username + ": ");
password = ReadPassword();
}
HiveServiceLocator.Instance.Password = password;
}
return CheckStatus(opts);
}
private static int CheckStatus(Options opt) {
if (opt.JobId == default(Guid)) return CheckStatusAll(opt);
var jobId = opt.JobId;
if (opt.Verbose) {
List tasks = null;
try {
tasks = HiveServiceLocator.Instance.CallHiveService(x => x.GetLightweightJobTasksWithoutStateLog(jobId));
} catch (System.ServiceModel.Security.SecurityAccessDeniedException) {
Console.WriteLine("?");
return EXIT_NOTFOUND;
}
int completed, failed, running, paused;
GetStats(tasks, out completed, out failed, out running, out paused);
Console.WriteLine(FormatStateInfo(tasks.Count, completed, failed, running, paused));
return failed > 0 ? EXIT_FAILED : EXIT_OK;
} else {
Job job = null;
try {
job = HiveServiceLocator.Instance.CallHiveService(x => x.GetJob(jobId));
} catch (System.ServiceModel.Security.SecurityAccessDeniedException) {
Console.WriteLine("?");
return EXIT_NOTFOUND;
}
Console.WriteLine(FormatStateInfo(job.JobCount, job.FinishedCount, job.CalculatingCount));
return EXIT_OK;
}
}
private static int CheckStatusAll(Options opt) {
List jobs = null;
try {
jobs = HiveServiceLocator.Instance.CallHiveService(x => x.GetJobs());
} catch (System.ServiceModel.Security.SecurityAccessDeniedException) {
Console.WriteLine("?");
return EXIT_NOTFOUND;
}
if (opt.Verbose) {
List tasks = null;
int totFinished, totFailed, totCalculating, totPaused, total;
totFinished = totFailed = totCalculating = totPaused = total = 0;
try {
foreach (var j in jobs) {
tasks = HiveServiceLocator.Instance.CallHiveService(x => x.GetLightweightJobTasksWithoutStateLog(j.Id));
int finished, failed, calculating, paused;
GetStats(tasks, out finished, out failed, out calculating, out paused);
totFinished += finished;
totFailed += failed;
totCalculating += calculating;
totPaused += paused;
total += tasks.Count;
Console.WriteLine(FormatStateInfo(tasks.Count, finished, failed, calculating, paused) + " | " + Truncate(j.Name, 40).PadRight(40) + " | " + j.DateCreated.ToShortDateString());
}
} catch (System.ServiceModel.Security.SecurityAccessDeniedException) {
Console.WriteLine("?");
return EXIT_NOTFOUND;
}
Console.WriteLine();
Console.WriteLine(FormatStateInfo(total, totFinished, totFailed, totCalculating, totPaused) + " | ALL");
return totFailed > 0 ? EXIT_FAILED : EXIT_OK;
} else {
int totFinished, totCalculating, total;
totFinished = totCalculating = total = 0;
foreach (var j in jobs) {
Console.WriteLine(FormatStateInfo(j.JobCount, j.FinishedCount, j.CalculatingCount) + " | " + Truncate(j.Name, 40).PadRight(40) + " | " + j.DateCreated.ToShortDateString());
totFinished += j.FinishedCount;
totCalculating += j.CalculatingCount;
total += j.JobCount;
}
Console.WriteLine();
Console.WriteLine(FormatStateInfo(total, totFinished, totCalculating) + " | ALL");
return EXIT_OK;
}
}
private static void GetStats(List tasks, out int completed, out int failed, out int running, out int paused) {
completed = tasks.Count(x => x.State == TaskState.Finished);
failed = tasks.Count(x => x.State == TaskState.Failed || x.State == TaskState.Aborted);
running = tasks.Count(x => x.State == TaskState.Calculating || x.State == TaskState.Transferring
|| x.State == TaskState.Waiting);
paused = tasks.Count(x => x.State == TaskState.Paused);
}
private static string FormatStateInfo(int total, int finished, int calculating) {
var state = finished == total ? "DONE" : "CALC";
return string.Join(" ", new object[] { state
, "CALC=" + calculating.ToString().PadRight(4)
, "DONE=" + finished.ToString().PadRight(4) });
}
private static string FormatStateInfo(int total, int finished, int failed, int calculating, int paused) {
var state = finished == total ? "DONE" : failed > 0 ? "FAIL" : calculating > 0 ? "CALC" : paused > 0 ? "PAUS" : "NDEF";
return string.Join(" ", new object[] { state
, "CALC=" + calculating.ToString().PadRight(4)
, "DONE=" + finished.ToString().PadRight(4)
, "FAIL=" + failed.ToString().PadRight(4)
, "PAUS=" + paused.ToString().PadRight(4) });
}
#region Helpers
private static string Truncate(string text, int length) {
if (text.Length <= length) return text;
return text.Substring(0, length - 3) + "...";
}
private static string ReadPassword() {
ConsoleKeyInfo info;
var sb = new StringBuilder();
var index = 0;
while (true) {
info = Console.ReadKey(true);
if (info.Key == ConsoleKey.Escape) Environment.Exit(EXIT_ERR);
if (info.Key == ConsoleKey.Enter) break;
if (info.Key == ConsoleKey.Backspace) {
if (index > 0) {
sb.Remove(index - 1, 1);
//else sb.Remove(index, 1);
index--;
Console.CursorLeft--;
for (var i = index; i < sb.Length; i++)
Console.Write('*');
Console.Write(' ');
Console.CursorLeft -= sb.Length - index + 1;
} else Console.Write((char)7);
} else if (info.Key == ConsoleKey.LeftArrow) {
if (index > 0) {
index--;
Console.CursorLeft--;
}
} else if (info.Key == ConsoleKey.RightArrow) {
if (index < sb.Length) {
index++;
Console.CursorLeft++;
}
} else if (info.KeyChar < 32) {
Console.Write((char)7);
} else {
if (sb.Length == index)
sb.Append(info.KeyChar);
else sb.Insert(index, info.KeyChar);
for (var i = index; i < sb.Length; i++)
Console.Write('*');
index++;
Console.CursorLeft -= sb.Length - index;
}
}
Console.WriteLine();
return sb.ToString();
}
#endregion
}
}