Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs @ 15804

Last change on this file since 15804 was 15792, checked in by jzenisek, 7 years ago

#2839 preliminary integration of several HiveAdministrator related improvements from #2877 (full merge pending)

  • slaves and slave groups are sorted by name
  • slave state is indicated by different colors
  • number of contained slaves is shown for each group
  • CPU utilization is shown for each calculating slave
  • last heartbeat date is shown for each offline slave
File size: 11.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Threading;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using System.Collections.Generic;
27using System.Linq;
28
29namespace HeuristicLab.Clients.Hive {
30  [Item("Hive Administrator", "Hive Administrator")]
31  public sealed class HiveAdminClient : IContent {
32    private static HiveAdminClient instance;
33    public static HiveAdminClient Instance {
34      get {
35        if (instance == null) instance = new HiveAdminClient();
36        return instance;
37      }
38    }
39
40    #region Properties
41    private IItemList<Resource> resources;
42    public IItemList<Resource> Resources {
43      get { return resources; }
44    }
45
46    private IItemList<Downtime> downtimes;
47    public IItemList<Downtime> Downtimes {
48      get { return downtimes; }
49    }
50
51    private Guid downtimeForResourceId;
52    public Guid DowntimeForResourceId {
53      get { return downtimeForResourceId; }
54      set {
55        downtimeForResourceId = value;
56        if (downtimes != null) {
57          downtimes.Clear();
58        }
59      }
60    }
61
62    private IItemList<Project> projects;
63    public IItemList<Project> Projects {
64      get { return projects; }
65    }
66
67    private Dictionary<Guid, HashSet<Project>> projectAncestors;
68    public Dictionary<Guid, HashSet<Project>> ProjectAncestors {
69      get { return projectAncestors; }
70    }
71
72    private Dictionary<Guid, HashSet<Project>> projectDescendants;
73    public Dictionary<Guid, HashSet<Project>> ProjectDescendants {
74      get { return projectDescendants; }
75    }
76
77    private Dictionary<Guid, HashSet<Resource>> resourceAncestors;
78    public Dictionary<Guid, HashSet<Resource>> ResourceAncestors {
79      get { return resourceAncestors; }
80    }
81
82    private Dictionary<Guid, HashSet<Resource>> resourceDescendants;
83    public Dictionary<Guid, HashSet<Resource>> ResourceDescendants {
84      get { return resourceDescendants; }
85    }
86
87
88    #endregion
89
90    #region Events
91    public event EventHandler Refreshing;
92    private void OnRefreshing() {
93      EventHandler handler = Refreshing;
94      if (handler != null) handler(this, EventArgs.Empty);
95    }
96    public event EventHandler Refreshed;
97    private void OnRefreshed() {
98      var handler = Refreshed;
99      if (handler != null) handler(this, EventArgs.Empty);
100    }
101    #endregion
102
103    private HiveAdminClient() { }
104
105    #region Refresh
106    public void Refresh() {
107      OnRefreshing();
108
109      try {
110        resources = new ItemList<Resource>();
111        projects = new ItemList<Project>();
112
113        projectAncestors = new Dictionary<Guid, HashSet<Project>>();
114        projectDescendants = new Dictionary<Guid, HashSet<Project>>();
115        resourceAncestors = new Dictionary<Guid, HashSet<Resource>>();
116        resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
117
118        HiveServiceLocator.Instance.CallHiveService(service => {
119          service.GetSlaveGroupsForAdministration().ForEach(g => resources.Add(g));
120          service.GetSlavesForAdministration().ForEach(s => resources.Add(s));
121          service.GetProjectsForAdministration().ForEach(p => projects.Add(p));
122        });
123
124        UpdateResourceGenealogy(resources);
125        UpdateProjectGenealogy(projects);
126      }
127      catch {
128        throw;
129      }
130      finally {
131        OnRefreshed();
132      }
133    }
134
135    public void UpdateResourceGenealogy(IItemList<Resource> resources) {
136      resourceAncestors.Clear();
137      resourceDescendants.Clear();
138
139      foreach (var r in resources) {
140        resourceAncestors.Add(r.Id, new HashSet<Resource>());
141        resourceDescendants.Add(r.Id, new HashSet<Resource>());
142      }
143
144      foreach (var r in resources) {
145        var parentResourceId = r.ParentResourceId;
146        while (parentResourceId != null) {
147          var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
148          if (parent != null) {
149            resourceAncestors[r.Id].Add(parent);
150            resourceDescendants[parent.Id].Add(r);
151            parentResourceId = parent.ParentResourceId;
152          } else {
153            parentResourceId = null;
154          }
155        }
156      }
157    }
158
159    public void UpdateProjectGenealogy(IItemList<Project> projects) {
160      projectAncestors.Clear();
161      projectDescendants.Clear();
162
163      foreach (var p in projects) {
164        projectAncestors.Add(p.Id, new HashSet<Project>());
165        projectDescendants.Add(p.Id, new HashSet<Project>());
166      }
167
168      foreach (var p in projects) {
169        var parentProjectId = p.ParentProjectId;
170        while (parentProjectId != null) {
171          var parent = projects.SingleOrDefault(x => x.Id == parentProjectId);
172          if (parent != null) {
173            projectAncestors[p.Id].Add(parent);
174            projectDescendants[parent.Id].Add(p);
175            parentProjectId = parent.ParentProjectId;
176          } else {
177            parentProjectId = null;
178          }
179        }
180      }
181    }
182    #endregion
183
184    #region Refresh downtime calendar
185    public void RefreshCalendar() {
186      if (downtimeForResourceId != null && downtimeForResourceId != Guid.Empty) {
187        OnRefreshing();
188
189        try {
190          downtimes = new ItemList<Downtime>();
191
192          HiveServiceLocator.Instance.CallHiveService(service => {
193            service.GetDowntimesForResource(downtimeForResourceId).ForEach(d => downtimes.Add(d));
194          });
195        }
196        catch {
197          throw;
198        }
199        finally {
200          OnRefreshed();
201        }
202      }
203    }
204    #endregion
205
206    #region Store
207    public static void Store(IHiveItem item, CancellationToken cancellationToken) {
208      if (item.Id == Guid.Empty) {
209        if (item is SlaveGroup) {
210          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlaveGroup((SlaveGroup)item));
211        }
212        if (item is Slave) {
213          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlave((Slave)item));
214        }
215        if (item is Downtime) {
216          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddDowntime((Downtime)item));
217        }
218        if (item is Project) {
219          item.Id = HiveServiceLocator.Instance.CallHiveService(s => s.AddProject((Project)item));
220        }
221      } else {
222        if (item is SlaveGroup) {
223          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlaveGroup((SlaveGroup)item));
224        }
225        if (item is Slave) {
226          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlave((Slave)item));
227        }
228        if (item is Downtime) {
229          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateDowntime((Downtime)item));
230        }
231        if (item is Project) {
232          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateProject((Project)item));
233        }
234      }
235    }
236    #endregion
237
238    #region Delete
239    public static void Delete(IHiveItem item) {
240      if (item is SlaveGroup) {
241        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlaveGroup(item.Id));
242      } else if (item is Slave) {
243        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlave(item.Id));
244      } else if (item is Downtime) {
245        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteDowntime(item.Id));
246      } else if (item is Project) {
247        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteProject(item.Id));
248      }
249    }
250    #endregion
251
252    public void ResetDowntime() {
253      downtimeForResourceId = Guid.Empty;
254      if (downtimes != null) {
255        downtimes.Clear();
256      }
257    }
258
259    #region Helper
260    public bool CheckAccessToAdminAreaGranted() {
261      if(projects != null) {
262        return projects.Count > 0;
263      } else {
264        bool accessGranted = false;
265        HiveServiceLocator.Instance.CallHiveService(s => {
266          accessGranted = s.CheckAccessToAdminAreaGranted();
267        });
268        return accessGranted;
269      }
270    }
271
272    public bool CheckOwnershipOfResource(Resource res, Guid userId) {
273      if (res == null || userId == Guid.Empty) return false;
274
275      if (res.OwnerUserId == userId) {
276        return true;
277      } else if(resourceAncestors.ContainsKey(res.Id)) {
278        return resourceAncestors[res.Id].Where(x => x.OwnerUserId == userId).Any();
279      }
280
281      return false;
282    }
283
284    public bool CheckOwnershipOfProject(Project pro, Guid userId) {
285      if (pro == null || userId == Guid.Empty) return false;
286
287      if (pro.OwnerUserId == userId) {
288        return true;
289      } else if (projectAncestors.ContainsKey(pro.Id)) {
290        return projectAncestors[pro.Id].Where(x => x.OwnerUserId == userId).Any();
291      }
292
293      return false;
294    }
295
296    public bool CheckOwnershipOfParentProject(Project pro, Guid userId) {
297      if (pro == null || userId == Guid.Empty) return false;
298
299      if(projectAncestors.ContainsKey(pro.Id)) {
300        return projectAncestors[pro.Id].Where(x => x.OwnerUserId == userId).Any();
301      }
302
303      return false;
304    }
305
306    public bool CheckParentChange(Project child, Project parent) {
307      bool changePossible = true;
308
309      // change is not possible...
310      // ... if the moved project is null
311      // ... or the new parent is not stored yet
312      // ... or there is not parental change
313      if (child == null
314        || (parent != null && parent.Id == Guid.Empty)
315        || (parent != null && parent.Id == child.ParentProjectId)) {
316        changePossible = false;
317      } else if(parent != null && projectDescendants.ContainsKey(child.Id)) {
318        // ... if the new parent is among the moved project's descendants
319        changePossible = !projectDescendants[child.Id].Where(x => x.Id == parent.Id).Any();
320      }
321
322      return changePossible;
323    }
324
325    public bool CheckParentChange(Resource child, Resource parent) {
326      bool changePossible = true;
327
328      // change is not possisble...
329      // ... if the moved resource is null
330      // ... or the new parent is not stored yet
331      // ... or the new parent is a slave
332      // ... or there is not parental change
333      if (child == null
334        || (parent != null && parent.Id == Guid.Empty)
335        || (parent != null && parent is Slave)
336        || (parent != null && parent.Id == child.ParentResourceId)) {
337        changePossible = false;
338      } else if (parent != null && resourceDescendants.ContainsKey(child.Id)) {
339        // ... or if the new parent is among the moved resource's descendants
340        changePossible = !resourceDescendants[child.Id].Where(x => x.Id == parent.Id).Any();
341      }
342
343      return changePossible;
344    }
345    #endregion
346  }
347}
Note: See TracBrowser for help on using the repository browser.