Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 16209 was 16209, checked in by jzenisek, 5 years ago

#2839:

  • adapted job execution implementation at ProjectJobsView
  • prohibited resource checking for non-admins
File size: 24.9 KB
RevLine 
[6976]1#region License Information
2/* HeuristicLab
[15583]3 * Copyright (C) 2002-2018 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;
23using System.Threading;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
[16117]26using System.Collections.Generic;
27using System.Linq;
[16202]28using HeuristicLab.Clients.Access;
[6976]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;
79        }
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)
168              .ForEach(a => projectResourceAssignments.Add(a));
[16208]169            projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<RefreshableJob>()));
[16117]170            var unsortedJobs = service.GetJobsByProjectIds(projectIds)
171              .OrderBy(x => x.DateCreated).ToList();
172
[16208]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)));
[16117]176
[16208]177            foreach (var job in jobs.SelectMany(x => x.Value))
178              LoadLightweightJob(job);
179
[16117]180            projectNames = service.GetProjectNames();
181            resourceNames = service.GetResourceNames();
182          }
[6976]183        });
[16117]184
185        UpdateResourceGenealogy();
186        UpdateProjectGenealogy();
187        RefreshDisabledParentProjects();
188        RefreshDisabledParentResources();
[6976]189      }
190      catch {
191        throw;
192      }
193      finally {
194        OnRefreshed();
195      }
196    }
[16117]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>();
[16208]318      jobs = new Dictionary<Guid, HiveItemCollection<RefreshableJob>>();
[16209]319      tasks = new Dictionary<Guid, List<LightweightTask>>();
[16117]320
321      HiveServiceLocator.Instance.CallHiveService(service => {
322        service.GetProjectsForAdministration().ForEach(p => projectIds.Add(p.Id));
323        if(projectIds.Any()) {
[16208]324          projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<RefreshableJob>()));
[16117]325          var unsortedJobs = service.GetJobsByProjectIds(projectIds)
326            .OrderBy(x => x.DateCreated).ToList();
[16208]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);
[16117]334        }
335      });
336    }
337
[16209]338    public void LoadLightweightJob(RefreshableJob refreshableJob) {
[16208]339      var job = refreshableJob.Job;
[16209]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 =>
[16208]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 (
[16209]357          lightweightTasks
[16208]358            .Where(x => x.ParentTaskId != null)
359            .All(x =>
360              x.State != TaskState.Waiting
361              || x.State != TaskState.Transferring
362              || x.State != TaskState.Calculating)
[16209]363          && lightweightTasks
[16208]364             .Where(x => x.ParentTaskId != null)
365             .Any(x => x.State == TaskState.Paused)) {
366          refreshableJob.ExecutionState = ExecutionState.Paused;
367          refreshableJob.RefreshAutomatically = false;
[16209]368        } else if (lightweightTasks.Any(x => x.State == TaskState.Calculating
[16208]369                                  || x.State == TaskState.Transferring
370                                  || x.State == TaskState.Waiting)) {
371          refreshableJob.ExecutionState = ExecutionState.Started;
372        }
[16209]373
374        refreshableJob.ExecutionTime = TimeSpan.FromMilliseconds(lightweightTasks.Sum(x => x.ExecutionTime.TotalMilliseconds));
[16208]375      }
376    }
377
[16117]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
[16208]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));
[16117]387
388        jobs[projectId] = sortedJobs;
389      }
390    }
391
[6976]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
[7132]402          HiveServiceLocator.Instance.CallHiveService(service => {
[6976]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) {
[7132]420          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlaveGroup((SlaveGroup)item));
[6976]421        }
422        if (item is Slave) {
[7132]423          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddSlave((Slave)item));
[6976]424        }
425        if (item is Downtime) {
[7132]426          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddDowntime((Downtime)item));
[6976]427        }
[16117]428        if (item is Project) {
429          item.Id = HiveServiceLocator.Instance.CallHiveService(s => s.AddProject((Project)item));
430        }
[6976]431      } else {
432        if (item is SlaveGroup) {
[7132]433          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlaveGroup((SlaveGroup)item));
[6976]434        }
435        if (item is Slave) {
[7132]436          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateSlave((Slave)item));
[6976]437        }
438        if (item is Downtime) {
[7132]439          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateDowntime((Downtime)item));
[6976]440        }
[16117]441        if (item is Project) {
442          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateProject((Project)item));
443        }
[6976]444      }
445    }
446    #endregion
447
448    #region Delete
449    public static void Delete(IHiveItem item) {
450      if (item is SlaveGroup) {
[7132]451        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlaveGroup(item.Id));
[6976]452      } else if (item is Slave) {
[7132]453        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteSlave(item.Id));
[6976]454      } else if (item is Downtime) {
[7132]455        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteDowntime(item.Id));
[16117]456      } else if (item is Project) {
457        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteProject(item.Id));
[6976]458      }
459    }
[16117]460
[16208]461    public static void RemoveJobs(List<Guid> jobIds) {
[16117]462      HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateJobStates(jobIds, JobState.StatisticsPending));
463    }
[6976]464    #endregion
465
[16208]466    #region Job Handling
467
468    public static void ResumeJob(RefreshableJob refreshableJob) {
469      HiveServiceLocator.Instance.CallHiveService(service => {
[16209]470        var tasks = service.GetLightweightJobTasksWithoutStateLog(refreshableJob.Id);
471        foreach (var task in tasks) {
472          if (task.State == TaskState.Paused) {
473            service.RestartTask(task.Id);
[16208]474          }
475        }
476      });
477      refreshableJob.ExecutionState = ExecutionState.Started;
478    }
479
480    public static void PauseJob(RefreshableJob refreshableJob) {
481      HiveServiceLocator.Instance.CallHiveService(service => {
[16209]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);
[16208]486        }
487      });
488      refreshableJob.ExecutionState = ExecutionState.Paused;
489    }
490
491    public static void StopJob(RefreshableJob refreshableJob) {
492      HiveServiceLocator.Instance.CallHiveService(service => {
[16209]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);
[16208]497        }
498      });
499      refreshableJob.ExecutionState = ExecutionState.Stopped;
500    }
501
502    public static void RemoveJob(RefreshableJob refreshableJob) {
[16209]503      HiveServiceLocator.Instance.CallHiveService((service) => {
504        service.UpdateJobState(refreshableJob.Id, JobState.StatisticsPending);
[16208]505      });
506    }
507    #endregion
508
[6976]509    public void ResetDowntime() {
510      downtimeForResourceId = Guid.Empty;
511      if (downtimes != null) {
512        downtimes.Clear();
513      }
514    }
[16117]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
[16202]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
[16117]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)) {
[16202]586        return GetAvailableProjectAncestors(pro.Id).Any(x => x.OwnerUserId == userId);
[16117]587      }
588
[16202]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
[16117]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
[16202]605      if (child == null
606          || (parent != null && parent.Id == Guid.Empty)
607          || (parent != null && parent.Id == child.ParentProjectId)) {
[16117]608        changePossible = false;
[16202]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;
[16117]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    }
[16202]645
[16209]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
[16202]651    private bool IsAdmin() {
652      return HiveRoles.CheckAdminUserPermissions();
653    }
[16117]654    #endregion
[6976]655  }
656}
Note: See TracBrowser for help on using the repository browser.