source: trunk/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs @ 16209

Last change on this file since 16209 was 16209, checked in by jzenisek, 12 months ago

#2839:

  • adapted job execution implementation at ProjectJobsView
  • prohibited resource checking for non-admins
File size: 24.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 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;
28using HeuristicLab.Clients.Access;
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
41    #region Properties
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
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
73    private Dictionary<Guid, HiveItemCollection<RefreshableJob>> jobs;
74    public Dictionary<Guid, HiveItemCollection<RefreshableJob>> Jobs {
75      get { return jobs; }
76      set {
77        if (value != jobs)
78          jobs = value;
79        }
80    }
81
82    private Dictionary<Guid, List<LightweightTask>> tasks;
83    public Dictionary<Guid, List<LightweightTask>> Tasks {
84      get { return tasks; }
85    }
86
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
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>();
149        projects = new ItemList<Project>();
150        projectResourceAssignments = new ItemList<AssignedProjectResource>();
151        jobs = new Dictionary<Guid, HiveItemCollection<RefreshableJob>>();
152        tasks = new Dictionary<Guid, List<LightweightTask>>();
153        projectNames = new Dictionary<Guid, string>();
154        resourceNames = new Dictionary<Guid, string>();
155
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
161        HiveServiceLocator.Instance.CallHiveService(service => {
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)
168              .ForEach(a => projectResourceAssignments.Add(a));
169            projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<RefreshableJob>()));
170            var unsortedJobs = service.GetJobsByProjectIds(projectIds)
171              .OrderBy(x => x.DateCreated).ToList();
172
173            unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
174            unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
175            unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
176
177            foreach (var job in jobs.SelectMany(x => x.Value))
178              LoadLightweightJob(job);
179
180            projectNames = service.GetProjectNames();
181            resourceNames = service.GetResourceNames();
182          }
183        });
184
185        UpdateResourceGenealogy();
186        UpdateProjectGenealogy();
187        RefreshDisabledParentProjects();
188        RefreshDisabledParentResources();
189      }
190      catch {
191        throw;
192      }
193      finally {
194        OnRefreshed();
195      }
196    }
197
198    //public void UpdateResourceGenealogy(IItemList<Resource> resources) {
199    //  resourceAncestors.Clear();
200    //  resourceDescendants.Clear();
201
202    //  foreach (var r in resources) {
203    //    resourceAncestors.Add(r.Id, new HashSet<Resource>());
204    //    resourceDescendants.Add(r.Id, new HashSet<Resource>());
205    //  }
206
207    //  foreach (var r in resources) {
208    //    var parentResourceId = r.ParentResourceId;
209    //    while (parentResourceId != null) {
210    //      var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
211    //      if (parent != null) {
212    //        resourceAncestors[r.Id].Add(parent);
213    //        resourceDescendants[parent.Id].Add(r);
214    //        parentResourceId = parent.ParentResourceId;
215    //      } else {
216    //        parentResourceId = null;
217    //      }
218    //    }
219    //  }
220    //}
221
222    //public void UpdateProjectGenealogy(IItemList<Project> projects) {
223    //  projectAncestors.Clear();
224    //  projectDescendants.Clear();
225
226    //  foreach (var p in projects) {
227    //    projectAncestors.Add(p.Id, new HashSet<Project>());
228    //    projectDescendants.Add(p.Id, new HashSet<Project>());
229    //  }
230
231    //  foreach (var p in projects) {
232    //    var parentProjectId = p.ParentProjectId;
233    //    while (parentProjectId != null) {
234    //      var parent = projects.SingleOrDefault(x => x.Id == parentProjectId);
235    //      if (parent != null) {
236    //        projectAncestors[p.Id].Add(parent);
237    //        projectDescendants[parent.Id].Add(p);
238    //        parentProjectId = parent.ParentProjectId;
239    //      } else {
240    //        parentProjectId = null;
241    //      }
242    //    }
243    //  }
244    //}
245
246    private void UpdateResourceGenealogy() {
247      resourceAncestors.Clear();
248      resourceDescendants.Clear();
249
250      // fetch resource ancestor set
251      HiveServiceLocator.Instance.CallHiveService(service => {
252        var ra = service.GetResourceGenealogy();
253        ra.Keys.ToList().ForEach(k => resourceAncestors.Add(k, new HashSet<Guid>()));
254        resourceAncestors.Keys.ToList().ForEach(k => resourceAncestors[k].UnionWith(ra[k]));
255      });
256
257      // build resource descendant set
258      resourceAncestors.Keys.ToList().ForEach(k => resourceDescendants.Add(k, new HashSet<Guid>()));
259      foreach (var ra in resourceAncestors) {
260        foreach (var ancestor in ra.Value) {
261          resourceDescendants[ancestor].Add(ra.Key);
262        }
263      }
264    }
265
266    private void UpdateProjectGenealogy() {
267      projectAncestors.Clear();
268      projectDescendants.Clear();
269
270      // fetch project ancestor list
271      HiveServiceLocator.Instance.CallHiveService(service => {
272        var pa = service.GetProjectGenealogy();
273        pa.Keys.ToList().ForEach(k => projectAncestors.Add(k, new HashSet<Guid>()));
274        projectAncestors.Keys.ToList().ForEach(k => projectAncestors[k].UnionWith(pa[k]));
275      });
276
277      // build project descendant list
278      projectAncestors.Keys.ToList().ForEach(k => projectDescendants.Add(k, new HashSet<Guid>()));
279      foreach (var pa in projectAncestors) {
280        foreach (var ancestor in pa.Value) {
281          projectDescendants[ancestor].Add(pa.Key);
282        }
283      }
284    }
285
286    private void RefreshDisabledParentProjects() {
287      disabledParentProjects = new HashSet<Project>();
288
289      foreach (var pid in projects
290        .Where(x => x.ParentProjectId.HasValue)
291        .SelectMany(x => projectAncestors[x.Id]).Distinct()
292        .Where(x => !projects.Select(y => y.Id).Contains(x))) {
293        var p = new Project();
294        p.Id = pid;
295        p.ParentProjectId = projectAncestors[pid].FirstOrDefault();
296        p.Name = projectNames[pid];
297        disabledParentProjects.Add(p);
298      }
299    }
300
301    private void RefreshDisabledParentResources() {
302      disabledParentResources = new HashSet<Resource>();
303
304      foreach (var rid in resources
305        .Where(x => x.ParentResourceId.HasValue)
306        .SelectMany(x => resourceAncestors[x.Id]).Distinct()
307        .Where(x => !resources.Select(y => y.Id).Contains(x))) {
308        var r = new SlaveGroup();
309        r.Id = rid;
310        r.ParentResourceId = resourceAncestors[rid].FirstOrDefault();
311        r.Name = resourceNames[rid];
312        disabledParentResources.Add(r);
313      }
314    }
315
316    public void RefreshJobs() {
317      var projectIds = new List<Guid>();
318      jobs = new Dictionary<Guid, HiveItemCollection<RefreshableJob>>();
319      tasks = new Dictionary<Guid, List<LightweightTask>>();
320
321      HiveServiceLocator.Instance.CallHiveService(service => {
322        service.GetProjectsForAdministration().ForEach(p => projectIds.Add(p.Id));
323        if(projectIds.Any()) {
324          projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<RefreshableJob>()));
325          var unsortedJobs = service.GetJobsByProjectIds(projectIds)
326            .OrderBy(x => x.DateCreated).ToList();
327         
328          unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
329          unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
330          unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
331
332          foreach(var job in jobs.SelectMany(x => x.Value))
333            LoadLightweightJob(job);
334        }
335      });
336    }
337
338    public void LoadLightweightJob(RefreshableJob refreshableJob) {
339      var job = refreshableJob.Job;
340      var lightweightTasks = HiveServiceLocator.Instance.CallHiveService(s => s.GetLightweightJobTasksWithoutStateLog(job.Id));
341
342      if (tasks.ContainsKey(job.Id)) {
343        tasks[job.Id].Clear();
344        tasks[job.Id].AddRange(lightweightTasks);
345      } else {
346        tasks.Add(job.Id, new List<LightweightTask>(lightweightTasks));       
347      }
348
349      if (lightweightTasks != null && lightweightTasks.Count > 0 && lightweightTasks.All(x => x.Id != Guid.Empty)) {
350        if (lightweightTasks.All(x =>
351          x.State == TaskState.Finished
352          || x.State == TaskState.Aborted
353          || x.State == TaskState.Failed)) {
354          refreshableJob.ExecutionState = ExecutionState.Stopped;
355          refreshableJob.RefreshAutomatically = false;
356        } else if (
357          lightweightTasks
358            .Where(x => x.ParentTaskId != null)
359            .All(x =>
360              x.State != TaskState.Waiting
361              || x.State != TaskState.Transferring
362              || x.State != TaskState.Calculating)
363          && lightweightTasks
364             .Where(x => x.ParentTaskId != null)
365             .Any(x => x.State == TaskState.Paused)) {
366          refreshableJob.ExecutionState = ExecutionState.Paused;
367          refreshableJob.RefreshAutomatically = false;
368        } else if (lightweightTasks.Any(x => x.State == TaskState.Calculating
369                                  || x.State == TaskState.Transferring
370                                  || x.State == TaskState.Waiting)) {
371          refreshableJob.ExecutionState = ExecutionState.Started;
372        }
373
374        refreshableJob.ExecutionTime = TimeSpan.FromMilliseconds(lightweightTasks.Sum(x => x.ExecutionTime.TotalMilliseconds));
375      }
376    }
377
378    public void SortJobs() {
379      for(int i = 0; i < jobs.Count; i++) {
380        var projectId = jobs.Keys.ElementAt(i);
381        var unsortedJobs = jobs.Values.ElementAt(i);
382
383        var sortedJobs = new HiveItemCollection<RefreshableJob>();
384        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.DeletionPending));
385        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.StatisticsPending));
386        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.Online));
387
388        jobs[projectId] = sortedJobs;
389      }
390    }
391
392    #endregion
393
394    #region Refresh downtime calendar
395    public void RefreshCalendar() {
396      if (downtimeForResourceId != null && downtimeForResourceId != Guid.Empty) {
397        OnRefreshing();
398
399        try {
400          downtimes = new ItemList<Downtime>();
401
402          HiveServiceLocator.Instance.CallHiveService(service => {
403            service.GetDowntimesForResource(downtimeForResourceId).ForEach(d => downtimes.Add(d));
404          });
405        }
406        catch {
407          throw;
408        }
409        finally {
410          OnRefreshed();
411        }
412      }
413    }
414    #endregion
415
416    #region Store
417    public static void Store(IHiveItem item, CancellationToken cancellationToken) {
418      if (item.Id == Guid.Empty) {
419        if (item is SlaveGroup) {
420          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlaveGroup((SlaveGroup)item));
421        }
422        if (item is Slave) {
423          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlave((Slave)item));
424        }
425        if (item is Downtime) {
426          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddDowntime((Downtime)item));
427        }
428        if (item is Project) {
429          item.Id = HiveServiceLocator.Instance.CallHiveService(s => s.AddProject((Project)item));
430        }
431      } else {
432        if (item is SlaveGroup) {
433          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlaveGroup((SlaveGroup)item));
434        }
435        if (item is Slave) {
436          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlave((Slave)item));
437        }
438        if (item is Downtime) {
439          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateDowntime((Downtime)item));
440        }
441        if (item is Project) {
442          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateProject((Project)item));
443        }
444      }
445    }
446    #endregion
447
448    #region Delete
449    public static void Delete(IHiveItem item) {
450      if (item is SlaveGroup) {
451        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlaveGroup(item.Id));
452      } else if (item is Slave) {
453        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlave(item.Id));
454      } else if (item is Downtime) {
455        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteDowntime(item.Id));
456      } else if (item is Project) {
457        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteProject(item.Id));
458      }
459    }
460
461    public static void RemoveJobs(List<Guid> jobIds) {
462      HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateJobStates(jobIds, JobState.StatisticsPending));
463    }
464    #endregion
465
466    #region Job Handling
467
468    public static void ResumeJob(RefreshableJob refreshableJob) {
469      HiveServiceLocator.Instance.CallHiveService(service => {
470        var tasks = service.GetLightweightJobTasksWithoutStateLog(refreshableJob.Id);
471        foreach (var task in tasks) {
472          if (task.State == TaskState.Paused) {
473            service.RestartTask(task.Id);
474          }
475        }
476      });
477      refreshableJob.ExecutionState = ExecutionState.Started;
478    }
479
480    public static void PauseJob(RefreshableJob refreshableJob) {
481      HiveServiceLocator.Instance.CallHiveService(service => {
482        var tasks = service.GetLightweightJobTasksWithoutStateLog(refreshableJob.Id);
483        foreach (var task in tasks) {
484          if (task.State != TaskState.Finished && task.State != TaskState.Aborted && task.State != TaskState.Failed)
485            service.PauseTask(task.Id);
486        }
487      });
488      refreshableJob.ExecutionState = ExecutionState.Paused;
489    }
490
491    public static void StopJob(RefreshableJob refreshableJob) {
492      HiveServiceLocator.Instance.CallHiveService(service => {
493        var tasks = service.GetLightweightJobTasksWithoutStateLog(refreshableJob.Id);
494        foreach (var task in tasks) {
495          if (task.State != TaskState.Finished && task.State != TaskState.Aborted && task.State != TaskState.Failed)
496            service.StopTask(task.Id);
497        }
498      });
499      refreshableJob.ExecutionState = ExecutionState.Stopped;
500    }
501
502    public static void RemoveJob(RefreshableJob refreshableJob) {
503      HiveServiceLocator.Instance.CallHiveService((service) => {
504        service.UpdateJobState(refreshableJob.Id, JobState.StatisticsPending);
505      });
506    }
507    #endregion
508
509    public void ResetDowntime() {
510      downtimeForResourceId = Guid.Empty;
511      if (downtimes != null) {
512        downtimes.Clear();
513      }
514    }
515
516    #region Helper
517    public IEnumerable<Project> GetAvailableProjectAncestors(Guid id) {
518      if (projectAncestors.ContainsKey(id)) return projects.Where(x => projectAncestors[id].Contains(x.Id));
519      else return Enumerable.Empty<Project>();
520    }
521
522    public IEnumerable<Project> GetAvailableProjectDescendants(Guid id) {
523      if(projectDescendants.ContainsKey(id)) return projects.Where(x => projectDescendants[id].Contains(x.Id));
524      else return Enumerable.Empty<Project>();
525    }
526
527    public IEnumerable<Resource> GetAvailableResourceAncestors(Guid id) {
528      if (resourceAncestors.ContainsKey(id)) return resources.Where(x => resourceAncestors[id].Contains(x.Id));
529      else return Enumerable.Empty<Resource>();
530    }
531
532    public IEnumerable<Resource> GetAvailableResourceDescendants(Guid id) {
533      if (resourceDescendants.ContainsKey(id)) return resources.Where(x => resourceDescendants[id].Contains(x.Id));
534      else return Enumerable.Empty<Resource>();
535    }
536
537    public IEnumerable<Resource> GetDisabledResourceAncestors(IEnumerable<Resource> availableResources) {
538      var missingParentIds = availableResources
539        .Where(x => x.ParentResourceId.HasValue)
540        .SelectMany(x => resourceAncestors[x.Id]).Distinct()
541        .Where(x => !availableResources.Select(y => y.Id).Contains(x));
542
543      return resources.OfType<SlaveGroup>().Union(disabledParentResources).Where(x => missingParentIds.Contains(x.Id));
544    }
545
546    public bool CheckAccessToAdminAreaGranted() {
547      if(projects != null) {
548        return projects.Count > 0;
549      } else {
550        bool accessGranted = false;
551        HiveServiceLocator.Instance.CallHiveService(s => {
552          accessGranted = s.CheckAccessToAdminAreaGranted();
553        });
554        return accessGranted;
555      }
556    }
557
558    public bool CheckOwnershipOfResource(Resource res, Guid userId) {
559      if (res == null || userId == Guid.Empty) return false;
560
561      if (res.OwnerUserId == userId) {
562        return true;
563      } else if(resourceAncestors.ContainsKey(res.Id)) {
564        return GetAvailableResourceAncestors(res.Id).Where(x => x.OwnerUserId == userId).Any();
565      }
566
567      return false;
568    }
569
570    public bool CheckOwnershipOfProject(Project pro, Guid userId) {
571      if (pro == null || userId == Guid.Empty) return false;
572
573      if (pro.OwnerUserId == userId) {
574        return true;
575      } else if (projectAncestors.ContainsKey(pro.Id)) {
576        return GetAvailableProjectAncestors(pro.Id).Where(x => x.OwnerUserId == userId).Any();
577      }
578
579      return false;
580    }
581
582    public bool CheckOwnershipOfParentProject(Project pro, Guid userId) {
583      if (pro == null || userId == Guid.Empty) return false;
584
585      if(projectAncestors.ContainsKey(pro.Id)) {
586        return GetAvailableProjectAncestors(pro.Id).Any(x => x.OwnerUserId == userId);
587      }
588
589      if (pro.ParentProjectId != null && pro.ParentProjectId != Guid.Empty) {
590        var parent = projects.FirstOrDefault(x => x.Id == pro.ParentProjectId.Value);
591        if (parent != null)
592          return parent.OwnerUserId == userId || GetAvailableProjectAncestors(parent.Id).Any(x => x.OwnerUserId == userId);
593      }
594
595      return false;
596    }
597
598    public bool CheckParentChange(Project child, Project parent) {
599      bool changePossible = true;
600
601      // change is not possible...
602      // ... if the moved project is null
603      // ... or the new parent is not stored yet
604      // ... or there is not parental change
605      if (child == null
606          || (parent != null && parent.Id == Guid.Empty)
607          || (parent != null && parent.Id == child.ParentProjectId)) {
608        changePossible = false;
609      } else if (parent == null && !IsAdmin()) {
610        // ... if parent is null, but user is no admin (only admins are allowed to create root projects)
611        changePossible = false;
612      } else if (parent != null && (!IsAdmin() && parent.OwnerUserId != UserInformation.Instance.User.Id && !CheckOwnershipOfParentProject(parent, UserInformation.Instance.User.Id))) {
613        // ... if the user is no admin nor owner of the new parent or grand..grandparents
614        changePossible = false;
615      } else if(parent != null && projectDescendants.ContainsKey(child.Id)) {
616        // ... if the new parent is among the moved project's descendants
617        changePossible = !GetAvailableProjectDescendants(child.Id).Where(x => x.Id == parent.Id).Any();
618      }
619
620      return changePossible;
621    }
622
623    public bool CheckParentChange(Resource child, Resource parent) {
624      bool changePossible = true;
625
626      // change is not possisble...
627      // ... if the child resource is null
628      // ... or the child resource equals the parent
629      // ... or the new parent is not stored yet
630      // ... or the new parent is a slave
631      // ... or there is not parental change
632      if (child == null 
633        || child == parent
634        || (parent != null && parent.Id == Guid.Empty)
635        || (parent != null && parent is Slave)
636        || (parent != null && parent.Id == child.ParentResourceId)) {
637        changePossible = false;
638      } else if (parent != null && resourceDescendants.ContainsKey(child.Id)) {
639        // ... or if the new parent is among the moved resource's descendants
640        changePossible = !GetAvailableResourceDescendants(child.Id).Where(x => x.Id == parent.Id).Any();
641      }
642
643      return changePossible;
644    }
645
646    public IEnumerable<Resource> GetAssignedResourcesForJob(Guid jobId) {
647      var assignedJobResource =  HiveServiceLocator.Instance.CallHiveService(service => service.GetAssignedResourcesForJob(jobId));
648      return Resources.Where(x => assignedJobResource.Select(y => y.ResourceId).Contains(x.Id));
649    }
650
651    private bool IsAdmin() {
652      return HiveRoles.CheckAdminUserPermissions();
653    }
654    #endregion
655  }
656}
Note: See TracBrowser for help on using the repository browser.