#region License Information /* HeuristicLab * Copyright (C) 2002-2015 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 HeuristicLab.Clients.Hive.WebJobManager.Services; using HeuristicLab.Clients.Hive.WebJobManager.Services.Imports; using HeuristicLab.Clients.Hive.WebJobManager.ViewModels.User; using Microsoft.AspNetCore.SignalR; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Threading; namespace HeuristicLab.Clients.Hive.WebJobManager.Hubs { /// /// SignalR Hub that manages all resource management. /// public class CalendarHub : Hub { private WebLoginService weblog; private Guid userId; private HiveAdminClientWeb adminClient; private HiveServiceLocatorWeb servloc; private AccessAdministrationClient accessClient; /// /// Loads up the services for the client (Instance is only created upon a call from a client) /// private void loader() { weblog = WebLoginService.Instance; string uid = Context.QueryString["userid"]; if (uid == null || uid == "" || Guid.Parse(uid) == Guid.Empty) { userId = Guid.Empty; } else { userId = Guid.Parse(uid); adminClient = weblog.getAdminClient(userId); servloc = weblog.getServiceLocator(userId); accessClient = weblog.getAccessAdminClient(userId); } } /// /// Initial client request for all user, group and resource information /// public void requestInfo() { loader(); adminClient.Refresh(); UserViewModel vm = new UserViewModel(accessClient, weblog.getCurrentUser(userId)).refreshAll(); var users = JsonConvert.SerializeObject(vm.users); var groups = JsonConvert.SerializeObject(vm.ugroups); var res = JsonConvert.SerializeObject(adminClient.Resources); Clients.Caller.processData(res, users, groups); } /// /// Request for the downtimes of a specific resource /// /// Resource ID public void requestDownTime(string id) { loader(); adminClient.Refresh(); Guid t = Guid.Parse(id); //Loads up the downtimes for the set resource ID adminClient.DowntimeForResourceId = t; adminClient.RefreshCalendar(); var down = JsonConvert.SerializeObject(adminClient.Downtimes); Clients.Caller.processDowntime(id, down); } /// /// Request for permissions of a specific resource (refreshable by recall) /// /// Resource ID public void requestPermissions(string id) { loader(); Guid r = Guid.Parse(id); var perm = servloc.CallHiveService(x => x.GetResourcePermissions(r)); Clients.Caller.processPermissions(id, JsonConvert.SerializeObject(perm)); } /// /// Edit permissions for a resource /// /// Permissions ID's /// Resource ID public void changePermissions(string[] perms, string idresource) { loader(); var res = Guid.Parse(idresource); //Collect current permissions var exist = servloc.CallHiveService(x => x.GetResourcePermissions(res)); //Separate list for new and to remove permissions List newPerms = new List(); List revokePerms = new List(); for (var i = 0; i < perms.Length; i++) { var p = Guid.Parse(perms[i]); var elemid = exist.FindIndex(x => x.GrantedUserId == p); if (elemid != -1) {//If it already exists => Scramble up Guid (checked further) exist[elemid].GrantedUserId = Guid.Empty; } else {//If it's not in the list, add to new permissions newPerms.Add(p); } } //Adds the new permissions to the resource servloc.CallHiveService(x => x.GrantResourcePermissions(res, newPerms)); foreach (var ex in exist) {//Checks for intact ID's and adds them to the revoke list if(ex.GrantedUserId != Guid.Empty) { revokePerms.Add(ex.GrantedUserId); } } //Revokes all permissions that were deselected by the user servloc.CallHiveService(x => x.RevokeResourcePermissions(res, revokePerms)); //Live reload the view for the resource requestPermissions(idresource); } /// /// Toggles the disposable setting for a resource /// /// Resource ID public void toggleDisposable(string id) { loader(); adminClient.Refresh(); Guid c = Guid.Parse(id); var obj = adminClient.Resources.ToList().Find(x => x.Id == c); //Toggle ((Slave)(obj)).IsDisposable = !((Slave)(obj)).IsDisposable; adminClient.Store(obj, CancellationToken.None); //Notify client of successful saving Clients.Caller.processDispose( ((Slave)(obj)).IsDisposable); } /// /// Saves changes to a resource calendar /// /// Resource id /// To delete downtimes /// New downtimes /// Downtimes to update /// Check if refresh should be sent (Save all current graph or Save current graph) /// Check for last request (Save all) public void saveCalendar(string id, string[] del, string[][] add, string[][] upd, bool fresh, bool last) { loader(); var calid = Guid.Parse(id); //Load up calendar adminClient.Refresh(); adminClient.DowntimeForResourceId = calid; adminClient.RefreshCalendar(); var downlist = adminClient.Downtimes.ToList(); foreach(var s in del) {//Deletes downtimes var gu = Guid.Parse(s); var el = downlist.Find(x => x.Id == gu); adminClient.Delete(el); } foreach (var s in add) {//Adds new downtimes //init var obj = new Downtime(); obj.Id = Guid.Empty; if (s[0] == "Unavailable") obj.DowntimeType = DowntimeType.Offline; else obj.DowntimeType = DowntimeType.Shutdown; obj.StartDate = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[1])); obj.EndDate = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[2])); if (s[3] == "true") obj.AllDayEvent = true; else obj.AllDayEvent = false; obj.ResourceId = Guid.Parse(s[4]); //Recurrency check if (s[5] == "true") {//Recurrency set obj.Recurring = true; if (s[6] == "0") {//new Recur var dayarr = s[9].Split(','); var start = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[7])); var end = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[8])); loopAddDowns(start, end, dayarr, obj);//Loop creation of recurrency. Start to end date } else {//Existing recurrency (only edits current element, client handles the creation of the other events) obj.RecurringId = Guid.Parse(s[6]); adminClient.Store(obj, CancellationToken.None); } } else { //No recurrency obj.Recurring = false; adminClient.Store(obj, CancellationToken.None); } } foreach(var s in upd) {//Update existing downtime var obj = downlist.Find(x => x.Id == Guid.Parse(s[0])); if (s[1] == "Unavailable") obj.DowntimeType = DowntimeType.Offline; else obj.DowntimeType = DowntimeType.Shutdown; obj.StartDate = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[2])); obj.EndDate = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[3])); if (s[4] == "true") obj.AllDayEvent = true; else obj.AllDayEvent = false; if (s[5] == "true" && !obj.Recurring) {//Recurrence set obj.Recurring = true; if (s[6] == "00000000-0000-0000-0000-000000000000") {//Creates new recurrence var dayarr = s[9].Split(','); var start = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[7])); var end = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[8])); loopAddDowns(start, end, dayarr, obj); adminClient.Delete(obj); //Delete needed to prevent doubles in the creation of the recurrency //Why: event could be on not included day of the week => loop cannot find that. } else { obj.RecurringId = Guid.Parse(s[6]); //adminClient.Store(obj, CancellationToken.None); //Throws error } } else { //adminClient.Store(obj, CancellationToken.None); //Throws error } } if( last) {//Last element from save all => Notify client Clients.Caller.savingAllDone(); } else if (fresh) {//Refresh for graph needed Clients.Caller.savingCurrentDone(); } } /// /// Creates downtimes for a new recurrency /// /// Start date /// End date /// Boolean day array (sun = 0,...) /// Downtime to recur private void loopAddDowns(DateTime start, DateTime end, string[] dayarr, Downtime obj) { var rid = Guid.NewGuid(); while (start < end) { if (dayarr[(int)(start.DayOfWeek)] == "true") {//Check for day of the week //Set setting for the downtime to add var temp = new Downtime(); temp.StartDate = start.AddHours(obj.StartDate.Hour - start.Hour) .AddMinutes(obj.StartDate.Minute - start.Minute); temp.EndDate = start.AddHours(obj.EndDate.Hour - start.Hour) .AddMinutes(obj.EndDate.Minute - start.Minute); temp.Id = Guid.Empty; temp.DowntimeType = obj.DowntimeType; temp.AllDayEvent = obj.AllDayEvent; temp.ResourceId = obj.ResourceId; temp.Recurring = obj.Recurring; temp.RecurringId = rid; adminClient.Store(temp, CancellationToken.None); } start = start.AddDays(1); } } } }