Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
09/13/18 13:18:45 (6 years ago)
Author:
ddorfmei
Message:

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

Location:
branches/2931_OR-Tools_LP_MIP
Files:
1 deleted
12 edited
5 copied

Legend:

Unmodified
Added
Removed
  • branches/2931_OR-Tools_LP_MIP

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

  • branches/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/Converter.cs

    r15583 r16139  
    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/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/DataTransfer/Job.cs

    r15583 r16139  
    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/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj

    r16070 r16139  
    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/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/HiveService.cs

    r15583 r16139  
    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          var administrationGrantedProjects = projectDao
     358            .GetAdministrationGrantedProjectsForUser(currentUserId)
     359            .ToList();
     360
     361          if (administrationGrantedProjects.Select(x => x.ProjectId).Contains(projectId)) {
     362            var jobs = jobDao.GetByProjectId(projectId)
     363            .Select(x => x.ToDto())
     364            .ToList();
     365
     366            EvaluateJobs(pm, jobs);
     367            return jobs;
     368          } else {
     369            return Enumerable.Empty<DT.Job>();
     370          }
     371        });
     372      }
     373    }
     374
     375    public IEnumerable<DT.Job> GetJobsByProjectIds(IEnumerable<Guid> projectIds) {
     376      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     377      var pm = PersistenceManager;
     378      using (new PerformanceLogger("GetJobsByProjectIds")) {
     379        var currentUserId = UserManager.CurrentUserId;
     380        var projectDao = pm.ProjectDao;
     381        var jobDao = pm.JobDao;
     382        return pm.UseTransaction(() => {
     383          // check for which of requested projectIds the user is granted to administer
     384          var administrationGrantedProjectIds = projectDao
     385            .GetAdministrationGrantedProjectsForUser(currentUserId)
     386            .Select(x => x.ProjectId)
     387            .ToList();
     388          var requestedAndGrantedProjectIds = projectIds.Intersect(administrationGrantedProjectIds);
     389
     390          if (requestedAndGrantedProjectIds.Any()) {
     391            var jobs = jobDao.GetByProjectIds(requestedAndGrantedProjectIds)
     392              .Select(x => x.ToDto())
    353393              .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;
     394
     395            EvaluateJobs(pm, jobs);
     396            return jobs;
     397          } else {
     398            return Enumerable.Empty<DT.Job>();
     399          }
     400        });
     401      }
     402    }
     403
     404    public Guid AddJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
     405      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     406      var dateCreated = DateTime.Now;
     407      var pm = PersistenceManager;
     408
     409      // check project availability (cf. duration)
     410      CheckProjectAvailability(pm, jobDto.ProjectId, dateCreated);
     411
     412      // check user - project
     413      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
     414
     415      // check project - resources
     416      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
     417
    377418      using (new PerformanceLogger("AddJob")) {
    378419        var jobDao = pm.JobDao;
    379420        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) {
     421
     422        return pm.UseTransaction(() => {
     423          var newJob = jobDto.ToEntity();
     424          newJob.OwnerUserId = UserManager.CurrentUserId;
     425          newJob.DateCreated = dateCreated;
     426
     427          // add resource assignments
     428          if (resourceIds != null && resourceIds.Any()) {
     429            newJob.AssignedJobResources.AddRange(resourceIds.Select(
     430              x => new DA.AssignedJobResource {
     431                ResourceId = x
     432              }));
     433          }
     434
     435          var job = jobDao.Save(newJob);
     436          if (userPriorityDao.GetById(newJob.OwnerUserId) == null) {
    385437            userPriorityDao.Save(new DA.UserPriority {
    386               UserId = jobDto.OwnerUserId,
    387               DateEnqueued = jobDto.DateCreated
     438              UserId = newJob.OwnerUserId,
     439              DateEnqueued = newJob.DateCreated
    388440            });
    389441          }
     
    394446    }
    395447
    396     public void UpdateJob(DT.Job jobDto) {
     448    public void UpdateJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
    397449      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    398450      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
    399451      var pm = PersistenceManager;
     452      var dateUpdated = DateTime.Now;
     453
     454      // check project availability
     455      CheckProjectAvailability(pm, jobDto.ProjectId, dateUpdated);
     456      // check user - project permission
     457      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
     458      // check project - resources permission
     459      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
     460
    400461      using (new PerformanceLogger("UpdateJob")) {
    401462        bool exists = true;
     
    406467            exists = false;
    407468            job = new DA.Job();
    408           }
     469          } else if (job.State != DA.JobState.Online) {
     470            throw new InvalidOperationException(NO_JOB_UPDATE_POSSIBLE);
     471          }
     472
     473
    409474          jobDto.CopyToEntity(job);
     475
    410476          if (!exists) {
     477            // add resource assignments
     478            if (resourceIds != null && resourceIds.Any()) {
     479              job.AssignedJobResources.AddRange(resourceIds.Select(
     480                x => new DA.AssignedJobResource {
     481                  ResourceId = x
     482                }));
     483            }
    411484            jobDao.Save(job);
    412           }
    413           pm.SubmitChanges();
    414         });
    415       }
    416     }
    417 
    418     public void DeleteJob(Guid jobId) {
     485          } else if (resourceIds != null) {
     486            var addedJobResourceIds = resourceIds.Except(job.AssignedJobResources.Select(x => x.ResourceId));
     487            var removedJobResourceIds = job.AssignedJobResources
     488              .Select(x => x.ResourceId)
     489              .Except(resourceIds)
     490              .ToArray();
     491
     492            // remove resource assignments
     493            foreach (var rid in removedJobResourceIds) {
     494              var ajr = job.AssignedJobResources.Where(x => x.ResourceId == rid).SingleOrDefault();
     495              if (ajr != null) job.AssignedJobResources.Remove(ajr);
     496            }
     497
     498            // add resource assignments
     499            job.AssignedJobResources.AddRange(addedJobResourceIds.Select(
     500              x => new DA.AssignedJobResource {
     501                ResourceId = x
     502              }));
     503          }
     504          pm.SubmitChanges();
     505        });
     506      }
     507    }
     508
     509    public void UpdateJobState(Guid jobId, DT.JobState jobState) {
    419510      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    420511      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
    421512      var pm = PersistenceManager;
    422       using (new PerformanceLogger("DeleteJob")) {
     513      using (new PerformanceLogger("UpdateJobState")) {
    423514        var jobDao = pm.JobDao;
    424515        pm.UseTransaction(() => {
    425           // child task will be deleted by db-trigger
    426           jobDao.Delete(jobId);
    427           pm.SubmitChanges();
    428         });
     516          var job = jobDao.GetById(jobId);
     517          if (job != null) {
     518            var jobStateEntity = jobState.ToEntity();
     519            // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
     520            // and from "StatisticsPending" to "DeletionPending" = deletion request by HiveStatisticGenerator for EventManager
     521            if (job.State == DA.JobState.Online && jobStateEntity == DA.JobState.StatisticsPending) {
     522              job.State = jobStateEntity;
     523              foreach (var task in job.Tasks
     524              .Where(x => x.State == DA.TaskState.Waiting
     525                || x.State == DA.TaskState.Paused
     526                || x.State == DA.TaskState.Offline)) {
     527                task.State = DA.TaskState.Aborted;
     528              }
     529              pm.SubmitChanges();
     530            } else if (job.State == DA.JobState.StatisticsPending && jobStateEntity == DA.JobState.DeletionPending) {
     531              job.State = jobStateEntity;
     532              pm.SubmitChanges();
     533            }
     534          }
     535        });
     536      }
     537    }
     538
     539    public void UpdateJobStates(IEnumerable<Guid> jobIds, DT.JobState jobState) {
     540      if (jobState != JobState.StatisticsPending) return; // only process requests for "StatisticsPending"
     541
     542      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     543      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     544      var currentUserId = UserManager.CurrentUserId;
     545
     546      var pm = PersistenceManager;
     547      using (new PerformanceLogger("UpdateJobStates")) {
     548        var jobDao = pm.JobDao;
     549        var projectDao = pm.ProjectDao;
     550        pm.UseTransaction(() => {
     551          foreach (var jobId in jobIds) {
     552            var job = jobDao.GetById(jobId);
     553            if (job != null) {
     554
     555              var administrationGrantedProjects = projectDao
     556                .GetAdministrationGrantedProjectsForUser(currentUserId)
     557                .ToList();
     558
     559              // check if user is granted to administer the job-parenting project
     560              if (isAdministrator || administrationGrantedProjects.Contains(job.Project)) {
     561                // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
     562                if (job.State == DA.JobState.Online) {
     563                  job.State = DA.JobState.StatisticsPending;
     564                  foreach (var task in job.Tasks
     565                  .Where(x => x.State == DA.TaskState.Waiting
     566                    || x.State == DA.TaskState.Paused
     567                    || x.State == DA.TaskState.Offline)) {
     568                    task.State = DA.TaskState.Aborted;
     569                  }
     570                  pm.SubmitChanges();
     571                }
     572              }
     573            }
     574          }
     575        });
     576      }
     577    }
     578
     579    public IEnumerable<DT.AssignedJobResource> GetAssignedResourcesForJob(Guid jobId) {
     580      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     581      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
     582      var pm = PersistenceManager;
     583      var assignedJobResourceDao = pm.AssignedJobResourceDao;
     584      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     585        return pm.UseTransaction(() =>
     586          assignedJobResourceDao.GetByJobId(jobId)
     587          .Select(x => x.ToDto())
     588          .ToList()
     589        );
    429590      }
    430591    }
     
    532693          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
    533694        }
    534       }
    535       catch (Exception ex) {
     695      } catch (Exception ex) {
    536696        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
    537697      }
     
    604764    #endregion
    605765
    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();
     766    #region Project Methods
     767    public Guid AddProject(DT.Project projectDto) {
     768      if (projectDto == null || projectDto.Id != Guid.Empty) return Guid.Empty;
     769      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     770      // check if current (non-admin) user is owner of one of projectDto's-parents
     771      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     772      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     773      if (!isAdmin) {
     774        if (projectDto != null && projectDto.ParentProjectId.HasValue) {
     775          AuthorizationManager.AuthorizeForProjectAdministration(projectDto.ParentProjectId.Value, false);
     776        } else {
     777          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     778        }
     779      }
     780
     781      // check that non-admins can not be set as owner of root projects
     782      if (projectDto != null && !projectDto.ParentProjectId.HasValue) {
     783        var owner = UserManager.GetUserById(projectDto.OwnerUserId);
     784        if (owner == null || !RoleVerifier.IsUserInRole(owner.UserName, HiveRoles.Administrator)) {
     785          throw new SecurityException(NOT_AUTHORIZED_PROJECTOWNER);
     786        }
     787      }
     788
     789      var pm = PersistenceManager;
     790      using (new PerformanceLogger("AddProject")) {
     791        var projectDao = pm.ProjectDao;
     792
     793        return pm.UseTransaction(() => {
     794          var project = projectDao.Save(projectDto.ToEntity());
     795
     796          var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     797          bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     798
     799          // if user is no admin, but owner of a parent project
     800          // check start/end date time boundaries of parent projects before updating child project
     801          if (!isAdmin) {
     802            var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     803            if (parentProject != null) {
     804              if (project.StartDate < parentProject.StartDate) project.StartDate = parentProject.StartDate;
     805              if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     806              || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     807                project.EndDate = parentProject.EndDate;
     808            }
     809          }
     810
     811
     812          project.ProjectPermissions.Clear();
     813          project.ProjectPermissions.Add(new DA.ProjectPermission {
     814            GrantedUserId = project.OwnerUserId,
     815            GrantedByUserId = UserManager.CurrentUserId
     816          });
     817
     818          pm.SubmitChanges();
     819          return project.ProjectId;
     820        });
     821      }
     822    }
     823
     824    public void UpdateProject(DT.Project projectDto) {
     825      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     826      // check if current (non-admin) user is owner of the project or the projectDto's-parents
     827      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     828      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     829      if (!isAdmin) {
     830        if (projectDto != null && projectDto.ParentProjectId.HasValue) {
     831          AuthorizationManager.AuthorizeForProjectAdministration(projectDto.Id, false);
     832        } else {
     833          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     834        }
     835      }
     836
     837      // check that non-admins can not be set as owner of root projects
     838      if (projectDto != null && !projectDto.ParentProjectId.HasValue) {
     839        var owner = UserManager.GetUserById(projectDto.OwnerUserId);
     840        if (owner == null || !RoleVerifier.IsUserInRole(owner.UserName, HiveRoles.Administrator)) {
     841          throw new SecurityException(NOT_AUTHORIZED_PROJECTOWNER);
     842        }
     843      }
     844
     845      var pm = PersistenceManager;
     846      using (new PerformanceLogger("UpdateProject")) {
     847        var projectDao = pm.ProjectDao;
     848        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     849        pm.UseTransaction(() => {
     850          var project = projectDao.GetById(projectDto.Id);
     851          if (project != null) { // (1) update existent project
     852            var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     853            bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     854
     855            var formerOwnerId = project.OwnerUserId;
     856            var formerStartDate = project.StartDate;
     857            var formerEndDate = project.EndDate;
     858            projectDto.CopyToEntity(project);
     859
     860            // if user is no admin, but owner of parent project(s)
     861            // check start/end date time boundaries of parent projects before updating child project
     862            if (!isAdmin && isParent) {
     863              var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     864              if (parentProject != null) {
     865                if (project.StartDate < parentProject.StartDate) project.StartDate = formerStartDate;
     866                if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     867                || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     868                  project.EndDate = formerEndDate;
     869              }
     870            }
     871
     872            // if user is admin or owner of parent project(s)
     873            if (isAdmin || isParent) {
     874              // if owner has changed...
     875              if (formerOwnerId != projectDto.OwnerUserId) {
     876                // Add permission for new owner if not already done
     877                if (!project.ProjectPermissions
     878                  .Select(pp => pp.GrantedUserId)
     879                  .Contains(projectDto.OwnerUserId)) {
     880                  project.ProjectPermissions.Add(new DA.ProjectPermission {
     881                    GrantedUserId = projectDto.OwnerUserId,
     882                    GrantedByUserId = UserManager.CurrentUserId
     883                  });
     884                }
     885              }
     886            } else { // if user is only owner of current project, but no admin and no owner of parent project(s)
     887              project.OwnerUserId = formerOwnerId;
     888              project.StartDate = formerStartDate;
     889              project.EndDate = formerEndDate;
     890            }
     891
     892          } else { // (2) save new project
     893            var newProject = projectDao.Save(projectDto.ToEntity());
     894
     895            var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     896            bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     897
     898            // if user is no admin, but owner of a parent project
     899            // check start/end date time boundaries of parent projects before updating child project
     900            if (!isAdmin) {
     901              var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     902              if (parentProject != null) {
     903                if (project.StartDate < parentProject.StartDate) project.StartDate = parentProject.StartDate;
     904                if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     905                || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     906                  project.EndDate = parentProject.EndDate;
     907              }
     908            }
     909
     910            newProject.ProjectPermissions.Clear();
     911            newProject.ProjectPermissions.Add(new DA.ProjectPermission {
     912              GrantedUserId = projectDto.OwnerUserId,
     913              GrantedByUserId = UserManager.CurrentUserId
     914            });
     915          }
     916
     917          pm.SubmitChanges();
     918        });
     919      }
     920    }
     921
     922    public void DeleteProject(Guid projectId) {
     923      if (projectId == Guid.Empty) return;
     924      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     925      // check if current (non-admin) user is owner of one of the projectDto's-parents
     926      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     927      if (!RoleVerifier.IsInRole(HiveRoles.Administrator)) {
     928        AuthorizationManager.AuthorizeForProjectAdministration(projectId, true);
     929      }
     930
     931      var pm = PersistenceManager;
     932      using (new PerformanceLogger("DeleteProject")) {
     933        var projectDao = pm.ProjectDao;
     934        var jobDao = pm.JobDao;
     935        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     936        pm.UseTransaction(() => {
     937          var projectIds = new HashSet<Guid> { projectId };
     938          projectIds.Union(projectDao.GetChildProjectIdsById(projectId));
     939
     940          var jobs = jobDao.GetByProjectIds(projectIds)
     941            .Select(x => x.ToDto())
     942            .ToList();
     943
     944          if (jobs.Count > 0) {
     945            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.");
     946          } else {
     947            assignedJobResourceDao.DeleteByProjectIds(projectIds);
     948            projectDao.DeleteByIds(projectIds);
     949            pm.SubmitChanges();
     950          }
     951        });
     952      }
     953    }
     954
     955    // query granted project for use (i.e. to calculate on)
     956    public DT.Project GetProject(Guid projectId) {
     957      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     958      var pm = PersistenceManager;
     959      using (new PerformanceLogger("GetProject")) {
     960        var projectDao = pm.ProjectDao;
     961        var currentUserId = UserManager.CurrentUserId;
     962        var userAndGroupIds = new List<Guid> { currentUserId };
     963        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     964        return pm.UseTransaction(() => {
     965          return projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     966          .Where(x => x.ProjectId == projectId)
     967          .Select(x => x.ToDto())
     968          .SingleOrDefault();
     969        });
     970      }
     971    }
     972
     973    // query granted projects for use (i.e. to calculate on)
     974    public IEnumerable<DT.Project> GetProjects() {
     975      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     976      var pm = PersistenceManager;
     977      using (new PerformanceLogger("GetProjects")) {
     978        var projectDao = pm.ProjectDao;
     979        var currentUserId = UserManager.CurrentUserId;
     980        var userAndGroupIds = new List<Guid> { currentUserId };
     981        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     982        return pm.UseTransaction(() => {
     983          var projects = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     984            .Select(x => x.ToDto()).ToList();
     985          var now = DateTime.Now;
     986          return projects.Where(x => x.StartDate <= now && (x.EndDate == null || x.EndDate >= now)).ToList();
     987        });
     988      }
     989    }
     990
     991    public IEnumerable<DT.Project> GetProjectsForAdministration() {
     992      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     993      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     994      var pm = PersistenceManager;
     995      using (new PerformanceLogger("GetProjectsForAdministration")) {
     996        var projectDao = pm.ProjectDao;
     997
     998        return pm.UseTransaction(() => {
     999          if (isAdministrator) {
     1000            return projectDao.GetAll().Select(x => x.ToDto()).ToList();
     1001          } else {
     1002            var currentUserId = UserManager.CurrentUserId;
     1003            return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId)
     1004              .Select(x => x.ToDto()).ToList();
     1005
     1006          }
     1007        });
     1008      }
     1009    }
     1010
     1011    public IDictionary<Guid, HashSet<Guid>> GetProjectGenealogy() {
     1012      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1013      var pm = PersistenceManager;
     1014      using (new PerformanceLogger("GetProjectGenealogy")) {
     1015        var projectDao = pm.ProjectDao;
     1016        var projectAncestors = new Dictionary<Guid, HashSet<Guid>>();
     1017        return pm.UseTransaction(() => {
     1018          var projects = projectDao.GetAll().ToList();
     1019          projects.ForEach(p => projectAncestors.Add(p.ProjectId, new HashSet<Guid>()));
     1020          foreach (var p in projects) {
     1021            var parentProject = p.ParentProject;
     1022            while (parentProject != null) {
     1023              projectAncestors[p.ProjectId].Add(parentProject.ProjectId);
     1024              parentProject = parentProject.ParentProject;
     1025            }
     1026          }
     1027          return projectAncestors;
     1028        });
     1029      }
     1030    }
     1031
     1032    public IDictionary<Guid, string> GetProjectNames() {
     1033      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1034      var pm = PersistenceManager;
     1035      using (new PerformanceLogger("GetProjectNames")) {
     1036        var projectDao = pm.ProjectDao;
     1037        var projectNames = new Dictionary<Guid, string>();
     1038        return pm.UseTransaction(() => {
     1039          projectDao
     1040            .GetAll().ToList()
     1041            .ForEach(p => projectNames.Add(p.ProjectId, p.Name));
     1042          return projectNames;
     1043        });
     1044      }
     1045    }
     1046    #endregion
     1047
     1048    #region ProjectPermission Methods
     1049    public void SaveProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool reassign, bool cascading, bool reassignCascading) {
     1050      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1051      if (projectId == null || grantedUserIds == null) return;
     1052      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1053      var pm = PersistenceManager;
     1054      using (new PerformanceLogger("SaveProjectPermissions")) {
     1055        var projectDao = pm.ProjectDao;
     1056        var projectPermissionDao = pm.ProjectPermissionDao;
     1057        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1058
     1059        pm.UseTransaction(() => {
     1060          var project = projectDao.GetById(projectId);
     1061          if (project == null) return;
     1062          var projectPermissions = project.ProjectPermissions.Select(x => x.GrantedUserId).ToArray();
     1063
     1064          // guarantee that project owner is always permitted
     1065          if (!grantedUserIds.Contains(project.OwnerUserId)) {
     1066            grantedUserIds.Add(project.OwnerUserId);
     1067          }
     1068
     1069          //var addedPermissions = grantedUserIds.Except(projectPermissions);
     1070          var removedPermissions = projectPermissions.Except(grantedUserIds);
     1071
     1072          // remove job assignments and project permissions
     1073          if (reassign) {
     1074            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
     1075            project.ProjectPermissions.Clear();
     1076          } else {
     1077
     1078            var ugt = GetUserGroupTree();
     1079            var permittedGuids = new HashSet<Guid>(); // User- and Group-Guids
     1080            var notpermittedGuids = new HashSet<Guid>();
     1081
     1082            // remove job assignments:
     1083            // (1) get all member-Guids of all still or fresh permitted user/groups
     1084            foreach (var item in grantedUserIds) {
     1085              permittedGuids.Add(item);
     1086              if (ugt.ContainsKey(item)) {
     1087                ugt[item].ToList().ForEach(x => permittedGuids.Add(x));
     1088              }
     1089            }
     1090
     1091            // (2) get all member-Guids of users and groups in removedPermissions
     1092            foreach (var item in removedPermissions) {
     1093              notpermittedGuids.Add(item);
     1094              if (ugt.ContainsKey(item)) {
     1095                ugt[item].ToList().ForEach(x => notpermittedGuids.Add(x));
     1096              }
     1097            }
     1098
     1099            // (3) get all Guids which are in removedPermissions but not in grantedUserIds
     1100            var definitelyNotPermittedGuids = notpermittedGuids.Except(permittedGuids);
     1101
     1102            // (4) delete jobs of those
     1103            assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, definitelyNotPermittedGuids);
     1104
     1105
     1106            // remove project permissions
     1107            foreach (var item in project.ProjectPermissions
     1108              .Where(x => removedPermissions.Contains(x.GrantedUserId))
     1109              .ToList()) {
     1110              project.ProjectPermissions.Remove(item);
     1111            }
     1112          }
     1113          pm.SubmitChanges();
     1114
     1115          // add project permissions
    6141116          foreach (var id in grantedUserIds) {
    615             if (resourcePermissions.All(x => x.GrantedUserId != id)) {
    616               resource.ResourcePermissions.Add(new DA.ResourcePermission {
     1117            if (project.ProjectPermissions.All(x => x.GrantedUserId != id)) {
     1118              project.ProjectPermissions.Add(new DA.ProjectPermission {
    6171119                GrantedUserId = id,
    6181120                GrantedByUserId = UserManager.CurrentUserId
     
    6211123          }
    6221124          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)
     1125
     1126          if (cascading) {
     1127            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
     1128            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
     1129
     1130            // remove job assignments
     1131            if (reassignCascading) {
     1132              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
     1133            } else {
     1134              assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, removedPermissions);
     1135            }
     1136
     1137            foreach (var p in childProjects) {
     1138              var cpAssignedPermissions = p.ProjectPermissions.Select(x => x.GrantedUserId).ToList();
     1139              // guarantee that project owner is always permitted
     1140              if (!cpAssignedPermissions.Contains(p.OwnerUserId)) {
     1141                cpAssignedPermissions.Add(p.OwnerUserId);
     1142              }
     1143              var cpRemovedPermissions = cpAssignedPermissions.Where(x => x != p.OwnerUserId).Except(grantedUserIds);
     1144
     1145              // remove left-over job assignments (for non-reassignments)
     1146              if (!reassignCascading) {
     1147                assignedJobResourceDao.DeleteByProjectIdAndUserIds(p.ProjectId, cpRemovedPermissions);
     1148              }
     1149
     1150              // remove project permissions
     1151              if (reassignCascading) {
     1152                p.ProjectPermissions.Clear();
     1153              } else {
     1154                foreach (var item in p.ProjectPermissions
     1155                  .Where(x => x.GrantedUserId != p.OwnerUserId
     1156                    && (removedPermissions.Contains(x.GrantedUserId) || cpRemovedPermissions.Contains(x.GrantedUserId)))
     1157                  .ToList()) {
     1158                  p.ProjectPermissions.Remove(item);
     1159                }
     1160              }
     1161              pm.SubmitChanges();
     1162
     1163              // add project permissions
     1164              var cpGrantedUserIds = new HashSet<Guid>(grantedUserIds);
     1165              cpGrantedUserIds.Add(p.OwnerUserId);
     1166
     1167              foreach (var id in cpGrantedUserIds) {
     1168                if (p.ProjectPermissions.All(x => x.GrantedUserId != id)) {
     1169                  p.ProjectPermissions.Add(new DA.ProjectPermission {
     1170                    GrantedUserId = id,
     1171                    GrantedByUserId = UserManager.CurrentUserId
     1172                  });
     1173                }
     1174              }
     1175            }
     1176          }
     1177          pm.SubmitChanges();
     1178        });
     1179      }
     1180    }
     1181
     1182    //private void GrantProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
     1183    //  throw new NotImplementedException();
     1184    //}
     1185
     1186    //private void RevokeProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
     1187    //  RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1188    //  if (projectId == null || grantedUserIds == null || !grantedUserIds.Any()) return;
     1189    //  AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1190    //  var pm = PersistenceManager;
     1191    //  using (new PerformanceLogger("RevokeProjectPermissions")) {
     1192    //    var projectPermissionDao = pm.ProjectPermissionDao;
     1193    //    var projectDao = pm.ProjectDao;
     1194    //    var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1195    //    pm.UseTransaction(() => {
     1196    //      if (cascading) {
     1197    //        var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
     1198    //        projectPermissionDao.DeleteByProjectIdsAndGrantedUserIds(childProjectIds, grantedUserIds);
     1199    //        assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, grantedUserIds);
     1200    //      }
     1201    //      projectPermissionDao.DeleteByProjectIdAndGrantedUserIds(projectId, grantedUserIds);
     1202    //      assignedJobResourceDao.DeleteByProjectIdAndUserIds(projectId, grantedUserIds);
     1203    //      pm.SubmitChanges();
     1204    //    });
     1205    //  }
     1206    //}
     1207
     1208    public IEnumerable<DT.ProjectPermission> GetProjectPermissions(Guid projectId) {
     1209      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1210      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1211      var pm = PersistenceManager;
     1212      using (new PerformanceLogger("GetProjectPermissions")) {
     1213        var projectPermissionDao = pm.ProjectPermissionDao;
     1214        return pm.UseTransaction(() => projectPermissionDao.GetByProjectId(projectId)
    6461215          .Select(x => x.ToDto())
    6471216          .ToList()
     
    6511220    #endregion
    6521221
     1222    #region AssignedProjectResource Methods
     1223    // basic: remove and add assignments (resourceIds) to projectId and its depending jobs
     1224    // reassign: clear all assignments from project and its depending jobs, before adding new ones (resourceIds)
     1225    // cascading: "basic" mode for child-projects
     1226    // reassignCascading: "reassign" mode for child-projects
     1227    public void SaveProjectResourceAssignments(Guid projectId, List<Guid> resourceIds, bool reassign, bool cascading, bool reassignCascading) {
     1228      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1229      if (projectId == null || resourceIds == null) return;
     1230      AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
     1231      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1232      var pm = PersistenceManager;
     1233      using (new PerformanceLogger("SaveProjectResourceAssignments")) {
     1234        var projectDao = pm.ProjectDao;
     1235        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1236        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1237        pm.UseTransaction(() => {
     1238          var project = projectDao.GetById(projectId);
     1239
     1240          var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     1241          bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     1242
     1243          var assignedResources = project.AssignedProjectResources.Select(x => x.ResourceId).ToArray();
     1244          if (!isParent) resourceIds = assignedResources.ToList();
     1245          var removedAssignments = assignedResources.Except(resourceIds);
     1246
     1247          // if user is admin or owner of parent project(s)
     1248          if (isAdmin || isParent) {
     1249            // remove job and project assignments
     1250            if (reassign) {
     1251              assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
     1252              project.AssignedProjectResources.Clear();
     1253            } else {
     1254              assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, removedAssignments);
     1255              foreach (var item in project.AssignedProjectResources
     1256                .Where(x => removedAssignments.Contains(x.ResourceId))
     1257                .ToList()) {
     1258                project.AssignedProjectResources.Remove(item);
     1259              }
     1260            }
     1261            pm.SubmitChanges();
     1262
     1263            // add project assignments
     1264            foreach (var id in resourceIds) {
     1265              if (project.AssignedProjectResources.All(x => x.ResourceId != id)) {
     1266                project.AssignedProjectResources.Add(new DA.AssignedProjectResource {
     1267                  ResourceId = id
     1268                });
     1269              }
     1270            }
     1271            pm.SubmitChanges();
     1272          }
     1273
     1274          // if user is admin, project owner or owner of parent projects
     1275          if (cascading) {
     1276            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
     1277            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
     1278
     1279            // remove job assignments
     1280            if (reassignCascading) {
     1281              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
     1282            } else {
     1283              assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, removedAssignments);
     1284            }
     1285            foreach (var p in childProjects) {
     1286              var cpAssignedResources = p.AssignedProjectResources.Select(x => x.ResourceId).ToArray();
     1287              var cpRemovedAssignments = cpAssignedResources.Except(resourceIds);
     1288
     1289              // remove left-over job assignments (for non-reassignments)
     1290              if (!reassignCascading) {
     1291                assignedJobResourceDao.DeleteByProjectIdAndResourceIds(p.ProjectId, cpRemovedAssignments);
     1292              }
     1293
     1294              // remove project assignments
     1295              if (reassignCascading) {
     1296                p.AssignedProjectResources.Clear();
     1297              } else {
     1298                foreach (var item in p.AssignedProjectResources
     1299                  .Where(x => removedAssignments.Contains(x.ResourceId) || cpRemovedAssignments.Contains(x.ResourceId))
     1300                  .ToList()) {
     1301                  p.AssignedProjectResources.Remove(item);
     1302                }
     1303              }
     1304              pm.SubmitChanges();
     1305
     1306              // add project assignments
     1307              foreach (var id in resourceIds) {
     1308                if (p.AssignedProjectResources.All(x => x.ResourceId != id)) {
     1309                  p.AssignedProjectResources.Add(new DA.AssignedProjectResource {
     1310                    ResourceId = id
     1311                  });
     1312                }
     1313              }
     1314            }
     1315          }
     1316          pm.SubmitChanges();
     1317        });
     1318      }
     1319    }
     1320
     1321    //private void AssignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
     1322    //  throw new NotImplementedException();
     1323    //}
     1324
     1325    //private void UnassignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
     1326    //  RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1327    //  if (projectId == null || resourceIds == null || !resourceIds.Any()) return;
     1328    //  AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
     1329    //  var pm = PersistenceManager;
     1330    //  using (new PerformanceLogger("UnassignProjectResources")) {
     1331    //    var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1332    //    var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1333    //    var projectDao = pm.ProjectDao;
     1334    //    pm.UseTransaction(() => {
     1335    //      if (cascading) {
     1336    //        var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
     1337    //        assignedProjectResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
     1338    //        assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
     1339    //      }
     1340    //      assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
     1341    //      assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
     1342    //      pm.SubmitChanges();
     1343    //    });
     1344    //  }
     1345    //}
     1346
     1347    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProject(Guid projectId) {
     1348      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1349      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, projectId);
     1350      var pm = PersistenceManager;
     1351      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1352        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1353        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
     1354          .Select(x => x.ToDto())
     1355          .ToList()
     1356        );
     1357      }
     1358    }
     1359
     1360    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectAdministration(Guid projectId) {
     1361      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1362      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1363      var pm = PersistenceManager;
     1364      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1365        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1366        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
     1367          .Select(x => x.ToDto())
     1368          .ToList()
     1369        );
     1370      }
     1371    }
     1372
     1373    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectsAdministration(IEnumerable<Guid> projectIds) {
     1374      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1375      foreach (var id in projectIds)
     1376        AuthorizationManager.AuthorizeForProjectAdministration(id, false);
     1377
     1378      var pm = PersistenceManager;
     1379      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1380        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1381        var assignments = new List<DT.AssignedProjectResource>();
     1382        pm.UseTransaction(() => {
     1383          foreach (var id in projectIds) {
     1384            assignments.AddRange(assignedProjectResourceDao.GetByProjectId(id)
     1385              .Select(x => x.ToDto()));
     1386          }
     1387        });
     1388        return assignments.Distinct();
     1389      }
     1390    }
     1391
     1392    #endregion
     1393
    6531394    #region Slave Methods
    6541395    public Guid AddSlave(DT.Slave slaveDto) {
     
    6661407
    6671408    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
    668       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1409      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
    6691410      var pm = PersistenceManager;
    6701411      using (new PerformanceLogger("AddSlaveGroup")) {
     
    6901431    }
    6911432
     1433    // query granted slaves for use (i.e. to calculate on)
    6921434    public IEnumerable<DT.Slave> GetSlaves() {
    6931435      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    694       bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
    6951436      var pm = PersistenceManager;
    6961437      using (new PerformanceLogger("GetSlaves")) {
    6971438        var slaveDao = pm.SlaveDao;
    698         var resourcePermissionDao = pm.ResourcePermissionDao;
     1439        var projectDao = pm.ProjectDao;
     1440        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1441
     1442        // collect user information
    6991443        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               )
     1444        var userAndGroupIds = new List<Guid> { currentUserId };
     1445        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     1446
     1447        return pm.UseTransaction(() => {
     1448          var slaves = slaveDao.GetAll()
    7111449            .Select(x => x.ToDto())
    7121450            .ToList();
    713         });
    714       }
    715     }
    716 
     1451          var grantedProjectIds = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     1452            .Select(x => x.ProjectId)
     1453            .ToList();
     1454          var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourcesByProjectIds(grantedProjectIds)
     1455            .Select(x => x.ResourceId)
     1456            .ToList();
     1457
     1458          return slaves
     1459            .Where(x => grantedResourceIds.Contains(x.Id))
     1460            .ToList();
     1461        });
     1462      }
     1463    }
     1464
     1465    // query granted slave groups for use (i.e. to calculate on)
    7171466    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
    7181467      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    719       bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
    7201468      var pm = PersistenceManager;
    7211469      using (new PerformanceLogger("GetSlaveGroups")) {
    7221470        var slaveGroupDao = pm.SlaveGroupDao;
    723         var resourcePermissionDao = pm.ResourcePermissionDao;
     1471        var projectDao = pm.ProjectDao;
     1472        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1473
     1474        // collect user information
    7241475        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               )
     1476        var userAndGroupIds = new List<Guid> { currentUserId };
     1477        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     1478
     1479        return pm.UseTransaction(() => {
     1480          var slaveGroups = slaveGroupDao.GetAll()
    7361481            .Select(x => x.ToDto())
    7371482            .ToList();
     1483          var grantedProjectIds = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     1484            .Select(x => x.ProjectId)
     1485            .ToList();
     1486          var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourcesByProjectIds(grantedProjectIds)
     1487            .Select(x => x.ResourceId)
     1488            .ToList();
     1489
     1490          return slaveGroups
     1491            .Where(x => grantedResourceIds.Contains(x.Id))
     1492            .ToList();
     1493        });
     1494      }
     1495    }
     1496
     1497    // query granted slaves for resource administration
     1498    public IEnumerable<DT.Slave> GetSlavesForAdministration() {
     1499      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1500      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1501      var pm = PersistenceManager;
     1502      using (new PerformanceLogger("GetSlavesForAdministration")) {
     1503        var slaveDao = pm.SlaveDao;
     1504        var currentUserId = UserManager.CurrentUserId;
     1505
     1506        if (isAdministrator) {
     1507          return pm.UseTransaction(() => {
     1508            return slaveDao.GetAll()
     1509              .Select(x => x.ToDto())
     1510              .ToList();
     1511          });
     1512        } else {
     1513          var slaves = slaveDao.GetAll()
     1514            .Select(x => x.ToDto())
     1515            .ToList();
     1516          var projectDao = pm.ProjectDao;
     1517          var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1518          var projects = projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).ToList();
     1519          var resourceIds = assignedProjectResourceDao
     1520            .GetAllGrantedResourcesByProjectIds(projects.Select(x => x.ProjectId).ToList())
     1521            .Select(x => x.ResourceId)
     1522            .ToList();
     1523
     1524          return slaves
     1525            .Where(x => resourceIds.Contains(x.Id))
     1526            .ToList();
     1527        }
     1528      }
     1529    }
     1530
     1531    // query granted slave groups for resource administration
     1532    public IEnumerable<DT.SlaveGroup> GetSlaveGroupsForAdministration() {
     1533      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1534      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1535      var pm = PersistenceManager;
     1536      using (new PerformanceLogger("GetSlaveGroupsForAdministration")) {
     1537        var slaveGroupDao = pm.SlaveGroupDao;
     1538        var currentUserId = UserManager.CurrentUserId;
     1539
     1540        if (isAdministrator) {
     1541          return pm.UseTransaction(() => {
     1542            return slaveGroupDao.GetAll()
     1543              .Select(x => x.ToDto())
     1544              .ToList();
     1545          });
     1546        } else {
     1547          var slaveGroups = slaveGroupDao.GetAll()
     1548            .Select(x => x.ToDto())
     1549            .ToList();
     1550          var projectDao = pm.ProjectDao;
     1551          var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1552          var projects = projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).ToList();
     1553          var resourceIds = assignedProjectResourceDao
     1554            .GetAllGrantedResourcesByProjectIds(projects.Select(x => x.ProjectId).ToList())
     1555            .Select(x => x.ResourceId)
     1556            .ToList();
     1557
     1558          return slaveGroups
     1559            .Where(x => resourceIds.Contains(x.Id))
     1560            .ToList();
     1561        }
     1562      }
     1563    }
     1564
     1565    public IDictionary<Guid, HashSet<Guid>> GetResourceGenealogy() {
     1566      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1567      var pm = PersistenceManager;
     1568      using (new PerformanceLogger("GetResourceGenealogy")) {
     1569        var resourceDao = pm.ResourceDao;
     1570        var resourceAncestors = new Dictionary<Guid, HashSet<Guid>>();
     1571        return pm.UseTransaction(() => {
     1572          var resources = resourceDao.GetAll().ToList();
     1573          resources.ForEach(r => resourceAncestors.Add(r.ResourceId, new HashSet<Guid>()));
     1574
     1575          foreach (var r in resources) {
     1576            var parentResource = r.ParentResource;
     1577            while (parentResource != null) {
     1578              resourceAncestors[r.ResourceId].Add(parentResource.ResourceId);
     1579              parentResource = parentResource.ParentResource;
     1580            }
     1581          }
     1582          return resourceAncestors;
     1583        });
     1584      }
     1585    }
     1586
     1587    public IDictionary<Guid, string> GetResourceNames() {
     1588      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1589      var pm = PersistenceManager;
     1590      using (new PerformanceLogger("GetResourceNames")) {
     1591        var resourceDao = pm.ResourceDao;
     1592        var resourceNames = new Dictionary<Guid, string>();
     1593        return pm.UseTransaction(() => {
     1594          resourceDao
     1595            .GetAll().ToList()
     1596            .ForEach(p => resourceNames.Add(p.ResourceId, p.Name));
     1597          return resourceNames;
    7381598        });
    7391599      }
     
    7421602    public void UpdateSlave(DT.Slave slaveDto) {
    7431603      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1604      if (slaveDto == null) return;
     1605      AuthorizationManager.AuthorizeForResourceAdministration(slaveDto.Id);
    7441606      var pm = PersistenceManager;
    7451607      using (new PerformanceLogger("UpdateSlave")) {
     
    7591621    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
    7601622      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1623      if (slaveGroupDto == null) return;
     1624      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupDto.Id);
    7611625      var pm = PersistenceManager;
    7621626      using (new PerformanceLogger("UpdateSlaveGroup")) {
     
    7751639
    7761640    public void DeleteSlave(Guid slaveId) {
     1641      if (slaveId == Guid.Empty) return;
    7771642      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    7781643      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
     
    7881653
    7891654    public void DeleteSlaveGroup(Guid slaveGroupId) {
     1655      if (slaveGroupId == Guid.Empty) return;
    7901656      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    7911657      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
    7921658      var pm = PersistenceManager;
    7931659      using (new PerformanceLogger("DeleteSlaveGroup")) {
    794         var slaveGroupDao = pm.SlaveGroupDao;
    795         pm.UseTransaction(() => {
    796           slaveGroupDao.Delete(slaveGroupId);
     1660        var resourceDao = pm.ResourceDao;
     1661        pm.UseTransaction(() => {
     1662          var resourceIds = new HashSet<Guid> { slaveGroupId };
     1663          resourceIds.Union(resourceDao.GetChildResourceIdsById(slaveGroupId));
     1664          resourceDao.DeleteByIds(resourceIds);
    7971665          pm.SubmitChanges();
    7981666        });
     
    9461814      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
    9471815      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
     1816    }
     1817
     1818    public Dictionary<Guid, HashSet<Guid>> GetUserGroupTree() {
     1819      var userGroupTree = new Dictionary<Guid, HashSet<Guid>>();
     1820      var userGroupMapping = UserManager.GetUserGroupMapping();
     1821
     1822      foreach (var ugm in userGroupMapping) {
     1823        if (ugm.Parent == null || ugm.Child == null) continue;
     1824
     1825        if (!userGroupTree.ContainsKey(ugm.Parent)) {
     1826          userGroupTree.Add(ugm.Parent, new HashSet<Guid>());
     1827        }
     1828        userGroupTree[ugm.Parent].Add(ugm.Child);
     1829      }
     1830
     1831      return userGroupTree;
     1832    }
     1833
     1834    public bool CheckAccessToAdminAreaGranted() {
     1835      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1836      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1837      var pm = PersistenceManager;
     1838      using (new PerformanceLogger("CheckAccessToAdminAreaGranted")) {
     1839        if (isAdministrator) {
     1840          return true;
     1841        } else {
     1842          var projectDao = pm.ProjectDao;
     1843          var currentUserId = UserManager.CurrentUserId;
     1844          return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).Any();
     1845        }
     1846      }
    9481847    }
    9491848    #endregion
     
    9901889    }
    9911890
    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;
     1891    private void CheckProjectAvailability(IPersistenceManager pm, Guid projectId, DateTime date) {
     1892      var projectDao = pm.ProjectDao;
     1893      using (new PerformanceLogger("UpdateJob")) {
     1894        var project = pm.UseTransaction(() => {
     1895          return projectDao.GetById(projectId);
     1896        });
     1897        if (project != null) {
     1898          if (project.StartDate > date) throw new ArgumentException("Cannot add job to specified project. The start date of the project is still in the future.");
     1899          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.");
     1900        } else {
     1901          throw new ArgumentException("Cannot add job to specified project. The project seems not to be available anymore.");
     1902        }
     1903      }
     1904    }
     1905
     1906    private void EvaluateJobs(IPersistenceManager pm, IEnumerable<DT.Job> jobs) {
     1907      if (jobs == null || !jobs.Any()) return;
     1908
     1909      var currentUserId = UserManager.CurrentUserId;
     1910      var taskDao = pm.TaskDao;
     1911      var jobPermissionDao = pm.JobPermissionDao;
     1912
     1913      var statistics = taskDao.GetAll()
     1914        .Where(x => jobs.Select(y => y.Id).Contains(x.JobId))
     1915        .GroupBy(x => x.JobId)
     1916        .Select(x => new {
     1917          x.Key,
     1918          TotalCount = x.Count(),
     1919          CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
     1920          FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
     1921        })
     1922        .ToList();
     1923
     1924      foreach (var job in jobs) {
     1925        var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
     1926        if (statistic != null) {
     1927          job.JobCount = statistic.TotalCount;
     1928          job.CalculatingCount = statistic.CalculatingCount;
     1929          job.FinishedCount = statistic.FinishedCount;
     1930        }
     1931
     1932        job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
     1933
     1934        if (currentUserId == job.OwnerUserId) {
     1935          job.Permission = Permission.Full;
     1936        } else {
     1937          var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
     1938          job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
     1939        }
     1940      }
    10011941    }
    10021942    #endregion
  • branches/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/HiveStatisticsGenerator.cs

    r15583 r16139  
    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/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/Interfaces/IAuthorizationManager.cs

    r15583 r16139  
    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/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs

    r15583 r16139  
    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 TASK_NOT_EXISTENT = "Queried task could not be found";
     41    private const string PROJECT_NOT_EXISTENT = "Queried project could not be found";
     42
    3543    private IPersistenceManager PersistenceManager {
    3644      get { return ServiceLocator.Instance.PersistenceManager; }
     
    4755    public void Authorize(Guid userId) {
    4856      if (userId != ServiceLocator.Instance.UserManager.CurrentUserId)
    49         throw new SecurityException(NOT_AUTHORIZED);
     57        throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
    5058    }
    5159
     
    5664      pm.UseTransaction(() => {
    5765        var task = taskDao.GetById(taskId);
    58         if (task == null) throw new SecurityException(NOT_AUTHORIZED);
     66        if (task == null) throw new SecurityException(TASK_NOT_EXISTENT);
    5967        AuthorizeJob(pm, task.JobId, requiredPermission);
    6068      });
     
    6876    }
    6977
     78    // authorize if user is admin or resource owner
    7079    public void AuthorizeForResourceAdministration(Guid resourceId) {
     80      var currentUserId = UserManager.CurrentUserId;
    7181      var pm = PersistenceManager;
    7282      var resourceDao = pm.ResourceDao;
    7383      pm.UseTransaction(() => {
    7484        var resource = resourceDao.GetById(resourceId);
    75         if (resource == null) throw new SecurityException(NOT_AUTHORIZED);
    76         if (resource.OwnerUserId != UserManager.CurrentUserId
     85        if (resource == null) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     86
     87        if (resource.OwnerUserId != currentUserId
    7788            && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
    78           throw new SecurityException(NOT_AUTHORIZED);
    79         }
    80       });
     89          throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     90        }
     91      });
     92    }
     93
     94    // authorize if user is admin, project owner or owner of a parent project
     95    public void AuthorizeForProjectAdministration(Guid projectId, bool parentalOwnership) {
     96      if (projectId == null || projectId == Guid.Empty) return;
     97      var currentUserId = UserManager.CurrentUserId;
     98      var pm = PersistenceManager;
     99      var projectDao = pm.ProjectDao;
     100      pm.UseTransaction(() => {
     101        var project = projectDao.GetById(projectId);
     102        if (project == null) throw new ArgumentException(PROJECT_NOT_EXISTENT);
     103        if(!RoleVerifier.IsInRole(HiveRoles.Administrator)
     104          && !project.ParentProjectId.HasValue) {
     105          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     106        }
     107
     108        List<Project> projectBranch = null;
     109        if(parentalOwnership) projectBranch = projectDao.GetParentProjectsById(projectId).ToList();
     110        else projectBranch = projectDao.GetCurrentAndParentProjectsById(projectId).ToList();
     111
     112        if(!RoleVerifier.IsInRole(HiveRoles.Administrator)
     113            && !projectBranch.Select(x => x.OwnerUserId).Contains(currentUserId)) {
     114          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     115        }
     116      });
     117    }
     118
     119    // authorize if user is admin, or owner of a project or parent project, for which the resources are assigned to
     120    public void AuthorizeForProjectResourceAdministration(Guid projectId, IEnumerable<Guid> resourceIds) {
     121      if (projectId == null || projectId == Guid.Empty) return;
     122      var currentUserId = UserManager.CurrentUserId;
     123      var pm = PersistenceManager;
     124      var projectDao = pm.ProjectDao;
     125      var resourceDao = pm.ResourceDao;
     126      var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     127      pm.UseTransaction(() => {
     128        // check if project exists (not necessary)
     129        var project = projectDao.GetById(projectId);
     130        if (project == null) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     131
     132        // check if resourceIds exist
     133        if (resourceIds != null && resourceIds.Any() && !resourceDao.CheckExistence(resourceIds))
     134          throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     135
     136        // check if user is admin
     137        if (RoleVerifier.IsInRole(HiveRoles.Administrator)) return;
     138
     139        // check if user is owner of the project or a parent project
     140        var projectBranch = projectDao.GetCurrentAndParentProjectsById(projectId).ToList();
     141        if (!projectBranch.Select(x => x.OwnerUserId).Contains(currentUserId)
     142            && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
     143          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     144        }
     145
     146        // check if the all argument resourceIds are among the assigned resources of the owned projects
     147        var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourceIdsOfOwnedParentProjects(projectId, currentUserId).ToList();
     148        if(resourceIds.Except(grantedResourceIds).Any()) {
     149          throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     150        }
     151      });
     152    }
     153
     154    // Check if a project is authorized to use a list of resources
     155    public void AuthorizeProjectForResourcesUse(Guid projectId, IEnumerable<Guid> resourceIds) {
     156      if (projectId == null || projectId == Guid.Empty || resourceIds == null || !resourceIds.Any()) return;
     157      var pm = PersistenceManager;
     158      var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     159      if (!assignedProjectResourceDao.CheckProjectGrantedForResources(projectId, resourceIds))
     160        throw new SecurityException(NOT_AUTHORIZED_PROJECTRESOURCE);
     161    }
     162
     163    // Check if current user is authorized to use an explicit project (e.g. in order to add a job)
     164    // note: administrators and project owner are NOT automatically granted
     165    public void AuthorizeUserForProjectUse(Guid userId, Guid projectId) {
     166      if(userId == null || userId == Guid.Empty) {
     167        throw new SecurityException(USER_NOT_IDENTIFIED);
     168      }
     169      if(projectId == null) return;
     170
     171      var pm = PersistenceManager;
     172      // collect current and group membership Ids
     173      var userAndGroupIds = new List<Guid>() { userId };
     174      userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(userId));
     175      // perform the actual check
     176      var projectPermissionDao = pm.ProjectPermissionDao;
     177      if (!projectPermissionDao.CheckUserGrantedForProject(projectId, userAndGroupIds)) {
     178        throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     179      }
    81180    }
    82181
     
    93192
    94193    private void AuthorizeJob(IPersistenceManager pm, Guid jobId, DT.Permission requiredPermission) {
     194      var currentUserId = UserManager.CurrentUserId;
    95195      var requiredPermissionEntity = requiredPermission.ToEntity();
    96       DA.Permission permission = GetPermissionForJob(pm, jobId, UserManager.CurrentUserId);
     196      DA.Permission permission = GetPermissionForJob(pm, jobId, currentUserId);
    97197      if (permission == Permission.NotAllowed
    98198          || ((permission != requiredPermissionEntity) && requiredPermissionEntity == Permission.Full)) {
    99         throw new SecurityException(NOT_AUTHORIZED);
     199        throw new SecurityException(NOT_AUTHORIZED_USERJOB);
    100200      }
    101201    }
  • branches/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs

    r15583 r16139  
    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/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs

    r15583 r16139  
    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/2931_OR-Tools_LP_MIP/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs

    r15583 r16139  
    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.