Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3040_VectorBasedGP/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs @ 18242

Last change on this file since 18242 was 17825, checked in by pfleck, 4 years ago

#3040 Merged trunk into branch.

File size: 22.3 KB
RevLine 
[6976]1#region License Information
2/* HeuristicLab
[17180]3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[6976]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;
[16878]23using System.Collections.Generic;
24using System.Linq;
[6976]25using System.Threading;
[16878]26using HeuristicLab.Clients.Access;
[6976]27using HeuristicLab.Common;
28using HeuristicLab.Core;
29
30namespace HeuristicLab.Clients.Hive {
31  [Item("Hive Administrator", "Hive Administrator")]
32  public sealed class HiveAdminClient : IContent {
33    private static HiveAdminClient instance;
34    public static HiveAdminClient Instance {
35      get {
36        if (instance == null) instance = new HiveAdminClient();
37        return instance;
38      }
39    }
40
[16117]41    #region Properties
[6976]42    private IItemList<Resource> resources;
43    public IItemList<Resource> Resources {
44      get { return resources; }
45    }
46
47    private IItemList<Downtime> downtimes;
48    public IItemList<Downtime> Downtimes {
49      get { return downtimes; }
50    }
51
52    private Guid downtimeForResourceId;
53    public Guid DowntimeForResourceId {
54      get { return downtimeForResourceId; }
55      set {
56        downtimeForResourceId = value;
57        if (downtimes != null) {
58          downtimes.Clear();
59        }
60      }
61    }
62
[16117]63    private IItemList<Project> projects;
64    public IItemList<Project> Projects {
65      get { return projects; }
66    }
67
68    private IItemList<AssignedProjectResource> projectResourceAssignments;
69    public IItemList<AssignedProjectResource> ProjectResourceAssignments {
70      get { return projectResourceAssignments; }
71    }
72
[16208]73    private Dictionary<Guid, HiveItemCollection<RefreshableJob>> jobs;
74    public Dictionary<Guid, HiveItemCollection<RefreshableJob>> Jobs {
[16117]75      get { return jobs; }
76      set {
77        if (value != jobs)
78          jobs = value;
[16878]79      }
[16117]80    }
81
[16209]82    private Dictionary<Guid, List<LightweightTask>> tasks;
83    public Dictionary<Guid, List<LightweightTask>> Tasks {
84      get { return tasks; }
85    }
86
[16117]87    private Dictionary<Guid, HashSet<Guid>> projectAncestors;
88    public Dictionary<Guid, HashSet<Guid>> ProjectAncestors {
89      get { return projectAncestors; }
90    }
91
92    private Dictionary<Guid, HashSet<Guid>> projectDescendants;
93    public Dictionary<Guid, HashSet<Guid>> ProjectDescendants {
94      get { return projectDescendants; }
95    }
96
97    private Dictionary<Guid, HashSet<Guid>> resourceAncestors;
98    public Dictionary<Guid, HashSet<Guid>> ResourceAncestors {
99      get { return resourceAncestors; }
100    }
101
102    private Dictionary<Guid, HashSet<Guid>> resourceDescendants;
103    public Dictionary<Guid, HashSet<Guid>> ResourceDescendants {
104      get { return resourceDescendants; }
105    }
106
107    private Dictionary<Guid, string> projectNames;
108    public Dictionary<Guid, string> ProjectNames {
109      get { return projectNames; }
110    }
111
112    private HashSet<Project> disabledParentProjects;
113    public HashSet<Project> DisabledParentProjects {
114      get { return disabledParentProjects; }
115    }
116
117    private Dictionary<Guid, string> resourceNames;
118    public Dictionary<Guid, string> ResourceNames {
119      get { return resourceNames; }
120    }
121
122    private HashSet<Resource> disabledParentResources;
123    public HashSet<Resource> DisabledParentResources {
124      get { return disabledParentResources; }
125    }
126    #endregion
127
[6976]128    #region Events
129    public event EventHandler Refreshing;
130    private void OnRefreshing() {
131      EventHandler handler = Refreshing;
132      if (handler != null) handler(this, EventArgs.Empty);
133    }
134    public event EventHandler Refreshed;
135    private void OnRefreshed() {
136      var handler = Refreshed;
137      if (handler != null) handler(this, EventArgs.Empty);
138    }
139    #endregion
140
141    private HiveAdminClient() { }
142
143    #region Refresh
144    public void Refresh() {
145      OnRefreshing();
146
147      try {
148        resources = new ItemList<Resource>();
[16117]149        projects = new ItemList<Project>();
150        projectResourceAssignments = new ItemList<AssignedProjectResource>();
[16208]151        jobs = new Dictionary<Guid, HiveItemCollection<RefreshableJob>>();
[16209]152        tasks = new Dictionary<Guid, List<LightweightTask>>();
[16117]153        projectNames = new Dictionary<Guid, string>();
154        resourceNames = new Dictionary<Guid, string>();
[6976]155
[16117]156        projectAncestors = new Dictionary<Guid, HashSet<Guid>>();
157        projectDescendants = new Dictionary<Guid, HashSet<Guid>>();
158        resourceAncestors = new Dictionary<Guid, HashSet<Guid>>();
159        resourceDescendants = new Dictionary<Guid, HashSet<Guid>>();
160
[7132]161        HiveServiceLocator.Instance.CallHiveService(service => {
[16117]162          service.GetSlaveGroupsForAdministration().ForEach(g => resources.Add(g));
163          service.GetSlavesForAdministration().ForEach(s => resources.Add(s));
164          service.GetProjectsForAdministration().ForEach(p => projects.Add(p));
165          var projectIds = projects.Select(p => p.Id).ToList();
166          if (projectIds.Any()) {
167            service.GetAssignedResourcesForProjectsAdministration(projectIds)
[16878]168                   .ForEach(a => projectResourceAssignments.Add(a));
169
[16117]170            projectNames = service.GetProjectNames();
171            resourceNames = service.GetResourceNames();
172          }
[6976]173        });
[16117]174
175        UpdateResourceGenealogy();
176        UpdateProjectGenealogy();
177        RefreshDisabledParentProjects();
178        RefreshDisabledParentResources();
[16878]179      } catch {
[6976]180        throw;
[16878]181      } finally {
[6976]182        OnRefreshed();
183      }
184    }
[16117]185
186    private void UpdateResourceGenealogy() {
187      resourceAncestors.Clear();
188      resourceDescendants.Clear();
189
190      // fetch resource ancestor set
191      HiveServiceLocator.Instance.CallHiveService(service => {
192        var ra = service.GetResourceGenealogy();
193        ra.Keys.ToList().ForEach(k => resourceAncestors.Add(k, new HashSet<Guid>()));
194        resourceAncestors.Keys.ToList().ForEach(k => resourceAncestors[k].UnionWith(ra[k]));
195      });
196
197      // build resource descendant set
198      resourceAncestors.Keys.ToList().ForEach(k => resourceDescendants.Add(k, new HashSet<Guid>()));
199      foreach (var ra in resourceAncestors) {
200        foreach (var ancestor in ra.Value) {
201          resourceDescendants[ancestor].Add(ra.Key);
202        }
203      }
204    }
205
206    private void UpdateProjectGenealogy() {
207      projectAncestors.Clear();
208      projectDescendants.Clear();
209
210      // fetch project ancestor list
211      HiveServiceLocator.Instance.CallHiveService(service => {
212        var pa = service.GetProjectGenealogy();
213        pa.Keys.ToList().ForEach(k => projectAncestors.Add(k, new HashSet<Guid>()));
214        projectAncestors.Keys.ToList().ForEach(k => projectAncestors[k].UnionWith(pa[k]));
215      });
216
217      // build project descendant list
218      projectAncestors.Keys.ToList().ForEach(k => projectDescendants.Add(k, new HashSet<Guid>()));
219      foreach (var pa in projectAncestors) {
220        foreach (var ancestor in pa.Value) {
221          projectDescendants[ancestor].Add(pa.Key);
222        }
223      }
224    }
225
226    private void RefreshDisabledParentProjects() {
227      disabledParentProjects = new HashSet<Project>();
228
229      foreach (var pid in projects
230        .Where(x => x.ParentProjectId.HasValue)
231        .SelectMany(x => projectAncestors[x.Id]).Distinct()
232        .Where(x => !projects.Select(y => y.Id).Contains(x))) {
233        var p = new Project();
234        p.Id = pid;
235        p.ParentProjectId = projectAncestors[pid].FirstOrDefault();
236        p.Name = projectNames[pid];
237        disabledParentProjects.Add(p);
238      }
239    }
240
241    private void RefreshDisabledParentResources() {
242      disabledParentResources = new HashSet<Resource>();
243
244      foreach (var rid in resources
245        .Where(x => x.ParentResourceId.HasValue)
246        .SelectMany(x => resourceAncestors[x.Id]).Distinct()
247        .Where(x => !resources.Select(y => y.Id).Contains(x))) {
248        var r = new SlaveGroup();
249        r.Id = rid;
250        r.ParentResourceId = resourceAncestors[rid].FirstOrDefault();
251        r.Name = resourceNames[rid];
252        disabledParentResources.Add(r);
253      }
254    }
255
[16878]256    public void RefreshJobs(Guid projectId) {
257      HiveServiceLocator.Instance.CallHiveService(service => {
258        var projectIds = new HashSet<Guid>(service.GetProjectsForAdministration().Select(x => x.Id));
259        if (projectIds.Contains(projectId)) {
260          jobs.Add(projectId, new HiveItemCollection<RefreshableJob>());
[16117]261
[16878]262          var unsortedJobs = service.GetJobsByProjectId(projectId)
263                                    .OrderBy(x => x.DateCreated).ToList();
264
[16208]265          unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
266          unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
267          unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
268
[16878]269          foreach (var job in jobs.SelectMany(x => x.Value))
[16208]270            LoadLightweightJob(job);
[16117]271        }
272      });
273    }
274
[16209]275    public void LoadLightweightJob(RefreshableJob refreshableJob) {
[16208]276      var job = refreshableJob.Job;
[16209]277      var lightweightTasks = HiveServiceLocator.Instance.CallHiveService(s => s.GetLightweightJobTasksWithoutStateLog(job.Id));
278
279      if (tasks.ContainsKey(job.Id)) {
280        tasks[job.Id].Clear();
281        tasks[job.Id].AddRange(lightweightTasks);
282      } else {
[16878]283        tasks.Add(job.Id, new List<LightweightTask>(lightweightTasks));
[16209]284      }
285
286      if (lightweightTasks != null && lightweightTasks.Count > 0 && lightweightTasks.All(x => x.Id != Guid.Empty)) {
287        if (lightweightTasks.All(x =>
[16878]288          x.State == TaskState.Finished
289          || x.State == TaskState.Aborted
[16208]290          || x.State == TaskState.Failed)) {
291          refreshableJob.ExecutionState = ExecutionState.Stopped;
292          refreshableJob.RefreshAutomatically = false;
293        } else if (
[16209]294          lightweightTasks
[16208]295            .Where(x => x.ParentTaskId != null)
296            .All(x =>
297              x.State != TaskState.Waiting
298              || x.State != TaskState.Transferring
299              || x.State != TaskState.Calculating)
[16209]300          && lightweightTasks
[16208]301             .Where(x => x.ParentTaskId != null)
302             .Any(x => x.State == TaskState.Paused)) {
303          refreshableJob.ExecutionState = ExecutionState.Paused;
304          refreshableJob.RefreshAutomatically = false;
[16878]305        } else if (lightweightTasks.Any(x => x.State == TaskState.Calculating
306                                  || x.State == TaskState.Transferring
[16208]307                                  || x.State == TaskState.Waiting)) {
308          refreshableJob.ExecutionState = ExecutionState.Started;
309        }
[16209]310
311        refreshableJob.ExecutionTime = TimeSpan.FromMilliseconds(lightweightTasks.Sum(x => x.ExecutionTime.TotalMilliseconds));
[16208]312      }
313    }
314
[16117]315    public void SortJobs() {
[16878]316      for (int i = 0; i < jobs.Count; i++) {
[16117]317        var projectId = jobs.Keys.ElementAt(i);
318        var unsortedJobs = jobs.Values.ElementAt(i);
319
[16208]320        var sortedJobs = new HiveItemCollection<RefreshableJob>();
321        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.DeletionPending));
322        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.StatisticsPending));
323        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.Online));
[16117]324
325        jobs[projectId] = sortedJobs;
326      }
327    }
328
[6976]329    #endregion
330
331    #region Refresh downtime calendar
332    public void RefreshCalendar() {
333      if (downtimeForResourceId != null && downtimeForResourceId != Guid.Empty) {
334        OnRefreshing();
335
336        try {
337          downtimes = new ItemList<Downtime>();
338
[7132]339          HiveServiceLocator.Instance.CallHiveService(service => {
[6976]340            service.GetDowntimesForResource(downtimeForResourceId).ForEach(d => downtimes.Add(d));
341          });
[16878]342        } catch {
[6976]343          throw;
[16878]344        } finally {
[6976]345          OnRefreshed();
346        }
347      }
348    }
349    #endregion
350
351    #region Store
352    public static void Store(IHiveItem item, CancellationToken cancellationToken) {
353      if (item.Id == Guid.Empty) {
354        if (item is SlaveGroup) {
[7132]355          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlaveGroup((SlaveGroup)item));
[6976]356        }
357        if (item is Slave) {
[7132]358          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlave((Slave)item));
[6976]359        }
360        if (item is Downtime) {
[7132]361          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddDowntime((Downtime)item));
[6976]362        }
[16117]363        if (item is Project) {
364          item.Id = HiveServiceLocator.Instance.CallHiveService(s => s.AddProject((Project)item));
365        }
[6976]366      } else {
367        if (item is SlaveGroup) {
[7132]368          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlaveGroup((SlaveGroup)item));
[6976]369        }
370        if (item is Slave) {
[7132]371          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlave((Slave)item));
[6976]372        }
373        if (item is Downtime) {
[7132]374          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateDowntime((Downtime)item));
[6976]375        }
[16117]376        if (item is Project) {
377          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateProject((Project)item));
378        }
[6976]379      }
380    }
381    #endregion
382
383    #region Delete
384    public static void Delete(IHiveItem item) {
385      if (item is SlaveGroup) {
[7132]386        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlaveGroup(item.Id));
[6976]387      } else if (item is Slave) {
[7132]388        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlave(item.Id));
[6976]389      } else if (item is Downtime) {
[7132]390        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteDowntime(item.Id));
[16117]391      } else if (item is Project) {
392        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteProject(item.Id));
[6976]393      }
394    }
[16117]395
[16208]396    public static void RemoveJobs(List<Guid> jobIds) {
[16117]397      HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateJobStates(jobIds, JobState.StatisticsPending));
398    }
[6976]399    #endregion
400
[16208]401    #region Job Handling
402
403    public static void ResumeJob(RefreshableJob refreshableJob) {
404      HiveServiceLocator.Instance.CallHiveService(service => {
[16209]405        var tasks = service.GetLightweightJobTasksWithoutStateLog(refreshableJob.Id);
406        foreach (var task in tasks) {
407          if (task.State == TaskState.Paused) {
408            service.RestartTask(task.Id);
[16208]409          }
410        }
411      });
412      refreshableJob.ExecutionState = ExecutionState.Started;
413    }
414
415    public static void PauseJob(RefreshableJob refreshableJob) {
416      HiveServiceLocator.Instance.CallHiveService(service => {
[16209]417        var tasks = service.GetLightweightJobTasksWithoutStateLog(refreshableJob.Id);
418        foreach (var task in tasks) {
419          if (task.State != TaskState.Finished && task.State != TaskState.Aborted && task.State != TaskState.Failed)
420            service.PauseTask(task.Id);
[16208]421        }
422      });
423      refreshableJob.ExecutionState = ExecutionState.Paused;
424    }
425
426    public static void StopJob(RefreshableJob refreshableJob) {
427      HiveServiceLocator.Instance.CallHiveService(service => {
[16209]428        var tasks = service.GetLightweightJobTasksWithoutStateLog(refreshableJob.Id);
429        foreach (var task in tasks) {
430          if (task.State != TaskState.Finished && task.State != TaskState.Aborted && task.State != TaskState.Failed)
431            service.StopTask(task.Id);
[16208]432        }
433      });
434      refreshableJob.ExecutionState = ExecutionState.Stopped;
435    }
436
437    public static void RemoveJob(RefreshableJob refreshableJob) {
[16209]438      HiveServiceLocator.Instance.CallHiveService((service) => {
439        service.UpdateJobState(refreshableJob.Id, JobState.StatisticsPending);
[16208]440      });
441    }
442    #endregion
443
[6976]444    public void ResetDowntime() {
445      downtimeForResourceId = Guid.Empty;
446      if (downtimes != null) {
447        downtimes.Clear();
448      }
449    }
[16117]450
451    #region Helper
452    public IEnumerable<Project> GetAvailableProjectAncestors(Guid id) {
453      if (projectAncestors.ContainsKey(id)) return projects.Where(x => projectAncestors[id].Contains(x.Id));
454      else return Enumerable.Empty<Project>();
455    }
456
457    public IEnumerable<Project> GetAvailableProjectDescendants(Guid id) {
[16878]458      if (projectDescendants.ContainsKey(id)) return projects.Where(x => projectDescendants[id].Contains(x.Id));
[16117]459      else return Enumerable.Empty<Project>();
460    }
461
462    public IEnumerable<Resource> GetAvailableResourceAncestors(Guid id) {
463      if (resourceAncestors.ContainsKey(id)) return resources.Where(x => resourceAncestors[id].Contains(x.Id));
464      else return Enumerable.Empty<Resource>();
465    }
466
467    public IEnumerable<Resource> GetAvailableResourceDescendants(Guid id) {
468      if (resourceDescendants.ContainsKey(id)) return resources.Where(x => resourceDescendants[id].Contains(x.Id));
469      else return Enumerable.Empty<Resource>();
470    }
471
[16202]472    public IEnumerable<Resource> GetDisabledResourceAncestors(IEnumerable<Resource> availableResources) {
473      var missingParentIds = availableResources
474        .Where(x => x.ParentResourceId.HasValue)
475        .SelectMany(x => resourceAncestors[x.Id]).Distinct()
476        .Where(x => !availableResources.Select(y => y.Id).Contains(x));
477
478      return resources.OfType<SlaveGroup>().Union(disabledParentResources).Where(x => missingParentIds.Contains(x.Id));
479    }
480
[16117]481    public bool CheckAccessToAdminAreaGranted() {
[16878]482      if (projects != null) {
[16117]483        return projects.Count > 0;
484      } else {
485        bool accessGranted = false;
486        HiveServiceLocator.Instance.CallHiveService(s => {
487          accessGranted = s.CheckAccessToAdminAreaGranted();
488        });
489        return accessGranted;
490      }
491    }
492
493    public bool CheckOwnershipOfResource(Resource res, Guid userId) {
494      if (res == null || userId == Guid.Empty) return false;
495
496      if (res.OwnerUserId == userId) {
497        return true;
[16878]498      } else if (resourceAncestors.ContainsKey(res.Id)) {
[16117]499        return GetAvailableResourceAncestors(res.Id).Where(x => x.OwnerUserId == userId).Any();
500      }
501
502      return false;
503    }
504
505    public bool CheckOwnershipOfProject(Project pro, Guid userId) {
506      if (pro == null || userId == Guid.Empty) return false;
507
508      if (pro.OwnerUserId == userId) {
509        return true;
510      } else if (projectAncestors.ContainsKey(pro.Id)) {
511        return GetAvailableProjectAncestors(pro.Id).Where(x => x.OwnerUserId == userId).Any();
512      }
513
514      return false;
515    }
516
517    public bool CheckOwnershipOfParentProject(Project pro, Guid userId) {
518      if (pro == null || userId == Guid.Empty) return false;
519
[16878]520      if (projectAncestors.ContainsKey(pro.Id)) {
[16202]521        return GetAvailableProjectAncestors(pro.Id).Any(x => x.OwnerUserId == userId);
[16117]522      }
523
[16202]524      if (pro.ParentProjectId != null && pro.ParentProjectId != Guid.Empty) {
525        var parent = projects.FirstOrDefault(x => x.Id == pro.ParentProjectId.Value);
526        if (parent != null)
527          return parent.OwnerUserId == userId || GetAvailableProjectAncestors(parent.Id).Any(x => x.OwnerUserId == userId);
528      }
529
[16117]530      return false;
531    }
532
533    public bool CheckParentChange(Project child, Project parent) {
534      bool changePossible = true;
535
536      // change is not possible...
537      // ... if the moved project is null
538      // ... or the new parent is not stored yet
539      // ... or there is not parental change
[16202]540      if (child == null
541          || (parent != null && parent.Id == Guid.Empty)
542          || (parent != null && parent.Id == child.ParentProjectId)) {
[16117]543        changePossible = false;
[16202]544      } else if (parent == null && !IsAdmin()) {
545        // ... if parent is null, but user is no admin (only admins are allowed to create root projects)
546        changePossible = false;
547      } else if (parent != null && (!IsAdmin() && parent.OwnerUserId != UserInformation.Instance.User.Id && !CheckOwnershipOfParentProject(parent, UserInformation.Instance.User.Id))) {
548        // ... if the user is no admin nor owner of the new parent or grand..grandparents
549        changePossible = false;
[16878]550      } else if (parent != null && projectDescendants.ContainsKey(child.Id)) {
[16117]551        // ... if the new parent is among the moved project's descendants
552        changePossible = !GetAvailableProjectDescendants(child.Id).Where(x => x.Id == parent.Id).Any();
553      }
554
555      return changePossible;
556    }
557
558    public bool CheckParentChange(Resource child, Resource parent) {
559      bool changePossible = true;
560
561      // change is not possisble...
562      // ... if the child resource is null
563      // ... or the child resource equals the parent
564      // ... or the new parent is not stored yet
565      // ... or the new parent is a slave
566      // ... or there is not parental change
[16878]567      if (child == null
[16117]568        || child == parent
569        || (parent != null && parent.Id == Guid.Empty)
570        || (parent != null && parent is Slave)
571        || (parent != null && parent.Id == child.ParentResourceId)) {
572        changePossible = false;
573      } else if (parent != null && resourceDescendants.ContainsKey(child.Id)) {
574        // ... or if the new parent is among the moved resource's descendants
575        changePossible = !GetAvailableResourceDescendants(child.Id).Where(x => x.Id == parent.Id).Any();
576      }
577
578      return changePossible;
579    }
[16202]580
[16209]581    public IEnumerable<Resource> GetAssignedResourcesForJob(Guid jobId) {
[16878]582      var assignedJobResource = HiveServiceLocator.Instance.CallHiveService(service => service.GetAssignedResourcesForJob(jobId));
[16209]583      return Resources.Where(x => assignedJobResource.Select(y => y.ResourceId).Contains(x.Id));
584    }
585
[16202]586    private bool IsAdmin() {
587      return HiveRoles.CheckAdminUserPermissions();
588    }
[16117]589    #endregion
[6976]590  }
591}
Note: See TracBrowser for help on using the repository browser.