Ignore:
Timestamp:
10/18/18 16:16:31 (17 months ago)
Author:
gkronber
Message:

#2915: merged changes in the trunk up to current HEAD (r15951:16232) into the branch

Location:
branches/2915-AbsoluteSymbol
Files:
1 deleted
12 edited
5 copied

Legend:

Unmodified
Added
Removed
  • branches/2915-AbsoluteSymbol

  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive

  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/Converter.cs

    r15583 r16240  
    121121        OwnerUserId = source.OwnerUserId,
    122122        DateCreated = source.DateCreated,
    123         ResourceNames = source.ResourceIds
     123        ProjectId = source.ProjectId,
     124        State = source.State.ToDto()
    124125      };
    125126    }
     
    139140      target.OwnerUserId = source.OwnerUserId;
    140141      target.DateCreated = source.DateCreated;
    141       target.ResourceIds = source.ResourceNames;
     142      target.ProjectId = source.ProjectId;
     143      target.State = source.State.ToEntity();
     144    }
     145    #endregion
     146
     147    #region AssignedJobResource
     148    public static DT.AssignedJobResource ToDto(this DA.AssignedJobResource source) {
     149      if (source == null) return null;
     150      return new DT.AssignedJobResource {
     151        JobId = source.JobId,
     152        ResourceId = source.ResourceId
     153      };
     154    }
     155    public static DA.AssignedJobResource ToEntity(this DT.AssignedJobResource source) {
     156      if (source == null) return null;
     157      var result = new DA.AssignedJobResource();
     158      source.CopyToEntity(result);
     159      return result;
     160    }
     161    public static void CopyToEntity(this DT.AssignedJobResource source, DA.AssignedJobResource target) {
     162      if ((source == null) || (target == null)) return;
     163      target.JobId = source.JobId;
     164      target.ResourceId = source.ResourceId;
    142165    }
    143166    #endregion
     
    221244    #endregion
    222245
    223     #region State
     246    #region TaskState
    224247    public static DT.TaskState ToDto(this DA.TaskState source) {
    225248      switch (source) {
     
    247270        case DT.TaskState.Waiting: return DA.TaskState.Waiting;
    248271        default: return DA.TaskState.Failed;
     272      }
     273    }
     274    #endregion
     275
     276    #region JobState
     277    public static DT.JobState ToDto(this DA.JobState source) {
     278      switch (source) {
     279        case DA.JobState.Online: return DT.JobState.Online;
     280        case DA.JobState.StatisticsPending: return DT.JobState.StatisticsPending;
     281        case DA.JobState.DeletionPending: return DT.JobState.DeletionPending;
     282        default: return DT.JobState.Online;
     283      }
     284    }
     285
     286    public static DA.JobState ToEntity(this DT.JobState source) {
     287      switch (source) {
     288        case DT.JobState.Online: return DA.JobState.Online;
     289        case DT.JobState.StatisticsPending: return DA.JobState.StatisticsPending;
     290        case DT.JobState.DeletionPending: return DA.JobState.DeletionPending;
     291        default: return DA.JobState.Online;
    249292      }
    250293    }
     
    333376    #endregion
    334377
    335     #region ResourcePermission
    336     public static DT.ResourcePermission ToDto(this DA.ResourcePermission source) {
    337       if (source == null) return null;
    338       return new DT.ResourcePermission {
    339         ResourceId = source.ResourceId,
     378    #region Project
     379    public static DT.Project ToDto(this DA.Project source) {
     380      if (source == null) return null;
     381      return new DT.Project {
     382        Id = source.ProjectId,
     383        ParentProjectId = source.ParentProjectId,
     384        DateCreated = source.DateCreated,
     385        Name = source.Name,
     386        Description = source.Description,
     387        OwnerUserId = source.OwnerUserId,
     388        StartDate = source.StartDate,
     389        EndDate = source.EndDate
     390      };
     391    }
     392    public static DA.Project ToEntity(this DT.Project source) {
     393      if (source == null) return null;
     394      var result = new DA.Project();
     395      source.CopyToEntity(result);
     396      return result;
     397    }
     398    public static void CopyToEntity(this DT.Project source, DA.Project target) {
     399      if ((source == null) || (target == null)) return;
     400      target.ProjectId = source.Id;
     401      target.ParentProjectId = source.ParentProjectId;
     402      target.DateCreated = source.DateCreated;
     403      target.Name = source.Name;
     404      target.Description = source.Description;
     405      target.OwnerUserId = source.OwnerUserId;
     406      target.StartDate = source.StartDate;
     407      target.EndDate = source.EndDate;
     408    }
     409    #endregion
     410
     411    #region ProjectPermission
     412    public static DT.ProjectPermission ToDto(this DA.ProjectPermission source) {
     413      if (source == null) return null;
     414      return new DT.ProjectPermission {
     415        ProjectId = source.ProjectId,
    340416        GrantedUserId = source.GrantedUserId,
    341417        GrantedByUserId = source.GrantedByUserId
    342418      };
    343419    }
    344     public static DA.ResourcePermission ToEntity(this DT.ResourcePermission source) {
    345       if (source == null) return null;
    346       var result = new DA.ResourcePermission();
    347       source.CopyToEntity(result);
    348       return result;
    349     }
    350     public static void CopyToEntity(this DT.ResourcePermission source, DA.ResourcePermission target) {
    351       if ((source == null) || (target == null)) return;
    352       target.ResourceId = source.ResourceId;
     420    public static DA.ProjectPermission ToEntity(this DT.ProjectPermission source) {
     421      if (source == null) return null;
     422      var result = new DA.ProjectPermission();
     423      source.CopyToEntity(result);
     424      return result;
     425    }
     426    public static void CopyToEntity(this DT.ProjectPermission source, DA.ProjectPermission target) {
     427      if ((source == null) || (target == null)) return;
     428      target.ProjectId = source.ProjectId;
    353429      target.GrantedUserId = source.GrantedUserId;
    354430      target.GrantedByUserId = source.GrantedByUserId;
     431    }
     432    #endregion
     433
     434    #region AssignedProjectResource
     435    public static DT.AssignedProjectResource ToDto(this DA.AssignedProjectResource source) {
     436      if (source == null) return null;
     437      return new DT.AssignedProjectResource {
     438        ProjectId = source.ProjectId,
     439        ResourceId = source.ResourceId
     440      };
     441    }
     442    public static DA.AssignedProjectResource ToEntity(this DT.AssignedProjectResource source) {
     443      if (source == null) return null;
     444      var result = new DA.AssignedProjectResource();
     445      source.CopyToEntity(result);
     446      return result;
     447    }
     448    public static void CopyToEntity(this DT.AssignedProjectResource source, DA.AssignedProjectResource target) {
     449      if ((source == null) || (target == null)) return;
     450      target.ProjectId = source.ProjectId;
     451      target.ResourceId = source.ResourceId;
    355452    }
    356453    #endregion
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/DataTransfer/Job.cs

    r15583 r16240  
    3232    public DateTime DateCreated { get; set; }
    3333    [DataMember]
    34     public string ResourceNames { get; set; }
     34    public Guid ProjectId { get; set; }
    3535    [DataMember]
    3636    public Permission Permission { get; set; } // the permission for the currently logged in user
    3737    [DataMember]
    3838    public string OwnerUsername { get; set; }
     39    [DataMember]
     40    public JobState State { get; set; }
    3941
    4042    /* ==== some computed statistics ==== */
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj

    r12878 r16240  
    119119  <ItemGroup>
    120120    <Compile Include="Converter.cs" />
     121    <Compile Include="DataTransfer\AssignedJobResource.cs" />
     122    <Compile Include="DataTransfer\AssignedProjectResource.cs" />
    121123    <Compile Include="DataTransfer\Command.cs" />
     124    <Compile Include="DataTransfer\JobState.cs" />
     125    <Compile Include="DataTransfer\Project.cs" />
     126    <Compile Include="DataTransfer\ProjectPermission.cs" />
    122127    <Compile Include="DataTransfer\UserPriority.cs" />
    123     <Compile Include="DataTransfer\ResourcePermission.cs" />
    124128    <Compile Include="DataTransfer\Downtime.cs" />
    125129    <Compile Include="DataTransfer\Heartbeat.cs" />
     
    149153    <Compile Include="Scheduler\JobInfoForScheduler.cs" />
    150154    <Compile Include="Scheduler\RoundRobinTaskScheduler.cs" />
    151     <None Include="app.config" />
     155    <None Include="app.config">
     156      <SubType>Designer</SubType>
     157    </None>
    152158    <None Include="Plugin.cs.frame" />
    153159    <None Include="Properties\AssemblyInfo.cs.frame" />
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/HiveService.cs

    r15583 r16240  
    4141  [HiveOperationContextBehavior]
    4242  public class HiveService : IHiveService {
     43    private const string NOT_AUTHORIZED_PROJECTRESOURCE = "Selected project is not authorized to access the requested resource";
     44    private const string NOT_AUTHORIZED_USERPROJECT = "Current user is not authorized to access the requested project";
     45    private const string NOT_AUTHORIZED_PROJECTOWNER = "The set user is not authorized to own the project";
     46    private const string NO_JOB_UPDATE_POSSIBLE = "This job has already been flagged for deletion, thus, it can not be updated anymore.";
     47
    4348    private static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
    4449
     
    6671
    6772    #region Task Methods
    68     public Guid AddTask(DT.Task task, DT.TaskData taskData, IEnumerable<Guid> resourceIds) {
    69       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     73
     74    public Guid AddTask(DT.Task task, DT.TaskData taskData) {
     75      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     76      AuthorizationManager.AuthorizeForJob(task.JobId, DT.Permission.Full);
    7077      var pm = PersistenceManager;
    7178      using (new PerformanceLogger("AddTask")) {
     
    7582        newTask.JobData = taskData.ToEntity();
    7683        newTask.JobData.LastUpdate = DateTime.Now;
    77         newTask.AssignedResources.AddRange(resourceIds.Select(
    78           x => new DA.AssignedResource {
    79             ResourceId = x
    80           }));
    8184        newTask.State = DA.TaskState.Waiting;
    8285        return pm.UseTransaction(() => {
     
    99102    public Guid AddChildTask(Guid parentTaskId, DT.Task task, DT.TaskData taskData) {
    100103      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    101       IEnumerable<Guid> resourceIds;
    102       var pm = PersistenceManager;
    103       using (new PerformanceLogger("AddChildTask")) {
    104         var assignedResourceDao = pm.AssignedResourceDao;
    105         resourceIds = pm.UseTransaction(() => {
    106           return assignedResourceDao.GetByTaskId(parentTaskId)
    107             .Select(x => x.ResourceId)
    108             .ToList();
    109         });
    110       }
    111104      task.ParentTaskId = parentTaskId;
    112       return AddTask(task, taskData, resourceIds);
     105      return AddTask(task, taskData);
    113106    }
    114107
     
    338331        return pm.UseTransaction(() => {
    339332          var jobs = jobDao.GetAll()
    340             .Where(x => x.OwnerUserId == currentUserId
    341                      || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
    342                                                  && y.GrantedUserId == currentUserId) > 0)
     333            .Where(x => x.State == DA.JobState.Online
     334                          && (x.OwnerUserId == currentUserId
     335                            || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
     336                              && y.GrantedUserId == currentUserId) > 0)
     337                          )
    343338            .Select(x => x.ToDto())
    344339            .ToList();
    345           var statistics = taskDao.GetAll()
    346               .GroupBy(x => x.JobId)
    347               .Select(x => new {
    348                 x.Key,
    349                 TotalCount = x.Count(),
    350                 CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
    351                 FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
    352               })
     340
     341          EvaluateJobs(pm, jobs);
     342          return jobs;
     343        });
     344      }
     345    }
     346
     347    public IEnumerable<DT.Job> GetJobsByProjectId(Guid projectId) {
     348      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     349      var pm = PersistenceManager;
     350      using (new PerformanceLogger("GetJobsByProjectId")) {
     351        var currentUserId = UserManager.CurrentUserId;
     352        var projectDao = pm.ProjectDao;
     353        var jobDao = pm.JobDao;
     354
     355        return pm.UseTransaction(() => {
     356          // check if user is granted to administer the requested projectId
     357          bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     358          List<DA.Project> administrationGrantedProjects;
     359          if (isAdmin) {
     360            administrationGrantedProjects = projectDao.GetAll().ToList();
     361          } else {
     362            administrationGrantedProjects = projectDao
     363              .GetAdministrationGrantedProjectsForUser(currentUserId)             
    353364              .ToList();
    354           foreach (var job in jobs) {
    355             var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
    356             if (statistic != null) {
    357               job.JobCount = statistic.TotalCount;
    358               job.CalculatingCount = statistic.CalculatingCount;
    359               job.FinishedCount = statistic.FinishedCount;
    360             }
    361             job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
    362             if (currentUserId == job.OwnerUserId) {
    363               job.Permission = Permission.Full;
    364             } else {
    365               var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
    366               job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
    367             }
    368           }
    369           return jobs;
    370         });
    371       }
    372     }
    373 
    374     public Guid AddJob(DT.Job jobDto) {
    375       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    376       var pm = PersistenceManager;
     365          }
     366
     367          if (administrationGrantedProjects.Select(x => x.ProjectId).Contains(projectId)) {
     368            var jobs = jobDao.GetByProjectId(projectId)
     369            .Select(x => x.ToDto())
     370            .ToList();
     371
     372            EvaluateJobs(pm, jobs);
     373            return jobs;
     374          } else {
     375            return Enumerable.Empty<DT.Job>();
     376          }
     377        });
     378      }
     379    }
     380
     381    public IEnumerable<DT.Job> GetJobsByProjectIds(IEnumerable<Guid> projectIds) {
     382      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     383      var pm = PersistenceManager;
     384      using (new PerformanceLogger("GetJobsByProjectIds")) {
     385        var currentUserId = UserManager.CurrentUserId;
     386        var projectDao = pm.ProjectDao;
     387        var jobDao = pm.JobDao;
     388        return pm.UseTransaction(() => {
     389          // check for which of requested projectIds the user is granted to administer
     390          bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     391          List<Guid> administrationGrantedProjectIds;
     392          if (isAdmin) {
     393            administrationGrantedProjectIds = projectDao.GetAll().Select(x => x.ProjectId).ToList();
     394          } else {
     395            administrationGrantedProjectIds = projectDao
     396              .GetAdministrationGrantedProjectsForUser(currentUserId)
     397              .Select(x => x.ProjectId)
     398              .ToList();
     399          }
     400          var requestedAndGrantedProjectIds = projectIds.Intersect(administrationGrantedProjectIds);
     401
     402          if (requestedAndGrantedProjectIds.Any()) {
     403            var jobs = jobDao.GetByProjectIds(requestedAndGrantedProjectIds)
     404              .Select(x => x.ToDto())
     405              .ToList();
     406
     407            EvaluateJobs(pm, jobs);
     408            return jobs;
     409          } else {
     410            return Enumerable.Empty<DT.Job>();
     411          }
     412        });
     413      }
     414    }
     415
     416    public Guid AddJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
     417      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     418      var dateCreated = DateTime.Now;
     419      var pm = PersistenceManager;
     420
     421      // check project availability (cf. duration)
     422      CheckProjectAvailability(pm, jobDto.ProjectId, dateCreated);
     423
     424      // check user - project
     425      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
     426
     427      // check project - resources
     428      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
     429
    377430      using (new PerformanceLogger("AddJob")) {
    378431        var jobDao = pm.JobDao;
    379432        var userPriorityDao = pm.UserPriorityDao;
    380         return pm.UseTransaction(() => {
    381           jobDto.OwnerUserId = UserManager.CurrentUserId;
    382           jobDto.DateCreated = DateTime.Now;
    383           var job = jobDao.Save(jobDto.ToEntity());
    384           if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
     433
     434        return pm.UseTransaction(() => {
     435          var newJob = jobDto.ToEntity();
     436          newJob.OwnerUserId = UserManager.CurrentUserId;
     437          newJob.DateCreated = dateCreated;
     438
     439          // add resource assignments
     440          if (resourceIds != null && resourceIds.Any()) {
     441            newJob.AssignedJobResources.AddRange(resourceIds.Select(
     442              x => new DA.AssignedJobResource {
     443                ResourceId = x
     444              }));
     445          }
     446
     447          var job = jobDao.Save(newJob);
     448          if (userPriorityDao.GetById(newJob.OwnerUserId) == null) {
    385449            userPriorityDao.Save(new DA.UserPriority {
    386               UserId = jobDto.OwnerUserId,
    387               DateEnqueued = jobDto.DateCreated
     450              UserId = newJob.OwnerUserId,
     451              DateEnqueued = newJob.DateCreated
    388452            });
    389453          }
     
    394458    }
    395459
    396     public void UpdateJob(DT.Job jobDto) {
     460    public void UpdateJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
    397461      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    398462      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
    399463      var pm = PersistenceManager;
     464      var dateUpdated = DateTime.Now;
     465
     466      // check project availability
     467      CheckProjectAvailability(pm, jobDto.ProjectId, dateUpdated);
     468      // check user - project permission
     469      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
     470      // check project - resources permission
     471      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
     472
    400473      using (new PerformanceLogger("UpdateJob")) {
    401474        bool exists = true;
     
    406479            exists = false;
    407480            job = new DA.Job();
    408           }
     481          } else if (job.State != DA.JobState.Online) {
     482            throw new InvalidOperationException(NO_JOB_UPDATE_POSSIBLE);
     483          }
     484
    409485          jobDto.CopyToEntity(job);
     486
    410487          if (!exists) {
     488            // add resource assignments
     489            if (resourceIds != null && resourceIds.Any()) {
     490              job.AssignedJobResources.AddRange(resourceIds.Select(
     491                x => new DA.AssignedJobResource {
     492                  ResourceId = x
     493                }));
     494            }
    411495            jobDao.Save(job);
    412           }
    413           pm.SubmitChanges();
    414         });
    415       }
    416     }
    417 
    418     public void DeleteJob(Guid jobId) {
    419       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     496          } else if (resourceIds != null) {
     497            var addedJobResourceIds = resourceIds.Except(job.AssignedJobResources.Select(x => x.ResourceId));
     498            var removedJobResourceIds = job.AssignedJobResources
     499              .Select(x => x.ResourceId)
     500              .Except(resourceIds)
     501              .ToArray();
     502
     503            // remove resource assignments
     504            foreach (var rid in removedJobResourceIds) {
     505              var ajr = job.AssignedJobResources.Where(x => x.ResourceId == rid).SingleOrDefault();
     506              if (ajr != null) job.AssignedJobResources.Remove(ajr);
     507            }
     508
     509            // add resource assignments
     510            job.AssignedJobResources.AddRange(addedJobResourceIds.Select(
     511              x => new DA.AssignedJobResource {
     512                ResourceId = x
     513              }));
     514          }
     515          pm.SubmitChanges();
     516        });
     517      }
     518    }
     519
     520    public void UpdateJobState(Guid jobId, DT.JobState jobState) {
     521      if (jobState != JobState.StatisticsPending) return; // only process requests for "StatisticsPending"
     522
     523      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     524      // check if user is an admin, or granted to administer a job-parenting project, or job owner
    420525      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
    421       var pm = PersistenceManager;
    422       using (new PerformanceLogger("DeleteJob")) {
     526
     527      var pm = PersistenceManager;
     528      using (new PerformanceLogger("UpdateJobState")) {
     529        var jobDao = pm.JobDao;       
     530        pm.UseTransaction(() => {
     531          var job = jobDao.GetById(jobId);
     532          if (job != null) {           
     533
     534            // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator           
     535            var jobStateEntity = jobState.ToEntity();
     536            if (job.State == DA.JobState.Online && jobStateEntity == DA.JobState.StatisticsPending) {
     537              job.State = jobStateEntity;
     538              foreach (var task in job.Tasks
     539              .Where(x => x.State == DA.TaskState.Waiting
     540                || x.State == DA.TaskState.Paused
     541                || x.State == DA.TaskState.Offline)) {
     542                task.State = DA.TaskState.Aborted;
     543              }
     544              pm.SubmitChanges();
     545            }
     546          }
     547        });
     548      }
     549    }
     550
     551    public void UpdateJobStates(IEnumerable<Guid> jobIds, DT.JobState jobState) {
     552      if (jobState != JobState.StatisticsPending) return; // only process requests for "StatisticsPending"
     553
     554      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     555      // check if user is an admin, or granted to administer a job-parenting project, or job owner
     556      foreach (var jobId in jobIds)
     557          AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
     558
     559      var pm = PersistenceManager;
     560      using (new PerformanceLogger("UpdateJobStates")) {
    423561        var jobDao = pm.JobDao;
    424         pm.UseTransaction(() => {
    425           // child task will be deleted by db-trigger
    426           jobDao.Delete(jobId);
    427           pm.SubmitChanges();
    428         });
     562        var projectDao = pm.ProjectDao;
     563        pm.UseTransaction(() => {
     564          foreach (var jobId in jobIds) {
     565            var job = jobDao.GetById(jobId);
     566            if (job != null) {
     567
     568              // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
     569              var jobStateEntity = jobState.ToEntity();
     570              if (job.State == DA.JobState.Online && jobStateEntity == DA.JobState.StatisticsPending) {
     571                job.State = jobStateEntity;
     572                foreach (var task in job.Tasks
     573                .Where(x => x.State == DA.TaskState.Waiting
     574                  || x.State == DA.TaskState.Paused
     575                  || x.State == DA.TaskState.Offline)) {
     576                  task.State = DA.TaskState.Aborted;
     577                }
     578                pm.SubmitChanges();
     579              }             
     580            }
     581          }
     582        });
     583      }
     584    }
     585
     586    public IEnumerable<DT.AssignedJobResource> GetAssignedResourcesForJob(Guid jobId) {
     587      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     588      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
     589      var pm = PersistenceManager;
     590      var assignedJobResourceDao = pm.AssignedJobResourceDao;
     591      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     592        return pm.UseTransaction(() =>
     593          assignedJobResourceDao.GetByJobId(jobId)
     594          .Select(x => x.ToDto())
     595          .ToList()
     596        );
    429597      }
    430598    }
     
    532700          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
    533701        }
    534       }
    535       catch (Exception ex) {
     702      } catch (Exception ex) {
    536703        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
    537704      }
     
    604771    #endregion
    605772
    606     #region ResourcePermission Methods
    607     public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
    608       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    609       var pm = PersistenceManager;
    610       using (new PerformanceLogger("GrantResourcePermissions")) {
    611         pm.UseTransaction(() => {
    612           var resource = AuthorizeForResource(pm, resourceId);
    613           var resourcePermissions = resource.ResourcePermissions.ToList();
     773    #region Project Methods
     774    public Guid AddProject(DT.Project projectDto) {
     775      if (projectDto == null || projectDto.Id != Guid.Empty) return Guid.Empty;
     776      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     777      // check if current (non-admin) user is owner of one of projectDto's-parents
     778      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     779      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     780      if (!isAdmin) {
     781        if (projectDto != null && projectDto.ParentProjectId.HasValue) {
     782          AuthorizationManager.AuthorizeForProjectAdministration(projectDto.ParentProjectId.Value, false);
     783        } else {
     784          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     785        }
     786      }
     787
     788      // check that non-admins can not be set as owner of root projects
     789      if (projectDto != null && !projectDto.ParentProjectId.HasValue) {
     790        var owner = UserManager.GetUserById(projectDto.OwnerUserId);
     791        if (owner == null || !RoleVerifier.IsUserInRole(owner.UserName, HiveRoles.Administrator)) {
     792          throw new SecurityException(NOT_AUTHORIZED_PROJECTOWNER);
     793        }
     794      }
     795
     796      var pm = PersistenceManager;
     797      using (new PerformanceLogger("AddProject")) {
     798        var projectDao = pm.ProjectDao;
     799
     800        return pm.UseTransaction(() => {
     801          var project = projectDao.Save(projectDto.ToEntity());
     802
     803          var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     804          bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     805
     806          // if user is no admin, but owner of a parent project
     807          // check start/end date time boundaries of parent projects before updating child project
     808          if (!isAdmin) {
     809            var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     810            if (parentProject != null) {
     811              if (project.StartDate < parentProject.StartDate) project.StartDate = parentProject.StartDate;
     812              if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     813              || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     814                project.EndDate = parentProject.EndDate;
     815            }
     816          }
     817
     818
     819          project.ProjectPermissions.Clear();
     820          project.ProjectPermissions.Add(new DA.ProjectPermission {
     821            GrantedUserId = project.OwnerUserId,
     822            GrantedByUserId = UserManager.CurrentUserId
     823          });
     824
     825          pm.SubmitChanges();
     826          return project.ProjectId;
     827        });
     828      }
     829    }
     830
     831    public void UpdateProject(DT.Project projectDto) {
     832      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     833      // check if current (non-admin) user is owner of the project or the projectDto's-parents
     834      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     835      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     836      if (!isAdmin) {
     837        if (projectDto != null && projectDto.ParentProjectId.HasValue) {
     838          AuthorizationManager.AuthorizeForProjectAdministration(projectDto.Id, false);
     839        } else {
     840          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     841        }
     842      }
     843
     844      // check that non-admins can not be set as owner of root projects
     845      if (projectDto != null && !projectDto.ParentProjectId.HasValue) {
     846        var owner = UserManager.GetUserById(projectDto.OwnerUserId);
     847        if (owner == null || !RoleVerifier.IsUserInRole(owner.UserName, HiveRoles.Administrator)) {
     848          throw new SecurityException(NOT_AUTHORIZED_PROJECTOWNER);
     849        }
     850      }
     851
     852      var pm = PersistenceManager;
     853      using (new PerformanceLogger("UpdateProject")) {
     854        var projectDao = pm.ProjectDao;
     855        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     856        pm.UseTransaction(() => {
     857          var project = projectDao.GetById(projectDto.Id);
     858          if (project != null) { // (1) update existent project
     859            var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     860            bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     861
     862            var formerOwnerId = project.OwnerUserId;
     863            var formerStartDate = project.StartDate;
     864            var formerEndDate = project.EndDate;
     865            projectDto.CopyToEntity(project);
     866
     867            // if user is no admin, but owner of parent project(s)
     868            // check start/end date time boundaries of parent projects before updating child project
     869            if (!isAdmin && isParent) {
     870              var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     871              if (parentProject != null) {
     872                if (project.StartDate < parentProject.StartDate) project.StartDate = formerStartDate;
     873                if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     874                || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     875                  project.EndDate = formerEndDate;
     876              }
     877            }
     878
     879            // if user is admin or owner of parent project(s)
     880            if (isAdmin || isParent) {
     881              // if owner has changed...
     882              if (formerOwnerId != projectDto.OwnerUserId) {
     883                // Add permission for new owner if not already done
     884                if (!project.ProjectPermissions
     885                  .Select(pp => pp.GrantedUserId)
     886                  .Contains(projectDto.OwnerUserId)) {
     887                  project.ProjectPermissions.Add(new DA.ProjectPermission {
     888                    GrantedUserId = projectDto.OwnerUserId,
     889                    GrantedByUserId = UserManager.CurrentUserId
     890                  });
     891                }
     892              }
     893            } else { // if user is only owner of current project, but no admin and no owner of parent project(s)
     894              project.OwnerUserId = formerOwnerId;
     895              project.StartDate = formerStartDate;
     896              project.EndDate = formerEndDate;
     897            }
     898
     899          } else { // (2) save new project
     900            var newProject = projectDao.Save(projectDto.ToEntity());
     901
     902            var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     903            bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     904
     905            // if user is no admin, but owner of a parent project
     906            // check start/end date time boundaries of parent projects before updating child project
     907            if (!isAdmin) {
     908              var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     909              if (parentProject != null) {
     910                if (project.StartDate < parentProject.StartDate) project.StartDate = parentProject.StartDate;
     911                if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     912                || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     913                  project.EndDate = parentProject.EndDate;
     914              }
     915            }
     916
     917            newProject.ProjectPermissions.Clear();
     918            newProject.ProjectPermissions.Add(new DA.ProjectPermission {
     919              GrantedUserId = projectDto.OwnerUserId,
     920              GrantedByUserId = UserManager.CurrentUserId
     921            });
     922          }
     923
     924          pm.SubmitChanges();
     925        });
     926      }
     927    }
     928
     929    public void DeleteProject(Guid projectId) {
     930      if (projectId == Guid.Empty) return;
     931      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     932      // check if current (non-admin) user is owner of one of the projectDto's-parents
     933      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     934      if (!RoleVerifier.IsInRole(HiveRoles.Administrator)) {
     935        AuthorizationManager.AuthorizeForProjectAdministration(projectId, true);
     936      }
     937
     938      var pm = PersistenceManager;
     939      using (new PerformanceLogger("DeleteProject")) {
     940        var projectDao = pm.ProjectDao;
     941        var jobDao = pm.JobDao;
     942        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     943        pm.UseTransaction(() => {
     944          var projectIds = new HashSet<Guid> { projectId };
     945          projectIds.Union(projectDao.GetChildProjectIdsById(projectId));
     946
     947          var jobs = jobDao.GetByProjectIds(projectIds)
     948            .Select(x => x.ToDto())
     949            .ToList();
     950
     951          if (jobs.Count > 0) {
     952            throw new InvalidOperationException("There are " + jobs.Count + " job(s) using this project and/or child-projects. It is necessary to delete them before the project.");
     953          } else {
     954            assignedJobResourceDao.DeleteByProjectIds(projectIds);
     955            projectDao.DeleteByIds(projectIds);
     956            pm.SubmitChanges();
     957          }
     958        });
     959      }
     960    }
     961
     962    // query granted project for use (i.e. to calculate on)
     963    public DT.Project GetProject(Guid projectId) {
     964      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     965      var pm = PersistenceManager;
     966      using (new PerformanceLogger("GetProject")) {
     967        var projectDao = pm.ProjectDao;
     968        var currentUserId = UserManager.CurrentUserId;
     969        var userAndGroupIds = new List<Guid> { currentUserId };
     970        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     971        return pm.UseTransaction(() => {
     972          return projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     973          .Where(x => x.ProjectId == projectId)
     974          .Select(x => x.ToDto())
     975          .SingleOrDefault();
     976        });
     977      }
     978    }
     979
     980    // query granted projects for use (i.e. to calculate on)
     981    public IEnumerable<DT.Project> GetProjects() {
     982      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     983      var pm = PersistenceManager;
     984      using (new PerformanceLogger("GetProjects")) {
     985        var projectDao = pm.ProjectDao;
     986        var currentUserId = UserManager.CurrentUserId;
     987        var userAndGroupIds = new List<Guid> { currentUserId };
     988        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     989        return pm.UseTransaction(() => {
     990          var projects = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     991            .Select(x => x.ToDto()).ToList();
     992          var now = DateTime.Now;
     993          return projects.Where(x => x.StartDate <= now && (x.EndDate == null || x.EndDate >= now)).ToList();
     994        });
     995      }
     996    }
     997
     998    public IEnumerable<DT.Project> GetProjectsForAdministration() {
     999      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1000      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1001      var pm = PersistenceManager;
     1002      using (new PerformanceLogger("GetProjectsForAdministration")) {
     1003        var projectDao = pm.ProjectDao;
     1004
     1005        return pm.UseTransaction(() => {
     1006          if (isAdministrator) {
     1007            return projectDao.GetAll().Select(x => x.ToDto()).ToList();
     1008          } else {
     1009            var currentUserId = UserManager.CurrentUserId;
     1010            return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId)
     1011              .Select(x => x.ToDto()).ToList();
     1012
     1013          }
     1014        });
     1015      }
     1016    }
     1017
     1018    public IDictionary<Guid, HashSet<Guid>> GetProjectGenealogy() {
     1019      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1020      var pm = PersistenceManager;
     1021      using (new PerformanceLogger("GetProjectGenealogy")) {
     1022        var projectDao = pm.ProjectDao;
     1023        var projectAncestors = new Dictionary<Guid, HashSet<Guid>>();
     1024        return pm.UseTransaction(() => {
     1025          var projects = projectDao.GetAll().ToList();
     1026          projects.ForEach(p => projectAncestors.Add(p.ProjectId, new HashSet<Guid>()));
     1027          foreach (var p in projects) {
     1028            var parentProject = p.ParentProject;
     1029            while (parentProject != null) {
     1030              projectAncestors[p.ProjectId].Add(parentProject.ProjectId);
     1031              parentProject = parentProject.ParentProject;
     1032            }
     1033          }
     1034          return projectAncestors;
     1035        });
     1036      }
     1037    }
     1038
     1039    public IDictionary<Guid, string> GetProjectNames() {
     1040      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1041      var pm = PersistenceManager;
     1042      using (new PerformanceLogger("GetProjectNames")) {
     1043        var projectDao = pm.ProjectDao;
     1044        var projectNames = new Dictionary<Guid, string>();
     1045        return pm.UseTransaction(() => {
     1046          projectDao
     1047            .GetAll().ToList()
     1048            .ForEach(p => projectNames.Add(p.ProjectId, p.Name));
     1049          return projectNames;
     1050        });
     1051      }
     1052    }
     1053    #endregion
     1054
     1055    #region ProjectPermission Methods
     1056    public void SaveProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool reassign, bool cascading, bool reassignCascading) {
     1057      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1058      if (projectId == null || grantedUserIds == null) return;
     1059      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1060      var pm = PersistenceManager;
     1061      using (new PerformanceLogger("SaveProjectPermissions")) {
     1062        var projectDao = pm.ProjectDao;
     1063        var projectPermissionDao = pm.ProjectPermissionDao;
     1064        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1065
     1066        pm.UseTransaction(() => {
     1067          var project = projectDao.GetById(projectId);
     1068          if (project == null) return;
     1069          var projectPermissions = project.ProjectPermissions.Select(x => x.GrantedUserId).ToArray();
     1070
     1071          // guarantee that project owner is always permitted
     1072          if (!grantedUserIds.Contains(project.OwnerUserId)) {
     1073            grantedUserIds.Add(project.OwnerUserId);
     1074          }
     1075
     1076          //var addedPermissions = grantedUserIds.Except(projectPermissions);
     1077          var removedPermissions = projectPermissions.Except(grantedUserIds);
     1078
     1079          // remove job assignments and project permissions
     1080          if (reassign) {
     1081            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
     1082            project.ProjectPermissions.Clear();
     1083          } else {
     1084
     1085            var ugt = GetUserGroupTree();
     1086            var permittedGuids = new HashSet<Guid>(); // User- and Group-Guids
     1087            var notpermittedGuids = new HashSet<Guid>();
     1088
     1089            // remove job assignments:
     1090            // (1) get all member-Guids of all still or fresh permitted user/groups
     1091            foreach (var item in grantedUserIds) {
     1092              permittedGuids.Add(item);
     1093              if (ugt.ContainsKey(item)) {
     1094                ugt[item].ToList().ForEach(x => permittedGuids.Add(x));
     1095              }
     1096            }
     1097
     1098            // (2) get all member-Guids of users and groups in removedPermissions
     1099            foreach (var item in removedPermissions) {
     1100              notpermittedGuids.Add(item);
     1101              if (ugt.ContainsKey(item)) {
     1102                ugt[item].ToList().ForEach(x => notpermittedGuids.Add(x));
     1103              }
     1104            }
     1105
     1106            // (3) get all Guids which are in removedPermissions but not in grantedUserIds
     1107            var definitelyNotPermittedGuids = notpermittedGuids.Except(permittedGuids);
     1108
     1109            // (4) delete jobs of those
     1110            assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, definitelyNotPermittedGuids);
     1111
     1112
     1113            // remove project permissions
     1114            foreach (var item in project.ProjectPermissions
     1115              .Where(x => removedPermissions.Contains(x.GrantedUserId))
     1116              .ToList()) {
     1117              project.ProjectPermissions.Remove(item);
     1118            }
     1119          }
     1120          pm.SubmitChanges();
     1121
     1122          // add project permissions
    6141123          foreach (var id in grantedUserIds) {
    615             if (resourcePermissions.All(x => x.GrantedUserId != id)) {
    616               resource.ResourcePermissions.Add(new DA.ResourcePermission {
     1124            if (project.ProjectPermissions.All(x => x.GrantedUserId != id)) {
     1125              project.ProjectPermissions.Add(new DA.ProjectPermission {
    6171126                GrantedUserId = id,
    6181127                GrantedByUserId = UserManager.CurrentUserId
     
    6211130          }
    6221131          pm.SubmitChanges();
    623         });
    624       }
    625     }
    626 
    627     public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
    628       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    629       var pm = PersistenceManager;
    630       using (new PerformanceLogger("RevokeResourcePermissions")) {
    631         var resourcePermissionDao = pm.ResourcePermissionDao;
    632         pm.UseTransaction(() => {
    633           AuthorizeForResource(pm, resourceId);
    634           resourcePermissionDao.DeleteByResourceAndGrantedUserId(resourceId, grantedUserIds);
    635           pm.SubmitChanges();
    636         });
    637       }
    638     }
    639 
    640     public IEnumerable<DT.ResourcePermission> GetResourcePermissions(Guid resourceId) {
    641       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    642       var pm = PersistenceManager;
    643       using (new PerformanceLogger("GetResourcePermissions")) {
    644         var resourcePermissionDao = pm.ResourcePermissionDao;
    645         return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
     1132
     1133          if (cascading) {
     1134            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
     1135            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
     1136
     1137            // remove job assignments
     1138            if (reassignCascading) {
     1139              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
     1140            } else {
     1141              assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, removedPermissions);
     1142            }
     1143
     1144            foreach (var p in childProjects) {
     1145              var cpAssignedPermissions = p.ProjectPermissions.Select(x => x.GrantedUserId).ToList();
     1146              // guarantee that project owner is always permitted
     1147              if (!cpAssignedPermissions.Contains(p.OwnerUserId)) {
     1148                cpAssignedPermissions.Add(p.OwnerUserId);
     1149              }
     1150              var cpRemovedPermissions = cpAssignedPermissions.Where(x => x != p.OwnerUserId).Except(grantedUserIds);
     1151
     1152              // remove left-over job assignments (for non-reassignments)
     1153              if (!reassignCascading) {
     1154                assignedJobResourceDao.DeleteByProjectIdAndUserIds(p.ProjectId, cpRemovedPermissions);
     1155              }
     1156
     1157              // remove project permissions
     1158              if (reassignCascading) {
     1159                p.ProjectPermissions.Clear();
     1160              } else {
     1161                foreach (var item in p.ProjectPermissions
     1162                  .Where(x => x.GrantedUserId != p.OwnerUserId
     1163                    && (removedPermissions.Contains(x.GrantedUserId) || cpRemovedPermissions.Contains(x.GrantedUserId)))
     1164                  .ToList()) {
     1165                  p.ProjectPermissions.Remove(item);
     1166                }
     1167              }
     1168              pm.SubmitChanges();
     1169
     1170              // add project permissions
     1171              var cpGrantedUserIds = new HashSet<Guid>(grantedUserIds);
     1172              cpGrantedUserIds.Add(p.OwnerUserId);
     1173
     1174              foreach (var id in cpGrantedUserIds) {
     1175                if (p.ProjectPermissions.All(x => x.GrantedUserId != id)) {
     1176                  p.ProjectPermissions.Add(new DA.ProjectPermission {
     1177                    GrantedUserId = id,
     1178                    GrantedByUserId = UserManager.CurrentUserId
     1179                  });
     1180                }
     1181              }
     1182            }
     1183          }
     1184          pm.SubmitChanges();
     1185        });
     1186      }
     1187    }
     1188
     1189    //private void GrantProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
     1190    //  throw new NotImplementedException();
     1191    //}
     1192
     1193    //private void RevokeProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
     1194    //  RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1195    //  if (projectId == null || grantedUserIds == null || !grantedUserIds.Any()) return;
     1196    //  AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1197    //  var pm = PersistenceManager;
     1198    //  using (new PerformanceLogger("RevokeProjectPermissions")) {
     1199    //    var projectPermissionDao = pm.ProjectPermissionDao;
     1200    //    var projectDao = pm.ProjectDao;
     1201    //    var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1202    //    pm.UseTransaction(() => {
     1203    //      if (cascading) {
     1204    //        var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
     1205    //        projectPermissionDao.DeleteByProjectIdsAndGrantedUserIds(childProjectIds, grantedUserIds);
     1206    //        assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, grantedUserIds);
     1207    //      }
     1208    //      projectPermissionDao.DeleteByProjectIdAndGrantedUserIds(projectId, grantedUserIds);
     1209    //      assignedJobResourceDao.DeleteByProjectIdAndUserIds(projectId, grantedUserIds);
     1210    //      pm.SubmitChanges();
     1211    //    });
     1212    //  }
     1213    //}
     1214
     1215    public IEnumerable<DT.ProjectPermission> GetProjectPermissions(Guid projectId) {
     1216      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1217      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1218      var pm = PersistenceManager;
     1219      using (new PerformanceLogger("GetProjectPermissions")) {
     1220        var projectPermissionDao = pm.ProjectPermissionDao;
     1221        return pm.UseTransaction(() => projectPermissionDao.GetByProjectId(projectId)
    6461222          .Select(x => x.ToDto())
    6471223          .ToList()
     
    6511227    #endregion
    6521228
     1229    #region AssignedProjectResource Methods
     1230    // basic: remove and add assignments (resourceIds) to projectId and its depending jobs
     1231    // reassign: clear all assignments from project and its depending jobs, before adding new ones (resourceIds)
     1232    // cascading: "basic" mode for child-projects
     1233    // reassignCascading: "reassign" mode for child-projects
     1234    public void SaveProjectResourceAssignments(Guid projectId, List<Guid> resourceIds, bool reassign, bool cascading, bool reassignCascading) {
     1235      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1236      if (projectId == null || resourceIds == null) return;
     1237      AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
     1238      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1239      var pm = PersistenceManager;
     1240      using (new PerformanceLogger("SaveProjectResourceAssignments")) {
     1241        var projectDao = pm.ProjectDao;
     1242        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1243        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1244        pm.UseTransaction(() => {
     1245          var project = projectDao.GetById(projectId);
     1246
     1247          var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     1248          bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     1249
     1250          var assignedResources = project.AssignedProjectResources.Select(x => x.ResourceId).ToArray();
     1251          if (!isParent && !isAdmin) resourceIds = assignedResources.ToList();
     1252          var removedAssignments = assignedResources.Except(resourceIds);
     1253
     1254          // if user is admin or owner of parent project(s)
     1255          if (isAdmin || isParent) {
     1256            // remove job and project assignments
     1257            if (reassign) {
     1258              assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
     1259              project.AssignedProjectResources.Clear();
     1260            } else {
     1261              assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, removedAssignments);
     1262              foreach (var item in project.AssignedProjectResources
     1263                .Where(x => removedAssignments.Contains(x.ResourceId))
     1264                .ToList()) {
     1265                project.AssignedProjectResources.Remove(item);
     1266              }
     1267            }
     1268            pm.SubmitChanges();
     1269
     1270            // add project assignments
     1271            foreach (var id in resourceIds) {
     1272              if (project.AssignedProjectResources.All(x => x.ResourceId != id)) {
     1273                project.AssignedProjectResources.Add(new DA.AssignedProjectResource {
     1274                  ResourceId = id
     1275                });
     1276              }
     1277            }
     1278            pm.SubmitChanges();
     1279          }
     1280
     1281          // if user is admin, project owner or owner of parent projects
     1282          if (cascading) {
     1283            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
     1284            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
     1285
     1286            // remove job assignments
     1287            if (reassignCascading) {
     1288              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
     1289            } else {
     1290              assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, removedAssignments);
     1291            }
     1292            foreach (var p in childProjects) {
     1293              var cpAssignedResources = p.AssignedProjectResources.Select(x => x.ResourceId).ToArray();
     1294              var cpRemovedAssignments = cpAssignedResources.Except(resourceIds);
     1295
     1296              // remove left-over job assignments (for non-reassignments)
     1297              if (!reassignCascading) {
     1298                assignedJobResourceDao.DeleteByProjectIdAndResourceIds(p.ProjectId, cpRemovedAssignments);
     1299              }
     1300
     1301              // remove project assignments
     1302              if (reassignCascading) {
     1303                p.AssignedProjectResources.Clear();
     1304              } else {
     1305                foreach (var item in p.AssignedProjectResources
     1306                  .Where(x => removedAssignments.Contains(x.ResourceId) || cpRemovedAssignments.Contains(x.ResourceId))
     1307                  .ToList()) {
     1308                  p.AssignedProjectResources.Remove(item);
     1309                }
     1310              }
     1311              pm.SubmitChanges();
     1312
     1313              // add project assignments
     1314              foreach (var id in resourceIds) {
     1315                if (p.AssignedProjectResources.All(x => x.ResourceId != id)) {
     1316                  p.AssignedProjectResources.Add(new DA.AssignedProjectResource {
     1317                    ResourceId = id
     1318                  });
     1319                }
     1320              }
     1321            }
     1322          }
     1323          pm.SubmitChanges();
     1324        });
     1325      }
     1326    }
     1327
     1328    //private void AssignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
     1329    //  throw new NotImplementedException();
     1330    //}
     1331
     1332    //private void UnassignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
     1333    //  RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1334    //  if (projectId == null || resourceIds == null || !resourceIds.Any()) return;
     1335    //  AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
     1336    //  var pm = PersistenceManager;
     1337    //  using (new PerformanceLogger("UnassignProjectResources")) {
     1338    //    var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1339    //    var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1340    //    var projectDao = pm.ProjectDao;
     1341    //    pm.UseTransaction(() => {
     1342    //      if (cascading) {
     1343    //        var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
     1344    //        assignedProjectResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
     1345    //        assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
     1346    //      }
     1347    //      assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
     1348    //      assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
     1349    //      pm.SubmitChanges();
     1350    //    });
     1351    //  }
     1352    //}
     1353
     1354    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProject(Guid projectId) {
     1355      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1356      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, projectId);
     1357      var pm = PersistenceManager;
     1358      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1359        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1360        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
     1361          .Select(x => x.ToDto())
     1362          .ToList()
     1363        );
     1364      }
     1365    }
     1366
     1367    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectAdministration(Guid projectId) {
     1368      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1369      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1370      var pm = PersistenceManager;
     1371      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1372        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1373        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
     1374          .Select(x => x.ToDto())
     1375          .ToList()
     1376        );
     1377      }
     1378    }
     1379
     1380    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectsAdministration(IEnumerable<Guid> projectIds) {
     1381      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1382      foreach (var id in projectIds)
     1383        AuthorizationManager.AuthorizeForProjectAdministration(id, false);
     1384
     1385      var pm = PersistenceManager;
     1386      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1387        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1388        var assignments = new List<DT.AssignedProjectResource>();
     1389        pm.UseTransaction(() => {
     1390          foreach (var id in projectIds) {
     1391            assignments.AddRange(assignedProjectResourceDao.GetByProjectId(id)
     1392              .Select(x => x.ToDto()));
     1393          }
     1394        });
     1395        return assignments.Distinct();
     1396      }
     1397    }
     1398
     1399    #endregion
     1400
    6531401    #region Slave Methods
    6541402    public Guid AddSlave(DT.Slave slaveDto) {
     
    6661414
    6671415    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
    668       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1416      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
    6691417      var pm = PersistenceManager;
    6701418      using (new PerformanceLogger("AddSlaveGroup")) {
     
    6901438    }
    6911439
     1440    // query granted slaves for use (i.e. to calculate on)
    6921441    public IEnumerable<DT.Slave> GetSlaves() {
    6931442      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    694       bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
    6951443      var pm = PersistenceManager;
    6961444      using (new PerformanceLogger("GetSlaves")) {
    6971445        var slaveDao = pm.SlaveDao;
    698         var resourcePermissionDao = pm.ResourcePermissionDao;
     1446        var projectDao = pm.ProjectDao;
     1447        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1448
     1449        // collect user information
    6991450        var currentUserId = UserManager.CurrentUserId;
    700         return pm.UseTransaction(() => {
    701           var resourcePermissions = resourcePermissionDao.GetAll();
    702           return slaveDao.GetAll().ToList()
    703             .Where(x => isAdministrator
    704               || x.OwnerUserId == null
    705               || x.OwnerUserId == currentUserId
    706               || UserManager.VerifyUser(currentUserId, resourcePermissions
    707                   .Where(y => y.ResourceId == x.ResourceId)
    708                   .Select(z => z.GrantedUserId)
    709                   .ToList())
    710               )
     1451        var userAndGroupIds = new List<Guid> { currentUserId };
     1452        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     1453
     1454        return pm.UseTransaction(() => {
     1455          var slaves = slaveDao.GetAll()
    7111456            .Select(x => x.ToDto())
    7121457            .ToList();
    713         });
    714       }
    715     }
    716 
     1458          var grantedProjectIds = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     1459            .Select(x => x.ProjectId)
     1460            .ToList();
     1461          var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourcesByProjectIds(grantedProjectIds)
     1462            .Select(x => x.ResourceId)
     1463            .ToList();
     1464
     1465          return slaves
     1466            .Where(x => grantedResourceIds.Contains(x.Id))
     1467            .ToList();
     1468        });
     1469      }
     1470    }
     1471
     1472    // query granted slave groups for use (i.e. to calculate on)
    7171473    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
    7181474      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    719       bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
    7201475      var pm = PersistenceManager;
    7211476      using (new PerformanceLogger("GetSlaveGroups")) {
    7221477        var slaveGroupDao = pm.SlaveGroupDao;
    723         var resourcePermissionDao = pm.ResourcePermissionDao;
     1478        var projectDao = pm.ProjectDao;
     1479        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1480
     1481        // collect user information
    7241482        var currentUserId = UserManager.CurrentUserId;
    725         return pm.UseTransaction(() => {
    726           var resourcePermissions = resourcePermissionDao.GetAll();
    727           return slaveGroupDao.GetAll().ToList()
    728             .Where(x => isAdministrator
    729               || x.OwnerUserId == null
    730               || x.OwnerUserId == currentUserId
    731               || UserManager.VerifyUser(currentUserId, resourcePermissions
    732                   .Where(y => y.ResourceId == x.ResourceId)
    733                   .Select(z => z.GrantedUserId)
    734                   .ToList())
    735               )
     1483        var userAndGroupIds = new List<Guid> { currentUserId };
     1484        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     1485
     1486        return pm.UseTransaction(() => {
     1487          var slaveGroups = slaveGroupDao.GetAll()
    7361488            .Select(x => x.ToDto())
    7371489            .ToList();
     1490          var grantedProjectIds = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     1491            .Select(x => x.ProjectId)
     1492            .ToList();
     1493          var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourcesByProjectIds(grantedProjectIds)
     1494            .Select(x => x.ResourceId)
     1495            .ToList();
     1496
     1497          return slaveGroups
     1498            .Where(x => grantedResourceIds.Contains(x.Id))
     1499            .ToList();
     1500        });
     1501      }
     1502    }
     1503
     1504    // query granted slaves for resource administration
     1505    public IEnumerable<DT.Slave> GetSlavesForAdministration() {
     1506      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1507      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1508      var pm = PersistenceManager;
     1509      using (new PerformanceLogger("GetSlavesForAdministration")) {
     1510        var slaveDao = pm.SlaveDao;
     1511        var currentUserId = UserManager.CurrentUserId;
     1512
     1513        if (isAdministrator) {
     1514          return pm.UseTransaction(() => {
     1515            return slaveDao.GetAll()
     1516              .Select(x => x.ToDto())
     1517              .ToList();
     1518          });
     1519        } else {
     1520          var slaves = slaveDao.GetAll()
     1521            .Select(x => x.ToDto())
     1522            .ToList();
     1523          var projectDao = pm.ProjectDao;
     1524          var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1525          var projects = projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).ToList();
     1526          var resourceIds = assignedProjectResourceDao
     1527            .GetAllGrantedResourcesByProjectIds(projects.Select(x => x.ProjectId).ToList())
     1528            .Select(x => x.ResourceId)
     1529            .ToList();
     1530
     1531          return slaves
     1532            .Where(x => resourceIds.Contains(x.Id))
     1533            .ToList();
     1534        }
     1535      }
     1536    }
     1537
     1538    // query granted slave groups for resource administration
     1539    public IEnumerable<DT.SlaveGroup> GetSlaveGroupsForAdministration() {
     1540      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1541      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1542      var pm = PersistenceManager;
     1543      using (new PerformanceLogger("GetSlaveGroupsForAdministration")) {
     1544        var slaveGroupDao = pm.SlaveGroupDao;
     1545        var currentUserId = UserManager.CurrentUserId;
     1546
     1547        if (isAdministrator) {
     1548          return pm.UseTransaction(() => {
     1549            return slaveGroupDao.GetAll()
     1550              .Select(x => x.ToDto())
     1551              .ToList();
     1552          });
     1553        } else {
     1554          var slaveGroups = slaveGroupDao.GetAll()
     1555            .Select(x => x.ToDto())
     1556            .ToList();
     1557          var projectDao = pm.ProjectDao;
     1558          var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1559          var projects = projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).ToList();
     1560          var resourceIds = assignedProjectResourceDao
     1561            .GetAllGrantedResourcesByProjectIds(projects.Select(x => x.ProjectId).ToList())
     1562            .Select(x => x.ResourceId)
     1563            .ToList();
     1564
     1565          return slaveGroups
     1566            .Where(x => resourceIds.Contains(x.Id))
     1567            .ToList();
     1568        }
     1569      }
     1570    }
     1571
     1572    public IDictionary<Guid, HashSet<Guid>> GetResourceGenealogy() {
     1573      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1574      var pm = PersistenceManager;
     1575      using (new PerformanceLogger("GetResourceGenealogy")) {
     1576        var resourceDao = pm.ResourceDao;
     1577        var resourceAncestors = new Dictionary<Guid, HashSet<Guid>>();
     1578        return pm.UseTransaction(() => {
     1579          var resources = resourceDao.GetAll().ToList();
     1580          resources.ForEach(r => resourceAncestors.Add(r.ResourceId, new HashSet<Guid>()));
     1581
     1582          foreach (var r in resources) {
     1583            var parentResource = r.ParentResource;
     1584            while (parentResource != null) {
     1585              resourceAncestors[r.ResourceId].Add(parentResource.ResourceId);
     1586              parentResource = parentResource.ParentResource;
     1587            }
     1588          }
     1589          return resourceAncestors;
     1590        });
     1591      }
     1592    }
     1593
     1594    public IDictionary<Guid, string> GetResourceNames() {
     1595      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1596      var pm = PersistenceManager;
     1597      using (new PerformanceLogger("GetResourceNames")) {
     1598        var resourceDao = pm.ResourceDao;
     1599        var resourceNames = new Dictionary<Guid, string>();
     1600        return pm.UseTransaction(() => {
     1601          resourceDao
     1602            .GetAll().ToList()
     1603            .ForEach(p => resourceNames.Add(p.ResourceId, p.Name));
     1604          return resourceNames;
    7381605        });
    7391606      }
     
    7421609    public void UpdateSlave(DT.Slave slaveDto) {
    7431610      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1611      if (slaveDto == null) return;
     1612      AuthorizationManager.AuthorizeForResourceAdministration(slaveDto.Id);
    7441613      var pm = PersistenceManager;
    7451614      using (new PerformanceLogger("UpdateSlave")) {
     
    7591628    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
    7601629      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1630      if (slaveGroupDto == null) return;
     1631      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupDto.Id);
    7611632      var pm = PersistenceManager;
    7621633      using (new PerformanceLogger("UpdateSlaveGroup")) {
     
    7751646
    7761647    public void DeleteSlave(Guid slaveId) {
     1648      if (slaveId == Guid.Empty) return;
    7771649      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    7781650      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
     
    7881660
    7891661    public void DeleteSlaveGroup(Guid slaveGroupId) {
     1662      if (slaveGroupId == Guid.Empty) return;
    7901663      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    7911664      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
    7921665      var pm = PersistenceManager;
    7931666      using (new PerformanceLogger("DeleteSlaveGroup")) {
    794         var slaveGroupDao = pm.SlaveGroupDao;
    795         pm.UseTransaction(() => {
    796           slaveGroupDao.Delete(slaveGroupId);
     1667        var resourceDao = pm.ResourceDao;
     1668        pm.UseTransaction(() => {
     1669          var resourceIds = new HashSet<Guid> { slaveGroupId };
     1670          resourceIds.Union(resourceDao.GetChildResourceIdsById(slaveGroupId));
     1671          resourceDao.DeleteByIds(resourceIds);
    7971672          pm.SubmitChanges();
    7981673        });
     
    9461821      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
    9471822      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
     1823    }
     1824
     1825    public Dictionary<Guid, HashSet<Guid>> GetUserGroupTree() {
     1826      var userGroupTree = new Dictionary<Guid, HashSet<Guid>>();
     1827      var userGroupMapping = UserManager.GetUserGroupMapping();
     1828
     1829      foreach (var ugm in userGroupMapping) {
     1830        if (ugm.Parent == null || ugm.Child == null) continue;
     1831
     1832        if (!userGroupTree.ContainsKey(ugm.Parent)) {
     1833          userGroupTree.Add(ugm.Parent, new HashSet<Guid>());
     1834        }
     1835        userGroupTree[ugm.Parent].Add(ugm.Child);
     1836      }
     1837
     1838      return userGroupTree;
     1839    }
     1840
     1841    public bool CheckAccessToAdminAreaGranted() {
     1842      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1843      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1844      var pm = PersistenceManager;
     1845      using (new PerformanceLogger("CheckAccessToAdminAreaGranted")) {
     1846        if (isAdministrator) {
     1847          return true;
     1848        } else {
     1849          var projectDao = pm.ProjectDao;
     1850          var currentUserId = UserManager.CurrentUserId;
     1851          return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).Any();
     1852        }
     1853      }
    9481854    }
    9491855    #endregion
     
    9901896    }
    9911897
    992     private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
    993       var resourceDao = pm.ResourceDao;
    994       var resource = resourceDao.GetById(resourceId);
    995       if (resource == null) throw new SecurityException("Not authorized");
    996       if (resource.OwnerUserId != UserManager.CurrentUserId
    997           && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
    998         throw new SecurityException("Not authorized");
    999       }
    1000       return resource;
     1898    private void CheckProjectAvailability(IPersistenceManager pm, Guid projectId, DateTime date) {
     1899      var projectDao = pm.ProjectDao;
     1900      using (new PerformanceLogger("UpdateJob")) {
     1901        var project = pm.UseTransaction(() => {
     1902          return projectDao.GetById(projectId);
     1903        });
     1904        if (project != null) {
     1905          if (project.StartDate > date) throw new ArgumentException("Cannot add job to specified project. The start date of the project is still in the future.");
     1906          else if (project.EndDate != null && project.EndDate < date) throw new ArgumentException("Cannot add job to specified project. The end date of the project is already reached.");
     1907        } else {
     1908          throw new ArgumentException("Cannot add job to specified project. The project seems not to be available anymore.");
     1909        }
     1910      }
     1911    }
     1912
     1913    private void EvaluateJobs(IPersistenceManager pm, IEnumerable<DT.Job> jobs) {
     1914      if (jobs == null || !jobs.Any()) return;
     1915
     1916      var currentUserId = UserManager.CurrentUserId;
     1917      var taskDao = pm.TaskDao;
     1918      var jobPermissionDao = pm.JobPermissionDao;
     1919
     1920      var statistics = taskDao.GetAll()
     1921        .Where(x => jobs.Select(y => y.Id).Contains(x.JobId))
     1922        .GroupBy(x => x.JobId)
     1923        .Select(x => new {
     1924          x.Key,
     1925          TotalCount = x.Count(),
     1926          CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
     1927          FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
     1928        })
     1929        .ToList();
     1930
     1931      foreach (var job in jobs) {
     1932        var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
     1933        if (statistic != null) {
     1934          job.JobCount = statistic.TotalCount;
     1935          job.CalculatingCount = statistic.CalculatingCount;
     1936          job.FinishedCount = statistic.FinishedCount;
     1937        }
     1938
     1939        job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
     1940
     1941        if (currentUserId == job.OwnerUserId) {
     1942          job.Permission = Permission.Full;
     1943        } else {
     1944          var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
     1945          job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
     1946        }
     1947      }
    10011948    }
    10021949    #endregion
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/HiveStatisticsGenerator.cs

    r15583 r16240  
    3737    public void GenerateStatistics() {
    3838      using (var pm = new PersistenceManager()) {
     39
     40        pm.UseTransaction(() => {
     41          UpdateDimProjectTable(pm);
     42          pm.SubmitChanges();
     43        });
     44
    3945        pm.UseTransaction(() => {
    4046          UpdateDimUserTable(pm);
     47         
    4148          UpdateDimJobTable(pm);
    4249          UpdateDimClientsTable(pm);
     
    5461            UpdateFactClientInfoTable(time, pm);
    5562            pm.SubmitChanges();
     63            UpdateFactProjectInfoTable(time, pm);
     64            pm.SubmitChanges();
    5665          });
    5766
    5867          pm.UseTransaction(() => {
    59             UpdateTaskFactsTable(pm);
     68            UpdateFactTaskTable(pm);
    6069            try {
    6170              pm.SubmitChanges();
     
    7281          });
    7382        }
     83
     84        pm.UseTransaction(() => {
     85          FlagJobsForDeletion(pm);
     86          pm.SubmitChanges();
     87        });
    7488      }
    7589    }
     
    106120    }
    107121
     122    // add new projects
     123    // delete expired projects
     124    // update information of existing projects
     125    private void UpdateDimProjectTable(PersistenceManager pm) {
     126      var projectDao = pm.ProjectDao;
     127      var dimProjectDao = pm.DimProjectDao;
     128
     129      var projects = projectDao.GetAll().ToList();
     130      var dimProjects = dimProjectDao.GetAllOnlineProjects().ToList();
     131
     132      var onlineProjects = dimProjects.Where(x => projects.Select(y => y.ProjectId).Contains(x.ProjectId));
     133      var addedProjects = projects.Where(x => !dimProjects.Select(y => y.ProjectId).Contains(x.ProjectId));
     134      var removedProjects = dimProjects.Where(x => !projects.Select(y => y.ProjectId).Contains(x.ProjectId));
     135
     136      // set expiration time of removed projects
     137      foreach (var p in removedProjects) {
     138        p.DateExpired = DateTime.Now;
     139      }
     140
     141      // add new projects
     142      dimProjectDao.Save(addedProjects.Select(x => new DimProject {
     143        ProjectId = x.ProjectId,
     144        ParentProjectId = x.ParentProjectId,
     145        Name = x.Name,
     146        Description = x.Description,
     147        OwnerUserId = x.OwnerUserId,
     148        StartDate = x.StartDate,
     149        EndDate = x.EndDate,
     150        DateCreated = x.DateCreated,
     151        DateExpired = null
     152      }));
     153
     154      // expire project if its parent has changed and create a new entry
     155      // otherwise perform "normal" update
     156      foreach (var dimP in onlineProjects) {
     157        var p = projects.Where(x => x.ProjectId == dimP.ProjectId).SingleOrDefault();
     158        if (p != null) {
     159          if (dimP.ParentProjectId == null ? p.ParentProjectId != null : dimP.ParentProjectId != p.ParentProjectId) { // or: (!object.Equals(dimP.ParentProjectId, p.ParentProjectId))
     160            dimP.DateExpired = DateTime.Now;
     161            dimProjectDao.Save(new DimProject {
     162              ProjectId = p.ProjectId,
     163              ParentProjectId = p.ParentProjectId,
     164              Name = p.Name,
     165              Description = p.Description,
     166              OwnerUserId = p.OwnerUserId,
     167              StartDate = p.StartDate,
     168              EndDate = p.EndDate,
     169              DateCreated = p.DateCreated,
     170              DateExpired = null
     171            });
     172          } else {
     173            dimP.Name = p.Name;
     174            dimP.Description = p.Description;
     175            dimP.OwnerUserId = p.OwnerUserId;
     176            dimP.StartDate = p.StartDate;
     177            dimP.EndDate = p.EndDate;
     178          }
     179        }
     180      }
     181    }
     182
    108183    private void UpdateDimJobTable(PersistenceManager pm) {
     184      var dimProjectDao = pm.DimProjectDao;
    109185      var dimJobDao = pm.DimJobDao;
    110186      var jobDao = pm.JobDao;
     
    118194          JobName = x.Name ?? string.Empty,
    119195          DateCreated = x.DateCreated,
     196          ProjectId = dimProjectDao.GetLastValidIdByProjectId(x.ProjectId),
    120197          TotalTasks = taskDao.GetAll().Count(y => y.JobId == x.JobId)
    121198        })
     
    127204        UserName = GetUserName(x.UserId),
    128205        DateCreated = x.DateCreated,
     206        ProjectId = x.ProjectId,
    129207        TotalTasks = x.TotalTasks,
    130208        CompletedTasks = 0,
     
    134212
    135213    private void UpdateExistingDimJobs(PersistenceManager pm) {
     214      var dimProjectDao = pm.DimProjectDao;
    136215      var jobDao = pm.JobDao;
    137216      var dimJobDao = pm.DimJobDao;
     
    151230          }
    152231        }
     232        var job = jobDao.GetById(dimJob.JobId);
    153233        if (totalTasks == completedTasks) {
    154234          var completeDate = factTaskDao.GetLastCompletedTaskFromJob(dimJob.JobId);
    155235          if (completeDate == null) {
    156             if (jobDao.GetById(dimJob.JobId) == null) {
     236            if (job == null) {
    157237              completeDate = DateTime.Now;
    158238            }
     
    160240          dimJob.DateCompleted = completeDate;
    161241        }
     242        if(job != null) {
     243          dimJob.JobName = job.Name;
     244          dimJob.ProjectId = dimProjectDao.GetLastValidIdByProjectId(job.ProjectId);
     245        }
     246
    162247        dimJob.TotalTasks = totalTasks;
    163248        dimJob.CompletedTasks = completedTasks;
     
    165250    }
    166251
     252    private void FlagJobsForDeletion(PersistenceManager pm) {
     253      var jobDao = pm.JobDao;
     254      var jobs = jobDao.GetJobsReadyForDeletion();
     255      foreach(var job in jobs) {
     256        job.State = JobState.DeletionPending;
     257      }
     258    }
     259
    167260    private void UpdateDimClientsTable(PersistenceManager pm) {
    168261      var dimClientDao = pm.DimClientDao;
    169       var slaveDao = pm.SlaveDao;
    170       var slaves = slaveDao.GetAll();
    171       var recentlyAddedClients = dimClientDao.GetActiveClients();
    172       var slaveIds = slaves.Select(x => x.ResourceId);
    173 
    174       var removedClientIds = recentlyAddedClients
    175         .Where(x => !slaveIds.Contains(x.ResourceId))
    176         .Select(x => x.Id);
    177       var modifiedClients =
    178         from slave in slaves
    179         join client in recentlyAddedClients on slave.ResourceId equals client.ResourceId
    180         where (slave.Name != client.Name
    181                || slave.ParentResourceId == null && client.ResourceGroupId != null // because both can be null and null comparison
    182                || slave.ParentResourceId != null && client.ResourceGroupId == null // does return no entry on the sql server
    183                || slave.ParentResourceId != client.ResourceGroupId
    184                || ((slave.ParentResource != null) && slave.ParentResource.ParentResourceId != client.ResourceGroup2Id))
    185         select new {
    186           SlaveId = slave.ResourceId,
    187           ClientId = client.Id
    188         };
    189       var clientIds = dimClientDao.GetActiveClients().Select(x => x.ResourceId);
    190       var modifiedClientIds = modifiedClients.Select(x => x.SlaveId);
    191       var newClients = slaves
    192         .Where(x => !clientIds.Contains(x.ResourceId)
    193                     || modifiedClientIds.Contains(x.ResourceId))
    194         .Select(x => new {
    195           x.ResourceId,
    196           x.Name,
    197           ResourceGroupId = x.ParentResourceId,
    198           GroupName = x.ParentResource != null ? x.ParentResource.Name : null,
    199           ResourceGroup2Id = x.ParentResource != null ? x.ParentResource.ParentResourceId : null,
    200           GroupName2 = x.ParentResource != null ? x.ParentResource.ParentResource != null ? x.ParentResource.ParentResource.Name : null : null
    201         })
    202         .ToList();
    203 
    204       var clientsToUpdate = removedClientIds.Union(modifiedClients.Select(x => x.ClientId));
    205       dimClientDao.UpdateExpirationTime(clientsToUpdate, DateTime.Now);
    206       dimClientDao.Save(newClients.Select(x => new DimClient {
     262      var resourceDao = pm.ResourceDao;
     263
     264      var resources = resourceDao.GetAll().ToList();
     265      var dimClients = dimClientDao.GetAllOnlineClients().ToList();
     266
     267      var onlineClients = dimClients.Where(x => resources.Select(y => y.ResourceId).Contains(x.ResourceId));
     268      var addedResources = resources.Where(x => !dimClients.Select(y => y.ResourceId).Contains(x.ResourceId));
     269      var removedResources = dimClients.Where(x => !resources.Select(y => y.ResourceId).Contains(x.ResourceId));
     270
     271      // set expiration time of removed resources
     272      foreach(var r in removedResources) {
     273        r.DateExpired = DateTime.Now;
     274      }
     275
     276      // add new resources
     277      dimClientDao.Save(addedResources.Select(x => new DimClient {
    207278        ResourceId = x.ResourceId,
     279        ParentResourceId = x.ParentResourceId,
    208280        Name = x.Name,
    209         ExpirationTime = null,
    210         ResourceGroupId = x.ResourceGroupId,
    211         GroupName = x.GroupName,
    212         ResourceGroup2Id = x.ResourceGroup2Id,
    213         GroupName2 = x.GroupName2
     281        ResourceType = x.ResourceType,
     282        DateCreated = DateTime.Now,
     283        DateExpired = null
    214284      }));
    215     }
     285
     286      // expire client if its parent has changed and create a new entry
     287      // otherwise perform "normal" update
     288      foreach(var dimc in onlineClients) {
     289        var r = resources.Where(x => x.ResourceId == dimc.ResourceId).SingleOrDefault();
     290        if(r != null) {
     291          if(dimc.ParentResourceId == null ? r.ParentResourceId != null : dimc.ParentResourceId != r.ParentResourceId) {
     292            var now = DateTime.Now;
     293            dimc.DateExpired = now;
     294            dimClientDao.Save(new DimClient {
     295              ResourceId = r.ResourceId,
     296              ParentResourceId = r.ParentResourceId,
     297              Name = r.Name,
     298              ResourceType = r.ResourceType,
     299              DateCreated = now,
     300              DateExpired = null
     301            });
     302          } else {
     303            dimc.Name = r.Name;
     304          }
     305        }
     306      }
     307    }
     308
     309    //// (1) for new slaves (not yet reported in Table DimClients) ...
     310    //// and modified slaves (name or parent resource changed) a new DimClient-entry is created
     311    //// (2) for already reported removed and modifid clients the expiration date is set
     312    //private void UpdateDimClientsTableOld(PersistenceManager pm) {
     313    //  var dimClientDao = pm.DimClientDao;
     314    //  var slaveDao = pm.SlaveDao;
     315    //  var slaves = slaveDao.GetAll();
     316    //  var recentlyAddedClients = dimClientDao.GetAllOnlineClients();
     317    //  var slaveIds = slaves.Select(x => x.ResourceId);
     318
     319    //  var removedClientIds = recentlyAddedClients
     320    //    .Where(x => !slaveIds.Contains(x.ResourceId))
     321    //    .Select(x => x.Id);
     322    //  var modifiedClients =
     323    //    from slave in slaves
     324    //    join client in recentlyAddedClients on slave.ResourceId equals client.ResourceId
     325    //    where (slave.Name != client.Name
     326    //           || slave.ParentResourceId == null && client.ResourceGroupId != null // because both can be null and null comparison
     327    //           || slave.ParentResourceId != null && client.ResourceGroupId == null // does return no entry on the sql server
     328    //           || slave.ParentResourceId != client.ResourceGroupId
     329    //           || ((slave.ParentResource != null) && slave.ParentResource.ParentResourceId != client.ResourceGroup2Id))
     330    //    select new {
     331    //      SlaveId = slave.ResourceId,
     332    //      ClientId = client.Id
     333    //    };
     334    //  var clientIds = dimClientDao.GetAllOnlineClients().Select(x => x.ResourceId);
     335    //  var modifiedClientIds = modifiedClients.Select(x => x.SlaveId);
     336    //  var newClients = slaves
     337    //    .Where(x => !clientIds.Contains(x.ResourceId)
     338    //                || modifiedClientIds.Contains(x.ResourceId))
     339    //    .Select(x => new {
     340    //      x.ResourceId,
     341    //      x.Name,
     342    //      ResourceGroupId = x.ParentResourceId,
     343    //      GroupName = x.ParentResource != null ? x.ParentResource.Name : null,
     344    //      ResourceGroup2Id = x.ParentResource != null ? x.ParentResource.ParentResourceId : null,
     345    //      GroupName2 = x.ParentResource != null ? x.ParentResource.ParentResource != null ? x.ParentResource.ParentResource.Name : null : null
     346    //    })
     347    //    .ToList();
     348
     349    //  var clientsToUpdate = removedClientIds.Union(modifiedClients.Select(x => x.ClientId));
     350    //  dimClientDao.UpdateExpirationTime(clientsToUpdate, DateTime.Now);
     351    //  dimClientDao.Save(newClients.Select(x => new DimClient {
     352    //    ResourceId = x.ResourceId,
     353    //    Name = x.Name,
     354    //    ExpirationTime = null,
     355    //    ResourceGroupId = x.ResourceGroupId,
     356    //    GroupName = x.GroupName,
     357    //    ResourceGroup2Id = x.ResourceGroup2Id,
     358    //    GroupName2 = x.GroupName2
     359    //  }));
     360    //}
     361
    216362
    217363    private void UpdateFactClientInfoTable(DimTime newTime, PersistenceManager pm) {
     
    222368      var newRawFactInfos =
    223369        from s in slaveDao.GetAll()
    224         join c in dimClientDao.GetActiveClients() on s.ResourceId equals c.ResourceId
     370        join c in dimClientDao.GetAllOnlineSlaves() on s.ResourceId equals c.ResourceId
    225371        join lcf in factClientInfoDao.GetLastUpdateTimestamps() on c.ResourceId equals lcf.ResourceId into joinCf
    226372        from cf in joinCf.DefaultIfEmpty()
     
    261407    }
    262408
    263     private void UpdateTaskFactsTable(PersistenceManager pm) {
     409    private void UpdateFactProjectInfoTable(DimTime newTime, PersistenceManager pm) {
     410      var factProjectInfoDao = pm.FactProjectInfoDao;
     411      var dimProjectDao = pm.DimProjectDao;
     412      var projectDao = pm.ProjectDao;
     413
     414      var projectAvailabilityStats = projectDao.GetAvailabilityStatsPerProject();
     415      var projectUsageStats = projectDao.GetUsageStatsPerProject();
     416      var dimProjects = dimProjectDao.GetAllOnlineProjects().ToList();
     417
     418      factProjectInfoDao.Save(
     419        from dimp in dimProjects
     420        let aStats = projectAvailabilityStats.Where(x => x.ProjectId == dimp.ProjectId).SingleOrDefault()
     421        let uStats = projectUsageStats.Where(x => x.ProjectId == dimp.ProjectId).SingleOrDefault()
     422        select new FactProjectInfo {
     423            ProjectId = dimp.Id,
     424            DimTime = newTime,
     425            NumTotalCores = aStats != null ? aStats.Cores : 0,
     426            TotalMemory = aStats != null ? aStats.Memory : 0,
     427            NumUsedCores = uStats != null ? uStats.Cores : 0,
     428            UsedMemory = uStats != null ? uStats.Memory : 0
     429          }
     430        );
     431    }
     432
     433    private void UpdateFactTaskTable(PersistenceManager pm) {
    264434      var factTaskDao = pm.FactTaskDao;
    265435      var taskDao = pm.TaskDao;
     
    267437
    268438      var factTaskIds = factTaskDao.GetAll().Select(x => x.TaskId);
    269       var notFinishedFactTasks = factTaskDao.GetNotFinishedTasks().Select(x => new {
    270         x.TaskId,
    271         x.LastClientId
    272       });
    273 
    274       var newTasks =
     439      var notFinishedFactTasks = factTaskDao.GetNotFinishedTasks();
     440      //var notFinishedFactTasks = factTaskDao.GetNotFinishedTasks().Select(x => new {
     441      //  x.TaskId,
     442      //  x.LastClientId
     443      //});
     444
     445      // query several properties for all new and not finished tasks
     446      // in order to use them later either...
     447      // (1) to update the fact task entry of not finished tasks
     448      // (2) to insert a new fact task entry for new tasks
     449      var newAndNotFinishedTasks =
    275450        (from task in taskDao.GetAllChildTasks()
    276451         let stateLogs = task.StateLogs.OrderByDescending(x => x.DateTime)
     
    280455         join lastFactTask in notFinishedFactTasks on task.TaskId equals lastFactTask.TaskId into lastFactPerTask
    281456         from lastFact in lastFactPerTask.DefaultIfEmpty()
    282          join client in dimClientDao.GetActiveClients() on lastSlaveId equals client.ResourceId into clientsPerSlaveId
     457         join client in dimClientDao.GetAllOnlineClients() on lastSlaveId equals client.ResourceId into clientsPerSlaveId
    283458         from client in clientsPerSlaveId.DefaultIfEmpty()
    284459         select new {
     
    296471         }).ToList();
    297472
    298       //insert facts for new tasks
     473      // (1) update data of already existing facts
     474      // i.e. for all in newAndNotFinishedTasks where NotFinishedTask = true
     475      foreach (var notFinishedFactTask in notFinishedFactTasks) {
     476        var nfftUpdate = newAndNotFinishedTasks.Where(x => x.TaskId == notFinishedFactTask.TaskId).SingleOrDefault();
     477        if(nfftUpdate != null) {
     478          var taskData = CalculateFactTaskData(nfftUpdate.StateLogs);
     479
     480          notFinishedFactTask.StartTime = taskData.StartTime;
     481          notFinishedFactTask.EndTime = taskData.EndTime;
     482          notFinishedFactTask.LastClientId = nfftUpdate.LastClientId;
     483          notFinishedFactTask.Priority = nfftUpdate.Priority;
     484          notFinishedFactTask.CoresRequired = nfftUpdate.CoresRequired;
     485          notFinishedFactTask.MemoryRequired = nfftUpdate.MemoryRequired;
     486          notFinishedFactTask.NumCalculationRuns = taskData.CalculationRuns;
     487          notFinishedFactTask.NumRetries = taskData.Retries;
     488          notFinishedFactTask.WaitingTime = taskData.WaitingTime;
     489          notFinishedFactTask.CalculatingTime = taskData.CalculatingTime;
     490          notFinishedFactTask.TransferTime = taskData.TransferTime;
     491          notFinishedFactTask.TaskState = nfftUpdate.State;
     492          notFinishedFactTask.Exception = taskData.Exception;
     493          notFinishedFactTask.InitialWaitingTime = taskData.InitialWaitingTime;
     494        }
     495      }
     496
     497      // (2) insert facts for new tasks
     498      // i.e. for all in newAndNotFinishedTasks where NotFinishedTask = false
    299499      factTaskDao.Save(
    300         from x in newTasks
     500        from x in newAndNotFinishedTasks
    301501        where !x.NotFinishedTask
    302502        let taskData = CalculateFactTaskData(x.StateLogs)
     
    320520        });
    321521
    322       //update data of already existing facts
    323       foreach (var notFinishedTask in factTaskDao.GetNotFinishedTasks()) {
    324         var ntc = newTasks.Where(x => x.TaskId == notFinishedTask.TaskId);
    325         if (ntc.Any()) {
    326           var x = ntc.Single();
    327           var taskData = CalculateFactTaskData(x.StateLogs);
    328 
    329           notFinishedTask.StartTime = taskData.StartTime;
    330           notFinishedTask.EndTime = taskData.EndTime;
    331           notFinishedTask.LastClientId = x.LastClientId;
    332           notFinishedTask.Priority = x.Priority;
    333           notFinishedTask.CoresRequired = x.CoresRequired;
    334           notFinishedTask.MemoryRequired = x.MemoryRequired;
    335           notFinishedTask.NumCalculationRuns = taskData.CalculationRuns;
    336           notFinishedTask.NumRetries = taskData.Retries;
    337           notFinishedTask.WaitingTime = taskData.WaitingTime;
    338           notFinishedTask.CalculatingTime = taskData.CalculatingTime;
    339           notFinishedTask.TransferTime = taskData.TransferTime;
    340           notFinishedTask.TaskState = x.State;
    341           notFinishedTask.Exception = taskData.Exception;
    342           notFinishedTask.InitialWaitingTime = taskData.InitialWaitingTime;
    343         }
    344       }
     522
     523      ////update data of already existing facts
     524      //foreach (var notFinishedTask in factTaskDao.GetNotFinishedTasks()) {
     525      //  var ntc = newTasks.Where(x => x.TaskId == notFinishedTask.TaskId);
     526      //  if (ntc.Any()) {
     527      //    var x = ntc.Single();
     528      //    var taskData = CalculateFactTaskData(x.StateLogs);
     529
     530      //    notFinishedTask.StartTime = taskData.StartTime;
     531      //    notFinishedTask.EndTime = taskData.EndTime;
     532      //    notFinishedTask.LastClientId = x.LastClientId;
     533      //    notFinishedTask.Priority = x.Priority;
     534      //    notFinishedTask.CoresRequired = x.CoresRequired;
     535      //    notFinishedTask.MemoryRequired = x.MemoryRequired;
     536      //    notFinishedTask.NumCalculationRuns = taskData.CalculationRuns;
     537      //    notFinishedTask.NumRetries = taskData.Retries;
     538      //    notFinishedTask.WaitingTime = taskData.WaitingTime;
     539      //    notFinishedTask.CalculatingTime = taskData.CalculatingTime;
     540      //    notFinishedTask.TransferTime = taskData.TransferTime;
     541      //    notFinishedTask.TaskState = x.State;
     542      //    notFinishedTask.Exception = taskData.Exception;
     543      //    notFinishedTask.InitialWaitingTime = taskData.InitialWaitingTime;
     544      //  }
     545      //}
    345546    }
    346547
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/Interfaces/IAuthorizationManager.cs

    r15583 r16240  
    2222using System;
    2323using HeuristicLab.Services.Hive.DataTransfer;
     24using System.Collections.Generic;
    2425
    2526namespace HeuristicLab.Services.Hive {
     
    3536
    3637    void AuthorizeForResourceAdministration(Guid resourceId);
     38
     39    void AuthorizeForProjectAdministration(Guid projectId, bool parentalOwnership);
     40
     41    void AuthorizeForProjectResourceAdministration(Guid projectId, IEnumerable<Guid> resourceIds);
     42
     43    void AuthorizeProjectForResourcesUse(Guid projectId, IEnumerable<Guid> resourceIds);
     44
     45    void AuthorizeUserForProjectUse(Guid userId, Guid projectId);
    3746  }
    3847}
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs

    r15583 r16240  
    2727using DA = HeuristicLab.Services.Hive.DataAccess;
    2828using DT = HeuristicLab.Services.Hive.DataTransfer;
    29 
     29using System.Collections.Generic;
     30using System.Linq;
    3031
    3132namespace HeuristicLab.Services.Hive {
    3233  public class AuthorizationManager : IAuthorizationManager {
    3334
    34     private const string NOT_AUTHORIZED = "Current user is not authorized to access the requested resource";
     35    private const string NOT_AUTHORIZED_USERRESOURCE = "Current user is not authorized to access the requested resource";
     36    private const string NOT_AUTHORIZED_USERPROJECT = "Current user is not authorized to access the requested project";
     37    private const string NOT_AUTHORIZED_USERJOB = "Current user is not authorized to access the requested job";
     38    private const string NOT_AUTHORIZED_PROJECTRESOURCE = "Selected project is not authorized to access the requested resource";
     39    private const string USER_NOT_IDENTIFIED = "User could not be identified";
     40    private const string JOB_NOT_EXISTENT = "Queried job could not be found";
     41    private const string TASK_NOT_EXISTENT = "Queried task could not be found";
     42    private const string PROJECT_NOT_EXISTENT = "Queried project could not be found";
     43
    3544    private IPersistenceManager PersistenceManager {
    3645      get { return ServiceLocator.Instance.PersistenceManager; }
     
    4756    public void Authorize(Guid userId) {
    4857      if (userId != ServiceLocator.Instance.UserManager.CurrentUserId)
    49         throw new SecurityException(NOT_AUTHORIZED);
     58        throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
    5059    }
    5160
    5261    public void AuthorizeForTask(Guid taskId, DT.Permission requiredPermission) {
    5362      if (ServiceLocator.Instance.RoleVerifier.IsInRole(HiveRoles.Slave)) return; // slave-users can access all tasks
     63      if (ServiceLocator.Instance.RoleVerifier.IsInRole(HiveRoles.Administrator)) return; // administrator can access all tasks
     64      var currentUserId = UserManager.CurrentUserId;
    5465      var pm = PersistenceManager;
    5566      var taskDao = pm.TaskDao;
     67      var projectDao = pm.ProjectDao;
    5668      pm.UseTransaction(() => {
    5769        var task = taskDao.GetById(taskId);
    58         if (task == null) throw new SecurityException(NOT_AUTHORIZED);
     70        if (task == null) throw new SecurityException(TASK_NOT_EXISTENT);
     71
     72        // check if user is granted to administer a job-parenting project
     73        var administrationGrantedProjects = projectDao
     74          .GetAdministrationGrantedProjectsForUser(currentUserId)
     75          .ToList();
     76        if (administrationGrantedProjects.Contains(task.Job.Project)) return;
     77
    5978        AuthorizeJob(pm, task.JobId, requiredPermission);
    6079      });
     
    6281
    6382    public void AuthorizeForJob(Guid jobId, DT.Permission requiredPermission) {
    64       var pm = PersistenceManager;
    65       pm.UseTransaction(() => {
     83      if (ServiceLocator.Instance.RoleVerifier.IsInRole(HiveRoles.Administrator)) return; // administrator can access all jobs
     84      var currentUserId = UserManager.CurrentUserId;
     85      var pm = PersistenceManager;
     86      var jobDao = pm.JobDao;
     87      var projectDao = pm.ProjectDao;
     88      pm.UseTransaction(() => {
     89        var job = jobDao.GetById(jobId);
     90        if(job == null) throw new SecurityException(JOB_NOT_EXISTENT);
     91
     92        // check if user is granted to administer a job-parenting project
     93        var administrationGrantedProjects = projectDao
     94          .GetAdministrationGrantedProjectsForUser(currentUserId)
     95          .ToList();
     96        if (administrationGrantedProjects.Contains(job.Project)) return;
     97
    6698        AuthorizeJob(pm, jobId, requiredPermission);
    6799      });
    68100    }
    69101
     102    // authorize if user is admin or resource owner
    70103    public void AuthorizeForResourceAdministration(Guid resourceId) {
     104      var currentUserId = UserManager.CurrentUserId;
    71105      var pm = PersistenceManager;
    72106      var resourceDao = pm.ResourceDao;
    73107      pm.UseTransaction(() => {
    74108        var resource = resourceDao.GetById(resourceId);
    75         if (resource == null) throw new SecurityException(NOT_AUTHORIZED);
    76         if (resource.OwnerUserId != UserManager.CurrentUserId
     109        if (resource == null) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     110
     111        if (resource.OwnerUserId != currentUserId
    77112            && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
    78           throw new SecurityException(NOT_AUTHORIZED);
    79         }
    80       });
     113          throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     114        }
     115      });
     116    }
     117
     118    // authorize if user is admin, project owner or owner of a parent project
     119    public void AuthorizeForProjectAdministration(Guid projectId, bool parentalOwnership) {
     120      if (projectId == null || projectId == Guid.Empty) return;
     121      var currentUserId = UserManager.CurrentUserId;
     122      var pm = PersistenceManager;
     123      var projectDao = pm.ProjectDao;
     124      pm.UseTransaction(() => {
     125        var project = projectDao.GetById(projectId);
     126        if (project == null) throw new ArgumentException(PROJECT_NOT_EXISTENT);
     127        if(!RoleVerifier.IsInRole(HiveRoles.Administrator)
     128          && !project.ParentProjectId.HasValue) {
     129          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     130        }
     131
     132        List<Project> projectBranch = null;
     133        if(parentalOwnership) projectBranch = projectDao.GetParentProjectsById(projectId).ToList();
     134        else projectBranch = projectDao.GetCurrentAndParentProjectsById(projectId).ToList();
     135
     136        if(!RoleVerifier.IsInRole(HiveRoles.Administrator)
     137            && !projectBranch.Select(x => x.OwnerUserId).Contains(currentUserId)) {
     138          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     139        }
     140      });
     141    }
     142
     143    // authorize if user is admin, or owner of a project or parent project, for which the resources are assigned to
     144    public void AuthorizeForProjectResourceAdministration(Guid projectId, IEnumerable<Guid> resourceIds) {
     145      if (projectId == null || projectId == Guid.Empty) return;
     146      var currentUserId = UserManager.CurrentUserId;
     147      var pm = PersistenceManager;
     148      var projectDao = pm.ProjectDao;
     149      var resourceDao = pm.ResourceDao;
     150      var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     151      pm.UseTransaction(() => {
     152        // check if project exists (not necessary)
     153        var project = projectDao.GetById(projectId);
     154        if (project == null) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     155
     156        // check if resourceIds exist
     157        if (resourceIds != null && resourceIds.Any() && !resourceDao.CheckExistence(resourceIds))
     158          throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     159
     160        // check if user is admin
     161        if (RoleVerifier.IsInRole(HiveRoles.Administrator)) return;
     162
     163        // check if user is owner of the project or a parent project
     164        var projectBranch = projectDao.GetCurrentAndParentProjectsById(projectId).ToList();
     165        if (!projectBranch.Select(x => x.OwnerUserId).Contains(currentUserId)
     166            && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
     167          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     168        }
     169
     170        // check if the all argument resourceIds are among the assigned resources of the owned projects
     171        var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourceIdsOfOwnedParentProjects(projectId, currentUserId).ToList();
     172        if(resourceIds.Except(grantedResourceIds).Any()) {
     173          throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     174        }
     175      });
     176    }
     177
     178    // Check if a project is authorized to use a list of resources
     179    public void AuthorizeProjectForResourcesUse(Guid projectId, IEnumerable<Guid> resourceIds) {
     180      if (projectId == null || projectId == Guid.Empty || resourceIds == null || !resourceIds.Any()) return;
     181      var pm = PersistenceManager;
     182      var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     183      if (!assignedProjectResourceDao.CheckProjectGrantedForResources(projectId, resourceIds))
     184        throw new SecurityException(NOT_AUTHORIZED_PROJECTRESOURCE);
     185    }
     186
     187    // Check if current user is authorized to use an explicit project (e.g. in order to add a job)
     188    // note: administrators and project owner are NOT automatically granted
     189    public void AuthorizeUserForProjectUse(Guid userId, Guid projectId) {
     190      if(userId == null || userId == Guid.Empty) {
     191        throw new SecurityException(USER_NOT_IDENTIFIED);
     192      }
     193      if(projectId == null) return;
     194
     195      var pm = PersistenceManager;
     196      // collect current and group membership Ids
     197      var userAndGroupIds = new List<Guid>() { userId };
     198      userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(userId));
     199      // perform the actual check
     200      var projectPermissionDao = pm.ProjectPermissionDao;
     201      if (!projectPermissionDao.CheckUserGrantedForProject(projectId, userAndGroupIds)) {
     202        throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     203      }
    81204    }
    82205
     
    93216
    94217    private void AuthorizeJob(IPersistenceManager pm, Guid jobId, DT.Permission requiredPermission) {
     218      var currentUserId = UserManager.CurrentUserId;
    95219      var requiredPermissionEntity = requiredPermission.ToEntity();
    96       DA.Permission permission = GetPermissionForJob(pm, jobId, UserManager.CurrentUserId);
     220      DA.Permission permission = GetPermissionForJob(pm, jobId, currentUserId);
    97221      if (permission == Permission.NotAllowed
    98222          || ((permission != requiredPermissionEntity) && requiredPermissionEntity == Permission.Full)) {
    99         throw new SecurityException(NOT_AUTHORIZED);
     223        throw new SecurityException(NOT_AUTHORIZED_USERJOB);
    100224      }
    101225    }
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs

    r15583 r16240  
    3434    public void Cleanup() {
    3535      var pm = PersistenceManager;
     36
     37      pm.UseTransaction(() => {
     38        FinishJobDeletion(pm);
     39        pm.SubmitChanges();
     40      });
     41
    3642      pm.UseTransaction(() => {
    3743        SetTimeoutSlavesOffline(pm);
     
    4551        pm.SubmitChanges();
    4652      });
     53    }
     54
     55    /// <summary>
     56    /// Deletes all jobs which are in state "DeletionPending" (this will include all corresponding tasks).
     57    /// The state "DeletionPending" is set by HiveJanitor > StatisticsGenerator
     58    /// </summary>
     59    private void FinishJobDeletion(IPersistenceManager pm) {
     60      var jobDao = pm.JobDao;
     61      jobDao.DeleteByState(JobState.DeletionPending);
    4762    }
    4863
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs

    r15583 r16240  
    142142    private IEnumerable<MessageContainer> UpdateTasks(IPersistenceManager pm, Heartbeat heartbeat, bool isAllowedToCalculate) {
    143143      var taskDao = pm.TaskDao;
    144       var assignedResourceDao = pm.AssignedResourceDao;
     144      var jobDao = pm.JobDao;
     145      var assignedJobResourceDao = pm.AssignedJobResourceDao;
    145146      var actions = new List<MessageContainer>();
    146147      if (heartbeat.JobProgress == null || !heartbeat.JobProgress.Any())
    147148        return actions;
    148149
    149       if (!isAllowedToCalculate && heartbeat.JobProgress.Count != 0) {
    150         actions.Add(new MessageContainer(MessageContainer.MessageType.PauseAll));
    151       } else {
    152         // select all tasks and statelogs with one query
    153         var taskIds = heartbeat.JobProgress.Select(x => x.Key).ToList();
    154         var taskInfos = pm.UseTransaction(() =>
    155           (from task in taskDao.GetAll()
    156            where taskIds.Contains(task.TaskId)
    157            let lastStateLog = task.StateLogs.OrderByDescending(x => x.DateTime).FirstOrDefault()
    158            select new {
    159              TaskId = task.TaskId,
    160              Command = task.Command,
    161              SlaveId = lastStateLog != null ? lastStateLog.SlaveId : default(Guid)
    162            }).ToList()
    163         );
    164 
    165         // process the jobProgresses
    166         foreach (var jobProgress in heartbeat.JobProgress) {
    167           var progress = jobProgress;
    168           var curTask = taskInfos.SingleOrDefault(x => x.TaskId == progress.Key);
    169           if (curTask == null) {
    170             actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, progress.Key));
    171             LogFactory.GetLogger(this.GetType().Namespace).Log("Task on slave " + heartbeat.SlaveId + " does not exist in DB: " + jobProgress.Key);
    172           } else {
    173             var slaveId = curTask.SlaveId;
    174             if (slaveId == Guid.Empty || slaveId != heartbeat.SlaveId) {
    175               // assigned slave does not match heartbeat
     150      var jobIdsWithStatisticsPending = jobDao.GetJobIdsByState(DA.JobState.StatisticsPending).ToList();
     151
     152      // select all tasks and statelogs with one query
     153      var taskIds = heartbeat.JobProgress.Select(x => x.Key).ToList();
     154      var taskInfos = pm.UseTransaction(() =>
     155        (from task in taskDao.GetAll()
     156          where taskIds.Contains(task.TaskId)
     157          let lastStateLog = task.StateLogs.OrderByDescending(x => x.DateTime).FirstOrDefault()
     158          select new {
     159            TaskId = task.TaskId,
     160            JobId = task.JobId,
     161            State = task.State,
     162            Command = task.Command,
     163            SlaveId = lastStateLog != null ? lastStateLog.SlaveId : default(Guid)
     164          }).ToList()
     165      );
     166
     167      // process the jobProgresses
     168      foreach (var jobProgress in heartbeat.JobProgress) {
     169        var progress = jobProgress;
     170        var curTask = taskInfos.SingleOrDefault(x => x.TaskId == progress.Key);
     171        if (curTask == null) {
     172          actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, progress.Key));
     173          LogFactory.GetLogger(this.GetType().Namespace).Log("Task on slave " + heartbeat.SlaveId + " does not exist in DB: " + jobProgress.Key);
     174        } else if (jobIdsWithStatisticsPending.Contains(curTask.JobId)) {
     175          // parenting job of current task has been requested for deletion (indicated by job state "Statistics Pending")
     176          // update task execution time
     177          pm.UseTransaction(() => {
     178            taskDao.UpdateExecutionTime(curTask.TaskId, progress.Value.TotalMilliseconds);
     179          });
     180          actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
     181          LogFactory.GetLogger(this.GetType().Namespace).Log("Abort task " + curTask.TaskId + " on slave " + heartbeat.SlaveId + ". The parenting job " + curTask.JobId + " was requested to be deleted.");
     182        } else if (curTask.SlaveId == Guid.Empty || curTask.SlaveId != heartbeat.SlaveId) {
     183          // assigned slave does not match heartbeat
     184          actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
     185          LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not supposed to calculate task: " + curTask.TaskId);
     186        } else if (!isAllowedToCalculate) {
     187          actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
     188          LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not allowed to calculate any tasks tue to a downtime. The task is paused.");
     189        } else if (!assignedJobResourceDao.CheckJobGrantedForResource(curTask.JobId, heartbeat.SlaveId)) {
     190          // slaveId (and parent resourceGroupIds) are not among the assigned resources ids for task-parenting job
     191          // this might happen when (a) job-resource assignment has been changed (b) slave is moved to different group
     192          actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
     193          LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not granted to calculate task: " + curTask.TaskId + " of job: " + curTask.JobId);
     194        } else {
     195          // update task execution time
     196          pm.UseTransaction(() => {
     197            taskDao.UpdateExecutionTime(curTask.TaskId, progress.Value.TotalMilliseconds);
     198          });
     199          switch (curTask.Command) {
     200            case DA.Command.Stop:
     201              actions.Add(new MessageContainer(MessageContainer.MessageType.StopTask, curTask.TaskId));
     202              break;
     203            case DA.Command.Pause:
     204              actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
     205              break;
     206            case DA.Command.Abort:
    176207              actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
    177               LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not supposed to calculate task: " + curTask.TaskId);
    178             } else if (!assignedResourceDao.TaskIsAllowedToBeCalculatedBySlave(curTask.TaskId, heartbeat.SlaveId)) {
    179               // assigned resources ids of task do not match with slaveId (and parent resourceGroupIds); this might happen when slave is moved to different group
    180               actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
    181             } else {
    182               // update task execution time
    183               pm.UseTransaction(() => {
    184                 taskDao.UpdateExecutionTime(curTask.TaskId, progress.Value.TotalMilliseconds);
    185               });
    186               switch (curTask.Command) {
    187                 case DA.Command.Stop:
    188                   actions.Add(new MessageContainer(MessageContainer.MessageType.StopTask, curTask.TaskId));
    189                   break;
    190                 case DA.Command.Pause:
    191                   actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
    192                   break;
    193                 case DA.Command.Abort:
    194                   actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
    195                   break;
    196               }
    197             }
    198           }
    199         }
    200       }
     208              break;
     209          }
     210        }
     211       
     212      }
    201213      return actions;
    202214    }
  • branches/2915-AbsoluteSymbol/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs

    r15583 r16240  
    3131  public interface IHiveService {
    3232    #region Task Methods
    33     [OperationContract]
    34     Guid AddTask(Task task, TaskData taskData, IEnumerable<Guid> resourceIds);
     33
     34    [OperationContract]
     35    Guid AddTask(Task task, TaskData taskData);
    3536
    3637    [OperationContract]
     
    7879
    7980    [OperationContract]
    80     Guid AddJob(Job jobDto);
    81 
    82     [OperationContract]
    83     void UpdateJob(Job jobDto);
    84 
    85     [OperationContract]
    86     void DeleteJob(Guid JobId);
     81    IEnumerable<Job> GetJobsByProjectId(Guid projectId);
     82
     83    [OperationContract]
     84    IEnumerable<Job> GetJobsByProjectIds(IEnumerable<Guid> projectIds);
     85
     86    [OperationContract]
     87    Guid AddJob(Job jobDto, IEnumerable<Guid> resourceIds);
     88
     89    [OperationContract]
     90    void UpdateJob(Job jobDto, IEnumerable<Guid> resourceIds);
     91
     92    [OperationContract]
     93    void UpdateJobState(Guid JobId, JobState jobState);
     94
     95    [OperationContract]
     96    void UpdateJobStates(IEnumerable<Guid> jobIds, JobState jobState);
     97
     98    [OperationContract]
     99    IEnumerable<AssignedJobResource> GetAssignedResourcesForJob(Guid jobId);
    87100    #endregion
    88101
     
    132145    #endregion
    133146
    134     #region ResourcePermission Methods
    135     [OperationContract]
    136     void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds);
    137 
    138     [OperationContract]
    139     void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds);
    140 
    141     [OperationContract]
    142     IEnumerable<ResourcePermission> GetResourcePermissions(Guid resourceId);
     147    #region Project Methods
     148    [OperationContract]
     149    Guid AddProject(Project projectDto);
     150
     151    [OperationContract]
     152    void UpdateProject(Project projectDto);
     153
     154    [OperationContract]
     155    void DeleteProject(Guid projectId);
     156
     157    [OperationContract]
     158    Project GetProject(Guid projectId);
     159
     160    [OperationContract]
     161    IEnumerable<Project> GetProjects();
     162
     163    [OperationContract]
     164    IEnumerable<Project> GetProjectsForAdministration();
     165
     166    [OperationContract]
     167    IDictionary<Guid, HashSet<Guid>> GetProjectGenealogy();
     168
     169    [OperationContract]
     170    IDictionary<Guid, string> GetProjectNames();
     171    #endregion
     172
     173    #region ProjectPermission Methods
     174    [OperationContract]
     175    void SaveProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool reassign, bool cascading, bool reassignCascading);
     176
     177    //[OperationContract]
     178    //void GrantProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading);
     179
     180    //[OperationContract]
     181    //void RevokeProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading);
     182
     183    [OperationContract]
     184    IEnumerable<ProjectPermission> GetProjectPermissions(Guid projectId);
     185    #endregion
     186
     187    #region AssignedProjectResource Methods
     188    [OperationContract]
     189    void SaveProjectResourceAssignments(Guid projectId, List<Guid> resourceIds, bool reassign, bool cascading, bool reassignCascading);
     190
     191    //[OperationContract]
     192    //void AssignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading);
     193
     194    //[OperationContract]
     195    //void UnassignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading);
     196
     197    [OperationContract]
     198    IEnumerable<AssignedProjectResource> GetAssignedResourcesForProject(Guid projectId);
     199
     200    [OperationContract]
     201    IEnumerable<AssignedProjectResource> GetAssignedResourcesForProjectAdministration(Guid projectId);
     202
     203    [OperationContract]
     204    IEnumerable<AssignedProjectResource> GetAssignedResourcesForProjectsAdministration(IEnumerable<Guid> projectIds);
    143205    #endregion
    144206
     
    160222
    161223    [OperationContract]
     224    IEnumerable<Slave> GetSlavesForAdministration();
     225
     226    [OperationContract]
     227    IEnumerable<SlaveGroup> GetSlaveGroupsForAdministration();
     228
     229    [OperationContract]
     230    IDictionary<Guid, HashSet<Guid>> GetResourceGenealogy();
     231
     232    [OperationContract]
     233    IDictionary<Guid, string> GetResourceNames();
     234
     235    [OperationContract]
    162236    void UpdateSlave(Slave slave);
    163237
     
    207281    [OperationContract]
    208282    Guid GetUserIdByUsername(string username);
     283
     284    [OperationContract]
     285    Dictionary<Guid, HashSet<Guid>> GetUserGroupTree();
     286
     287    [OperationContract]
     288    bool CheckAccessToAdminAreaGranted();
    209289    #endregion
    210290
Note: See TracChangeset for help on using the changeset viewer.