Ignore:
Timestamp:
09/13/18 13:18:45 (11 months ago)
Author:
ddorfmei
Message:

#2931: Merged [16046-16138/trunk] into branch

Location:
branches/2931_OR-Tools_LP_MIP
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/2931_OR-Tools_LP_MIP

  • branches/2931_OR-Tools_LP_MIP/HeuristicLab.Clients.Hive

  • branches/2931_OR-Tools_LP_MIP/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs

    r15583 r16139  
    2424using HeuristicLab.Common;
    2525using HeuristicLab.Core;
     26using System.Collections.Generic;
     27using System.Linq;
    2628
    2729namespace HeuristicLab.Clients.Hive {
     
    3638    }
    3739
     40    #region Properties
    3841    private IItemList<Resource> resources;
    3942    public IItemList<Resource> Resources {
     
    5760    }
    5861
     62    private IItemList<Project> projects;
     63    public IItemList<Project> Projects {
     64      get { return projects; }
     65    }
     66
     67    private IItemList<AssignedProjectResource> projectResourceAssignments;
     68    public IItemList<AssignedProjectResource> ProjectResourceAssignments {
     69      get { return projectResourceAssignments; }
     70    }
     71
     72    private Dictionary<Guid, HiveItemCollection<Job>> jobs;
     73    public Dictionary<Guid, HiveItemCollection<Job>> Jobs {
     74      get { return jobs; }
     75      set {
     76        if (value != jobs)
     77          jobs = value;
     78        }
     79    }
     80
     81    private Dictionary<Guid, HashSet<Guid>> projectAncestors;
     82    public Dictionary<Guid, HashSet<Guid>> ProjectAncestors {
     83      get { return projectAncestors; }
     84    }
     85
     86    private Dictionary<Guid, HashSet<Guid>> projectDescendants;
     87    public Dictionary<Guid, HashSet<Guid>> ProjectDescendants {
     88      get { return projectDescendants; }
     89    }
     90
     91    private Dictionary<Guid, HashSet<Guid>> resourceAncestors;
     92    public Dictionary<Guid, HashSet<Guid>> ResourceAncestors {
     93      get { return resourceAncestors; }
     94    }
     95
     96    private Dictionary<Guid, HashSet<Guid>> resourceDescendants;
     97    public Dictionary<Guid, HashSet<Guid>> ResourceDescendants {
     98      get { return resourceDescendants; }
     99    }
     100
     101    private Dictionary<Guid, string> projectNames;
     102    public Dictionary<Guid, string> ProjectNames {
     103      get { return projectNames; }
     104    }
     105
     106    private HashSet<Project> disabledParentProjects;
     107    public HashSet<Project> DisabledParentProjects {
     108      get { return disabledParentProjects; }
     109    }
     110
     111    private Dictionary<Guid, string> resourceNames;
     112    public Dictionary<Guid, string> ResourceNames {
     113      get { return resourceNames; }
     114    }
     115
     116    private HashSet<Resource> disabledParentResources;
     117    public HashSet<Resource> DisabledParentResources {
     118      get { return disabledParentResources; }
     119    }
     120    #endregion
     121
    59122    #region Events
    60123    public event EventHandler Refreshing;
     
    78141      try {
    79142        resources = new ItemList<Resource>();
     143        projects = new ItemList<Project>();
     144        projectResourceAssignments = new ItemList<AssignedProjectResource>();
     145        jobs = new Dictionary<Guid, HiveItemCollection<Job>>();
     146        projectNames = new Dictionary<Guid, string>();
     147        resourceNames = new Dictionary<Guid, string>();
     148
     149        projectAncestors = new Dictionary<Guid, HashSet<Guid>>();
     150        projectDescendants = new Dictionary<Guid, HashSet<Guid>>();
     151        resourceAncestors = new Dictionary<Guid, HashSet<Guid>>();
     152        resourceDescendants = new Dictionary<Guid, HashSet<Guid>>();
    80153
    81154        HiveServiceLocator.Instance.CallHiveService(service => {
    82           service.GetSlaveGroups().ForEach(g => resources.Add(g));
    83           service.GetSlaves().ForEach(s => resources.Add(s));
     155          service.GetSlaveGroupsForAdministration().ForEach(g => resources.Add(g));
     156          service.GetSlavesForAdministration().ForEach(s => resources.Add(s));
     157          service.GetProjectsForAdministration().ForEach(p => projects.Add(p));
     158          var projectIds = projects.Select(p => p.Id).ToList();
     159          if (projectIds.Any()) {
     160            service.GetAssignedResourcesForProjectsAdministration(projectIds)
     161              .ForEach(a => projectResourceAssignments.Add(a));
     162            projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<Job>()));
     163            var unsortedJobs = service.GetJobsByProjectIds(projectIds)
     164              .OrderBy(x => x.DateCreated).ToList();
     165
     166            unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
     167            unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
     168            unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
     169
     170            projectNames = service.GetProjectNames();
     171            resourceNames = service.GetResourceNames();
     172          }
    84173        });
     174
     175        UpdateResourceGenealogy();
     176        UpdateProjectGenealogy();
     177        RefreshDisabledParentProjects();
     178        RefreshDisabledParentResources();
    85179      }
    86180      catch {
     
    91185      }
    92186    }
     187
     188    //public void UpdateResourceGenealogy(IItemList<Resource> resources) {
     189    //  resourceAncestors.Clear();
     190    //  resourceDescendants.Clear();
     191
     192    //  foreach (var r in resources) {
     193    //    resourceAncestors.Add(r.Id, new HashSet<Resource>());
     194    //    resourceDescendants.Add(r.Id, new HashSet<Resource>());
     195    //  }
     196
     197    //  foreach (var r in resources) {
     198    //    var parentResourceId = r.ParentResourceId;
     199    //    while (parentResourceId != null) {
     200    //      var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
     201    //      if (parent != null) {
     202    //        resourceAncestors[r.Id].Add(parent);
     203    //        resourceDescendants[parent.Id].Add(r);
     204    //        parentResourceId = parent.ParentResourceId;
     205    //      } else {
     206    //        parentResourceId = null;
     207    //      }
     208    //    }
     209    //  }
     210    //}
     211
     212    //public void UpdateProjectGenealogy(IItemList<Project> projects) {
     213    //  projectAncestors.Clear();
     214    //  projectDescendants.Clear();
     215
     216    //  foreach (var p in projects) {
     217    //    projectAncestors.Add(p.Id, new HashSet<Project>());
     218    //    projectDescendants.Add(p.Id, new HashSet<Project>());
     219    //  }
     220
     221    //  foreach (var p in projects) {
     222    //    var parentProjectId = p.ParentProjectId;
     223    //    while (parentProjectId != null) {
     224    //      var parent = projects.SingleOrDefault(x => x.Id == parentProjectId);
     225    //      if (parent != null) {
     226    //        projectAncestors[p.Id].Add(parent);
     227    //        projectDescendants[parent.Id].Add(p);
     228    //        parentProjectId = parent.ParentProjectId;
     229    //      } else {
     230    //        parentProjectId = null;
     231    //      }
     232    //    }
     233    //  }
     234    //}
     235
     236    private void UpdateResourceGenealogy() {
     237      resourceAncestors.Clear();
     238      resourceDescendants.Clear();
     239
     240      // fetch resource ancestor set
     241      HiveServiceLocator.Instance.CallHiveService(service => {
     242        var ra = service.GetResourceGenealogy();
     243        ra.Keys.ToList().ForEach(k => resourceAncestors.Add(k, new HashSet<Guid>()));
     244        resourceAncestors.Keys.ToList().ForEach(k => resourceAncestors[k].UnionWith(ra[k]));
     245      });
     246
     247      // build resource descendant set
     248      resourceAncestors.Keys.ToList().ForEach(k => resourceDescendants.Add(k, new HashSet<Guid>()));
     249      foreach (var ra in resourceAncestors) {
     250        foreach (var ancestor in ra.Value) {
     251          resourceDescendants[ancestor].Add(ra.Key);
     252        }
     253      }
     254    }
     255
     256    private void UpdateProjectGenealogy() {
     257      projectAncestors.Clear();
     258      projectDescendants.Clear();
     259
     260      // fetch project ancestor list
     261      HiveServiceLocator.Instance.CallHiveService(service => {
     262        var pa = service.GetProjectGenealogy();
     263        pa.Keys.ToList().ForEach(k => projectAncestors.Add(k, new HashSet<Guid>()));
     264        projectAncestors.Keys.ToList().ForEach(k => projectAncestors[k].UnionWith(pa[k]));
     265      });
     266
     267      // build project descendant list
     268      projectAncestors.Keys.ToList().ForEach(k => projectDescendants.Add(k, new HashSet<Guid>()));
     269      foreach (var pa in projectAncestors) {
     270        foreach (var ancestor in pa.Value) {
     271          projectDescendants[ancestor].Add(pa.Key);
     272        }
     273      }
     274    }
     275
     276    private void RefreshDisabledParentProjects() {
     277      disabledParentProjects = new HashSet<Project>();
     278
     279      foreach (var pid in projects
     280        .Where(x => x.ParentProjectId.HasValue)
     281        .SelectMany(x => projectAncestors[x.Id]).Distinct()
     282        .Where(x => !projects.Select(y => y.Id).Contains(x))) {
     283        var p = new Project();
     284        p.Id = pid;
     285        p.ParentProjectId = projectAncestors[pid].FirstOrDefault();
     286        p.Name = projectNames[pid];
     287        disabledParentProjects.Add(p);
     288      }
     289    }
     290
     291    private void RefreshDisabledParentResources() {
     292      disabledParentResources = new HashSet<Resource>();
     293
     294      foreach (var rid in resources
     295        .Where(x => x.ParentResourceId.HasValue)
     296        .SelectMany(x => resourceAncestors[x.Id]).Distinct()
     297        .Where(x => !resources.Select(y => y.Id).Contains(x))) {
     298        var r = new SlaveGroup();
     299        r.Id = rid;
     300        r.ParentResourceId = resourceAncestors[rid].FirstOrDefault();
     301        r.Name = resourceNames[rid];
     302        disabledParentResources.Add(r);
     303      }
     304    }
     305
     306    public void RefreshJobs() {
     307      var projectIds = new List<Guid>();
     308      jobs = new Dictionary<Guid, HiveItemCollection<Job>>();
     309
     310      HiveServiceLocator.Instance.CallHiveService(service => {
     311        service.GetProjectsForAdministration().ForEach(p => projectIds.Add(p.Id));
     312        if(projectIds.Any()) {
     313          projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<Job>()));
     314          var unsortedJobs = service.GetJobsByProjectIds(projectIds)
     315            .OrderBy(x => x.DateCreated).ToList();
     316          unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
     317          unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
     318          unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
     319        }
     320      });
     321    }
     322
     323    public void SortJobs() {
     324      for(int i = 0; i < jobs.Count; i++) {
     325        var projectId = jobs.Keys.ElementAt(i);
     326        var unsortedJobs = jobs.Values.ElementAt(i);
     327
     328        var sortedJobs = new HiveItemCollection<Job>();
     329        sortedJobs.AddRange(unsortedJobs.Where(j => j.State == JobState.DeletionPending));
     330        sortedJobs.AddRange(unsortedJobs.Where(j => j.State == JobState.StatisticsPending));
     331        sortedJobs.AddRange(unsortedJobs.Where(j => j.State == JobState.Online));
     332
     333        jobs[projectId] = sortedJobs;
     334      }
     335    }
     336
    93337    #endregion
    94338
     
    127371          item.Id = HiveServiceLocator.Instance.CallHiveService((s) => s.AddDowntime((Downtime)item));
    128372        }
     373        if (item is Project) {
     374          item.Id = HiveServiceLocator.Instance.CallHiveService(s => s.AddProject((Project)item));
     375        }
    129376      } else {
    130377        if (item is SlaveGroup) {
     
    136383        if (item is Downtime) {
    137384          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateDowntime((Downtime)item));
     385        }
     386        if (item is Project) {
     387          HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateProject((Project)item));
    138388        }
    139389      }
     
    149399      } else if (item is Downtime) {
    150400        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteDowntime(item.Id));
    151       }
     401      } else if (item is Project) {
     402        HiveServiceLocator.Instance.CallHiveService((s) => s.DeleteProject(item.Id));
     403      }
     404    }
     405
     406    public static void DeleteJobs(List<Guid> jobIds) {
     407
     408      HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateJobStates(jobIds, JobState.StatisticsPending));
    152409    }
    153410    #endregion
     
    159416      }
    160417    }
     418
     419    #region Helper
     420    public IEnumerable<Project> GetAvailableProjectAncestors(Guid id) {
     421      if (projectAncestors.ContainsKey(id)) return projects.Where(x => projectAncestors[id].Contains(x.Id));
     422      else return Enumerable.Empty<Project>();
     423    }
     424
     425    public IEnumerable<Project> GetAvailableProjectDescendants(Guid id) {
     426      if(projectDescendants.ContainsKey(id)) return projects.Where(x => projectDescendants[id].Contains(x.Id));
     427      else return Enumerable.Empty<Project>();
     428    }
     429
     430    public IEnumerable<Resource> GetAvailableResourceAncestors(Guid id) {
     431      if (resourceAncestors.ContainsKey(id)) return resources.Where(x => resourceAncestors[id].Contains(x.Id));
     432      else return Enumerable.Empty<Resource>();
     433    }
     434
     435    public IEnumerable<Resource> GetAvailableResourceDescendants(Guid id) {
     436      if (resourceDescendants.ContainsKey(id)) return resources.Where(x => resourceDescendants[id].Contains(x.Id));
     437      else return Enumerable.Empty<Resource>();
     438    }
     439
     440    public bool CheckAccessToAdminAreaGranted() {
     441      if(projects != null) {
     442        return projects.Count > 0;
     443      } else {
     444        bool accessGranted = false;
     445        HiveServiceLocator.Instance.CallHiveService(s => {
     446          accessGranted = s.CheckAccessToAdminAreaGranted();
     447        });
     448        return accessGranted;
     449      }
     450    }
     451
     452    public bool CheckOwnershipOfResource(Resource res, Guid userId) {
     453      if (res == null || userId == Guid.Empty) return false;
     454
     455      if (res.OwnerUserId == userId) {
     456        return true;
     457      } else if(resourceAncestors.ContainsKey(res.Id)) {
     458        return GetAvailableResourceAncestors(res.Id).Where(x => x.OwnerUserId == userId).Any();
     459      }
     460
     461      return false;
     462    }
     463
     464    public bool CheckOwnershipOfProject(Project pro, Guid userId) {
     465      if (pro == null || userId == Guid.Empty) return false;
     466
     467      if (pro.OwnerUserId == userId) {
     468        return true;
     469      } else if (projectAncestors.ContainsKey(pro.Id)) {
     470        return GetAvailableProjectAncestors(pro.Id).Where(x => x.OwnerUserId == userId).Any();
     471      }
     472
     473      return false;
     474    }
     475
     476    public bool CheckOwnershipOfParentProject(Project pro, Guid userId) {
     477      if (pro == null || userId == Guid.Empty) return false;
     478
     479      if(projectAncestors.ContainsKey(pro.Id)) {
     480        return GetAvailableProjectAncestors(pro.Id).Where(x => x.OwnerUserId == userId).Any();
     481      }
     482
     483      return false;
     484    }
     485
     486    public bool CheckParentChange(Project child, Project parent) {
     487      bool changePossible = true;
     488
     489      // change is not possible...
     490      // ... if the moved project is null
     491      // ... or the new parent is not stored yet
     492      // ... or there is not parental change
     493      if (child == null
     494        || (parent != null && parent.Id == Guid.Empty)
     495        || (parent != null && parent.Id == child.ParentProjectId)) {
     496        changePossible = false;
     497      } else if(parent != null && projectDescendants.ContainsKey(child.Id)) {
     498        // ... if the new parent is among the moved project's descendants
     499        changePossible = !GetAvailableProjectDescendants(child.Id).Where(x => x.Id == parent.Id).Any();
     500      }
     501
     502      return changePossible;
     503    }
     504
     505    public bool CheckParentChange(Resource child, Resource parent) {
     506      bool changePossible = true;
     507
     508      // change is not possisble...
     509      // ... if the child resource is null
     510      // ... or the child resource equals the parent
     511      // ... or the new parent is not stored yet
     512      // ... or the new parent is a slave
     513      // ... or there is not parental change
     514      if (child == null
     515        || child == parent
     516        || (parent != null && parent.Id == Guid.Empty)
     517        || (parent != null && parent is Slave)
     518        || (parent != null && parent.Id == child.ParentResourceId)) {
     519        changePossible = false;
     520      } else if (parent != null && resourceDescendants.ContainsKey(child.Id)) {
     521        // ... or if the new parent is among the moved resource's descendants
     522        changePossible = !GetAvailableResourceDescendants(child.Id).Where(x => x.Id == parent.Id).Any();
     523      }
     524
     525      return changePossible;
     526    }
     527    #endregion
    161528  }
    162529}
Note: See TracChangeset for help on using the changeset viewer.