Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2839_HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 15978

Last change on this file since 15978 was 15978, checked in by jzenisek, 6 years ago

#2839: applied several fixes:

  • show full project-path in project/resource selector
  • handle lost of project-ownership by not withdrawing permissions
  • update automatically after hand-down save
  • lock jobs for which statistics/deletion is pending
  • lock the disabled checkbox in ProjectResourcesView...
File size: 75.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Security;
26using System.ServiceModel;
27using HeuristicLab.Services.Access;
28using HeuristicLab.Services.Hive.DataAccess.Interfaces;
29using HeuristicLab.Services.Hive.DataTransfer;
30using HeuristicLab.Services.Hive.Manager;
31using HeuristicLab.Services.Hive.ServiceContracts;
32using DA = HeuristicLab.Services.Hive.DataAccess;
33using DT = HeuristicLab.Services.Hive.DataTransfer;
34
35namespace HeuristicLab.Services.Hive {
36  /// <summary>
37  /// Implementation of the Hive service (interface <see cref="IHiveService"/>).
38  /// We need 'IgnoreExtensionDataObject' Attribute for the slave to work.
39  /// </summary>
40  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
41  [HiveOperationContextBehavior]
42  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 NO_JOB_UPDATE_POSSIBLE = "This job has already been flagged for deletion, thus, it can not be updated anymore.";
46
47    private static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
48
49    private IPersistenceManager PersistenceManager {
50      get { return ServiceLocator.Instance.PersistenceManager; }
51    }
52
53    private IUserManager UserManager {
54      get { return ServiceLocator.Instance.UserManager; }
55    }
56
57    private IRoleVerifier RoleVerifier {
58      get { return ServiceLocator.Instance.RoleVerifier; }
59    }
60
61    private IAuthorizationManager AuthorizationManager {
62      get { return ServiceLocator.Instance.AuthorizationManager; }
63    }
64    private IEventManager EventManager {
65      get { return ServiceLocator.Instance.EventManager; }
66    }
67    private HeartbeatManager HeartbeatManager {
68      get { return ServiceLocator.Instance.HeartbeatManager; }
69    }
70
71    #region Task Methods
72
73    public Guid AddTask(DT.Task task, DT.TaskData taskData) {
74      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
75      AuthorizationManager.AuthorizeForJob(task.JobId, DT.Permission.Full);
76      var pm = PersistenceManager;
77      using (new PerformanceLogger("AddTask")) {
78        var taskDao = pm.TaskDao;
79        var stateLogDao = pm.StateLogDao;
80        var newTask = task.ToEntity();
81        newTask.JobData = taskData.ToEntity();
82        newTask.JobData.LastUpdate = DateTime.Now;
83        newTask.State = DA.TaskState.Waiting;
84        return pm.UseTransaction(() => {
85          taskDao.Save(newTask);
86          pm.SubmitChanges();
87          stateLogDao.Save(new DA.StateLog {
88            State = DA.TaskState.Waiting,
89            DateTime = DateTime.Now,
90            TaskId = newTask.TaskId,
91            UserId = UserManager.CurrentUserId,
92            SlaveId = null,
93            Exception = null
94          });
95          pm.SubmitChanges();
96          return newTask.TaskId;
97        }, false, true);
98      }
99    }
100
101    public Guid AddChildTask(Guid parentTaskId, DT.Task task, DT.TaskData taskData) {
102      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
103      task.ParentTaskId = parentTaskId;
104      return AddTask(task, taskData);
105    }
106
107    public DT.Task GetTask(Guid taskId) {
108      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
109      AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
110      var pm = PersistenceManager;
111      using (new PerformanceLogger("GetTask")) {
112        var taskDao = pm.TaskDao;
113        return pm.UseTransaction(() => {
114          var task = taskDao.GetById(taskId);
115          return task.ToDto();
116        });
117      }
118    }
119
120    public IEnumerable<DT.LightweightTask> GetLightweightJobTasks(Guid jobId) {
121      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
122      AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
123      var pm = PersistenceManager;
124      using (new PerformanceLogger("GetLightweightJobTasks")) {
125        var taskDao = pm.TaskDao;
126        return pm.UseTransaction(() => {
127          return taskDao.GetByJobId(jobId)
128            .ToList()
129            .Select(x => new DT.LightweightTask {
130              Id = x.TaskId,
131              ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
132              ParentTaskId = x.ParentTaskId,
133              StateLog = x.StateLogs.OrderBy(y => y.DateTime)
134                                    .Select(z => z.ToDto())
135                                    .ToList(),
136              State = x.State.ToDto(),
137              Command = x.Command.ToDto(),
138              LastTaskDataUpdate = x.JobData.LastUpdate
139            })
140            .ToList();
141        }, false, true);
142      }
143    }
144
145    public IEnumerable<DT.LightweightTask> GetLightweightJobTasksWithoutStateLog(Guid jobId) {
146      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
147      AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
148      var pm = PersistenceManager;
149      using (new PerformanceLogger("GetLightweightJobTasksWithoutStateLog")) {
150        var taskDao = pm.TaskDao;
151        return pm.UseTransaction(() => {
152          return taskDao.GetByJobId(jobId)
153            .ToList()
154            .Select(x => new DT.LightweightTask {
155              Id = x.TaskId,
156              ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
157              ParentTaskId = x.ParentTaskId,
158              StateLog = new List<DT.StateLog>(),
159              State = x.State.ToDto(),
160              Command = x.Command.ToDto(),
161              LastTaskDataUpdate = x.JobData.LastUpdate
162            })
163            .ToList();
164        }, false, true);
165      }
166    }
167
168    public DT.TaskData GetTaskData(Guid taskId) {
169      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
170      AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
171      var pm = PersistenceManager;
172      using (new PerformanceLogger("GetTaskData")) {
173        var taskDataDao = pm.TaskDataDao;
174        return pm.UseTransaction(() => taskDataDao.GetById(taskId).ToDto());
175      }
176    }
177
178    public void UpdateTask(DT.Task taskDto) {
179      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
180      AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
181      var pm = PersistenceManager;
182      using (new PerformanceLogger("UpdateTask")) {
183        var taskDao = pm.TaskDao;
184        pm.UseTransaction(() => {
185          var task = taskDao.GetById(taskDto.Id);
186          taskDto.CopyToEntity(task);
187          pm.SubmitChanges();
188        });
189      }
190    }
191
192    public void UpdateTaskData(DT.Task taskDto, DT.TaskData taskDataDto) {
193      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
194      AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
195      var pm = PersistenceManager;
196      using (new PerformanceLogger("UpdateTaskData")) {
197        var taskDao = pm.TaskDao;
198        var taskDataDao = pm.TaskDataDao;
199        pm.UseTransaction(() => {
200          var task = taskDao.GetById(taskDto.Id);
201          var taskData = taskDataDao.GetById(taskDataDto.TaskId);
202          taskDto.CopyToEntity(task);
203          taskDataDto.CopyToEntity(taskData);
204          taskData.LastUpdate = DateTime.Now;
205          pm.SubmitChanges();
206        });
207      }
208    }
209
210    public DT.Task UpdateTaskState(Guid taskId, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
211      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
212      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
213      var pm = PersistenceManager;
214      using (new PerformanceLogger("UpdateTaskState")) {
215        var taskDao = pm.TaskDao;
216        return pm.UseTransaction(() => {
217          var task = taskDao.GetById(taskId);
218          UpdateTaskState(pm, task, taskState, slaveId, userId, exception);
219          pm.SubmitChanges();
220          return task.ToDto();
221        });
222      }
223    }
224    #endregion
225
226    #region Task Control Methods
227    public void StopTask(Guid taskId) {
228      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
229      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
230      var pm = PersistenceManager;
231      using (new PerformanceLogger("StopTask")) {
232        var taskDao = pm.TaskDao;
233        pm.UseTransaction(() => {
234          var task = taskDao.GetById(taskId);
235          if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
236            task.Command = DA.Command.Stop;
237          } else if (task.State != DA.TaskState.Aborted
238                     && task.State != DA.TaskState.Finished
239                     && task.State != DA.TaskState.Failed) {
240            UpdateTaskState(pm, task, DT.TaskState.Aborted, null, null, string.Empty);
241          }
242          pm.SubmitChanges();
243        });
244      }
245    }
246
247    public void PauseTask(Guid taskId) {
248      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
249      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
250      var pm = PersistenceManager;
251      using (new PerformanceLogger("PauseTask")) {
252        var taskDao = pm.TaskDao;
253        pm.UseTransaction(() => {
254          var task = taskDao.GetById(taskId);
255          if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
256            task.Command = DA.Command.Pause;
257          } else if (task.State != DA.TaskState.Paused
258                     && task.State != DA.TaskState.Aborted
259                     && task.State != DA.TaskState.Finished
260                     && task.State != DA.TaskState.Failed) {
261            UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
262          }
263          pm.SubmitChanges();
264        });
265      }
266    }
267
268    public void RestartTask(Guid taskId) {
269      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
270      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
271      var pm = PersistenceManager;
272      using (new PerformanceLogger("RestartTask")) {
273        var taskDao = pm.TaskDao;
274        pm.UseTransaction(() => {
275          var task = taskDao.GetById(taskId);
276          task.Command = null;
277          UpdateTaskState(pm, task, DT.TaskState.Waiting, null, UserManager.CurrentUserId, string.Empty);
278          pm.SubmitChanges();
279        });
280      }
281    }
282    #endregion
283
284    #region Job Methods
285    public DT.Job GetJob(Guid id) {
286      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
287      AuthorizationManager.AuthorizeForJob(id, DT.Permission.Read);
288      var pm = PersistenceManager;
289      using (new PerformanceLogger("GetJob")) {
290        var jobDao = pm.JobDao;
291        var jobPermissionDao = pm.JobPermissionDao;
292        var taskDao = pm.TaskDao;
293        var currentUserId = UserManager.CurrentUserId;
294        return pm.UseTransaction(() => {
295          var job = jobDao.GetById(id).ToDto();
296          if (job != null) {
297            var statistics = taskDao.GetByJobId(job.Id)
298              .GroupBy(x => x.JobId)
299              .Select(x => new {
300                TotalCount = x.Count(),
301                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
302                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
303              }).FirstOrDefault();
304            if (statistics != null) {
305              job.JobCount = statistics.TotalCount;
306              job.CalculatingCount = statistics.CalculatingCount;
307              job.FinishedCount = statistics.FinishedCount;
308            }
309            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
310            if (currentUserId == job.OwnerUserId) {
311              job.Permission = Permission.Full;
312            } else {
313              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
314              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
315            }
316          }
317          return job;
318        });
319      }
320    }
321
322    public IEnumerable<DT.Job> GetJobs() {
323      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
324      var pm = PersistenceManager;
325      using (new PerformanceLogger("GetJobs")) {
326        var jobDao = pm.JobDao;
327        var jobPermissionDao = pm.JobPermissionDao;
328        var taskDao = pm.TaskDao;
329        var currentUserId = UserManager.CurrentUserId;
330        return pm.UseTransaction(() => {
331          var jobs = jobDao.GetAll()
332            .Where(x => x.State == DA.JobState.Online
333                          && (x.OwnerUserId == currentUserId
334                            || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
335                              && y.GrantedUserId == currentUserId) > 0)
336                          )
337            .Select(x => x.ToDto())
338            .ToList();
339
340          EvaluateJobs(pm, jobs);
341          return jobs;
342        });
343      }
344    }
345
346    public IEnumerable<DT.Job> GetJobsByProjectId(Guid projectId) {
347      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
348      var pm = PersistenceManager;
349      using (new PerformanceLogger("GetJobsByProjectId")) {
350        var currentUserId = UserManager.CurrentUserId;
351        var projectDao = pm.ProjectDao;
352        var jobDao = pm.JobDao;
353
354        return pm.UseTransaction(() => {
355          // check if user is granted to administer the requested projectId
356          var administrationGrantedProjects = projectDao
357            .GetAdministrationGrantedProjectsForUser(currentUserId)
358            .ToList();
359
360          if(administrationGrantedProjects.Select(x => x.ProjectId).Contains(projectId)) {
361            var jobs = jobDao.GetByProjectId(projectId)
362            .Select(x => x.ToDto())
363            .ToList();
364
365            EvaluateJobs(pm, jobs);
366            return jobs;
367          } else {
368            return Enumerable.Empty<DT.Job>();
369          }
370        });
371      }
372    }
373
374    public IEnumerable<DT.Job> GetJobsByProjectIds(IEnumerable<Guid> projectIds) {
375      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
376      var pm = PersistenceManager;
377      using (new PerformanceLogger("GetJobsByProjectIds")) {
378        var currentUserId = UserManager.CurrentUserId;
379        var projectDao = pm.ProjectDao;
380        var jobDao = pm.JobDao;
381        return pm.UseTransaction(() => {
382          // check for which of requested projectIds the user is granted to administer
383          var administrationGrantedProjectIds = projectDao
384            .GetAdministrationGrantedProjectsForUser(currentUserId)
385            .Select(x => x.ProjectId)
386            .ToList();
387          var requestedAndGrantedProjectIds = projectIds.Intersect(administrationGrantedProjectIds);
388
389          if(requestedAndGrantedProjectIds.Any()) {
390            var jobs = jobDao.GetByProjectIds(requestedAndGrantedProjectIds)
391              .Select(x => x.ToDto())
392              .ToList();
393
394            EvaluateJobs(pm, jobs);
395            return jobs;
396          } else {
397            return Enumerable.Empty<DT.Job>();
398          }
399        });
400      }
401    }
402
403    public Guid AddJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
404      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
405      var dateCreated = DateTime.Now;
406      var pm = PersistenceManager;
407
408      // check project availability (cf. duration)
409      CheckProjectAvailability(pm, jobDto.ProjectId, dateCreated);
410
411      // check user - project
412      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
413
414      // check project - resources
415      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
416     
417      using (new PerformanceLogger("AddJob")) {
418        var jobDao = pm.JobDao;
419        var userPriorityDao = pm.UserPriorityDao;
420
421        return pm.UseTransaction(() => {
422          var newJob = jobDto.ToEntity();
423          newJob.OwnerUserId = UserManager.CurrentUserId;
424          newJob.DateCreated = dateCreated;
425
426          // add resource assignments
427          if (resourceIds != null && resourceIds.Any()) {           
428            newJob.AssignedJobResources.AddRange(resourceIds.Select(
429              x => new DA.AssignedJobResource {
430                ResourceId = x
431              }));
432          }
433
434          var job = jobDao.Save(newJob);
435          if (userPriorityDao.GetById(newJob.OwnerUserId) == null) {
436            userPriorityDao.Save(new DA.UserPriority {
437              UserId = newJob.OwnerUserId,
438              DateEnqueued = newJob.DateCreated
439            });
440          }
441          pm.SubmitChanges();
442          return job.JobId;
443        });
444      }
445    }
446
447    public void UpdateJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
448      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
449      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
450      var pm = PersistenceManager;
451      var dateUpdated = DateTime.Now;
452
453      // check project availability
454      CheckProjectAvailability(pm, jobDto.ProjectId, dateUpdated);
455      // check user - project permission
456      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
457      // check project - resources permission
458      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
459
460      using (new PerformanceLogger("UpdateJob")) {
461        bool exists = true;
462        var jobDao = pm.JobDao;
463        pm.UseTransaction(() => {
464          var job = jobDao.GetById(jobDto.Id);
465          if (job == null) {
466            exists = false;
467            job = new DA.Job();
468          } else if(job.State != DA.JobState.Online) {
469            throw new InvalidOperationException(NO_JOB_UPDATE_POSSIBLE);
470          }
471
472
473          jobDto.CopyToEntity(job);
474
475          if (!exists) {
476            // add resource assignments
477            if (resourceIds != null && resourceIds.Any()) {
478              job.AssignedJobResources.AddRange(resourceIds.Select(
479                x => new DA.AssignedJobResource {
480                  ResourceId = x
481              }));
482            }
483            jobDao.Save(job);
484          } else if(resourceIds != null) {
485            var addedJobResourceIds = resourceIds.Except(job.AssignedJobResources.Select(x => x.ResourceId));
486            var removedJobResourceIds = job.AssignedJobResources
487              .Select(x => x.ResourceId)
488              .Except(resourceIds)
489              .ToArray();
490           
491            // remove resource assignments
492            foreach(var rid in removedJobResourceIds) {
493              var ajr = job.AssignedJobResources.Where(x => x.ResourceId == rid).SingleOrDefault();
494              if (ajr != null) job.AssignedJobResources.Remove(ajr);
495            }
496
497            // add resource assignments
498            job.AssignedJobResources.AddRange(addedJobResourceIds.Select(
499              x => new DA.AssignedJobResource {
500                ResourceId = x
501              }));
502          }
503          pm.SubmitChanges();
504        });
505      }
506    }
507
508    public void UpdateJobState(Guid jobId, DT.JobState jobState) {
509      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
510      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
511      var pm = PersistenceManager;
512      using (new PerformanceLogger("UpdateJobState")) {
513        var jobDao = pm.JobDao;
514        pm.UseTransaction(() => {
515          var job = jobDao.GetById(jobId);
516          if(job != null) {
517            var jobStateEntity = jobState.ToEntity();
518            // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
519            // and from "StatisticsPending" to "DeletionPending" = deletion request by HiveStatisticGenerator for EventManager
520            if (job.State == DA.JobState.Online && jobStateEntity == DA.JobState.StatisticsPending) {
521              job.State = jobStateEntity;
522              foreach(var task in job.Tasks
523              .Where(x => x.State == DA.TaskState.Waiting
524                || x.State == DA.TaskState.Paused
525                || x.State == DA.TaskState.Offline)) {
526                task.State = DA.TaskState.Aborted;
527              }
528              pm.SubmitChanges();
529            } else if(job.State == DA.JobState.StatisticsPending && jobStateEntity == DA.JobState.DeletionPending) {
530              job.State = jobStateEntity;
531              pm.SubmitChanges();
532            }
533          }
534        });
535      }
536    }
537
538    public void UpdateJobStates(IEnumerable<Guid> jobIds, DT.JobState jobState) {
539      if (jobState != JobState.StatisticsPending) return; // only process requests for "StatisticsPending"
540
541      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
542      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
543      var currentUserId = UserManager.CurrentUserId;
544
545      var pm = PersistenceManager;
546      using (new PerformanceLogger("UpdateJobStates")) {
547        var jobDao = pm.JobDao;
548        var projectDao = pm.ProjectDao;
549        pm.UseTransaction(() => {
550          foreach(var jobId in jobIds) {
551            var job = jobDao.GetById(jobId);
552            if (job != null) {
553
554              var administrationGrantedProjects = projectDao
555                .GetAdministrationGrantedProjectsForUser(currentUserId)
556                .ToList();
557
558              // check if user is granted to administer the job-parenting project
559              if (isAdministrator || administrationGrantedProjects.Contains(job.Project)) {
560                // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
561                if (job.State == DA.JobState.Online) {
562                  job.State = DA.JobState.StatisticsPending;
563                  foreach (var task in job.Tasks
564                  .Where(x => x.State == DA.TaskState.Waiting
565                    || x.State == DA.TaskState.Paused
566                    || x.State == DA.TaskState.Offline)) {
567                      task.State = DA.TaskState.Aborted;
568                  }
569                  pm.SubmitChanges();
570                }
571              }
572            }
573          }
574        });
575      }
576    }
577
578    public IEnumerable<DT.AssignedJobResource> GetAssignedResourcesForJob(Guid jobId) {
579      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
580      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
581      var pm = PersistenceManager;
582      var assignedJobResourceDao = pm.AssignedJobResourceDao;
583      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
584        return pm.UseTransaction(() =>
585          assignedJobResourceDao.GetByJobId(jobId)
586          .Select(x => x.ToDto())
587          .ToList()
588        );
589      }
590    }
591    #endregion
592
593    #region JobPermission Methods
594    public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
595      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
596      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
597      var pm = PersistenceManager;
598      using (new PerformanceLogger("GrantPermission")) {
599        var jobPermissionDao = pm.JobPermissionDao;
600        var currentUserId = UserManager.CurrentUserId;
601        pm.UseTransaction(() => {
602          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
603          pm.SubmitChanges();
604        });
605      }
606    }
607
608    public void RevokePermission(Guid jobId, Guid grantedUserId) {
609      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
610      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
611      var pm = PersistenceManager;
612      using (new PerformanceLogger("RevokePermission")) {
613        var jobPermissionDao = pm.JobPermissionDao;
614        var currentUserId = UserManager.CurrentUserId;
615        pm.UseTransaction(() => {
616          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
617          pm.SubmitChanges();
618        });
619      }
620    }
621
622    public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
623      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
624      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
625      var pm = PersistenceManager;
626      using (new PerformanceLogger("GetJobPermissions")) {
627        var jobPermissionDao = pm.JobPermissionDao;
628        return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
629          .Select(x => x.ToDto())
630          .ToList()
631        );
632      }
633    }
634
635    // BackwardsCompatibility3.3
636    #region Backwards compatible code, remove with 3.4
637    public bool IsAllowedPrivileged() {
638      return true;
639    }
640    #endregion
641    #endregion
642
643    #region Login Methods
644    public void Hello(DT.Slave slaveInfo) {
645      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
646      if (UserManager.CurrentUser.UserName != "hiveslave") {
647        slaveInfo.OwnerUserId = UserManager.CurrentUserId;
648      }
649      var pm = PersistenceManager;
650      using (new PerformanceLogger("Hello")) {
651        var slaveDao = pm.SlaveDao;
652        pm.UseTransaction(() => {
653          var slave = slaveDao.GetById(slaveInfo.Id);
654          if (slave == null) {
655            slaveDao.Save(slaveInfo.ToEntity());
656          } else {
657            bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
658            Guid? oldParentResourceId = slave.ParentResourceId;
659            slaveInfo.CopyToEntity(slave);
660            slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
661            slave.ParentResourceId = oldParentResourceId;
662            slave.LastHeartbeat = DateTime.Now;
663            slave.SlaveState = DA.SlaveState.Idle;
664          }
665          pm.SubmitChanges();
666        });
667      }
668    }
669
670    public void GoodBye(Guid slaveId) {
671      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
672      var pm = PersistenceManager;
673      using (new PerformanceLogger("GoodBye")) {
674        var slaveDao = pm.SlaveDao;
675        pm.UseTransaction(() => {
676          var slave = slaveDao.GetById(slaveId);
677          if (slave != null) {
678            slave.SlaveState = DA.SlaveState.Offline;
679            pm.SubmitChanges();
680          }
681        });
682      }
683    }
684    #endregion
685
686    #region Heartbeat Methods
687    public List<MessageContainer> Heartbeat(DT.Heartbeat heartbeat) {
688      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
689      List<MessageContainer> result = new List<MessageContainer>();
690      try {
691        using (new PerformanceLogger("ProcessHeartbeat")) {
692          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
693        }
694      } catch (Exception ex) {
695        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
696      }
697      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
698        TriggerEventManager(false);
699      }
700      return result;
701    }
702    #endregion
703
704    #region Plugin Methods
705    public DT.Plugin GetPlugin(Guid pluginId) {
706      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
707      var pm = PersistenceManager;
708      using (new PerformanceLogger("GetPlugin")) {
709        var pluginDao = pm.PluginDao;
710        return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
711      }
712    }
713
714    public Guid AddPlugin(DT.Plugin plugin, List<DT.PluginData> pluginData) {
715      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
716      var pm = PersistenceManager;
717      using (new PerformanceLogger("AddPlugin")) {
718        var pluginDao = pm.PluginDao;
719        plugin.UserId = UserManager.CurrentUserId;
720        plugin.DateCreated = DateTime.Now;
721        return pm.UseTransaction(() => {
722          var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
723          if (pluginEntity != null) {
724            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(pluginEntity.PluginId));
725          }
726          pluginEntity = plugin.ToEntity();
727          foreach (var data in pluginData) {
728            data.PluginId = default(Guid); // real id will be assigned from linq2sql
729            pluginEntity.PluginData.Add(data.ToEntity());
730          }
731          pluginDao.Save(pluginEntity);
732          pm.SubmitChanges();
733          return pluginEntity.PluginId;
734        });
735      }
736    }
737
738    public IEnumerable<DT.Plugin> GetPlugins() {
739      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
740      var pm = PersistenceManager;
741      using (new PerformanceLogger("GetPlugins")) {
742        var pluginDao = pm.PluginDao;
743        return pm.UseTransaction(() => pluginDao.GetAll()
744          .Where(x => x.Hash != null)
745          .Select(x => x.ToDto())
746          .ToList()
747        );
748      }
749    }
750
751    public IEnumerable<DT.PluginData> GetPluginDatas(List<Guid> pluginIds) {
752      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
753      var pm = PersistenceManager;
754      using (new PerformanceLogger("GetPluginDatas")) {
755        var pluginDataDao = pm.PluginDataDao;
756        return pm.UseTransaction(() => pluginDataDao.GetAll()
757            .Where(x => pluginIds.Contains(x.PluginId))
758            .Select(x => x.ToDto())
759            .ToList()
760        );
761      }
762    }
763    #endregion
764
765    #region Project Methods
766    public Guid AddProject(DT.Project projectDto) {
767      if (projectDto == null || projectDto.Id != Guid.Empty) return Guid.Empty;
768      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
769      // check if current (non-admin) user is owner of one of projectDto's-parents
770      if (!RoleVerifier.IsInRole(HiveRoles.Administrator)) {
771        if(projectDto.ParentProjectId.HasValue) {
772          AuthorizationManager.AuthorizeForProjectAdministration(projectDto.ParentProjectId.Value, false);
773        } else {
774          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
775        }
776      }
777     
778      var pm = PersistenceManager;
779      using (new PerformanceLogger("AddProject")) {
780        var projectDao = pm.ProjectDao;
781
782        return pm.UseTransaction(() => {
783          var project = projectDao.Save(projectDto.ToEntity());
784          project.ProjectPermissions.Clear();
785          project.ProjectPermissions.Add(new DA.ProjectPermission {
786            GrantedUserId = project.OwnerUserId,
787            GrantedByUserId = UserManager.CurrentUserId
788          });
789
790          pm.SubmitChanges();
791          return project.ProjectId;
792        });
793      }
794    }
795
796    public void UpdateProject(DT.Project projectDto) {
797      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
798      // check if current (non-admin) user is owner of the project or the projectDto's-parents
799      if (!RoleVerifier.IsInRole(HiveRoles.Administrator)) {
800        AuthorizationManager.AuthorizeForProjectAdministration(projectDto.Id, false);
801      }
802
803      var pm = PersistenceManager;
804      using (new PerformanceLogger("UpdateProject")) {
805        var projectDao = pm.ProjectDao;
806        var assignedJobResourceDao = pm.AssignedJobResourceDao;
807        pm.UseTransaction(() => {
808          var project = projectDao.GetById(projectDto.Id);
809          if (project != null) { // update existent project
810            var formerOwnerId = project.OwnerUserId;
811            projectDto.CopyToEntity(project);
812
813            // if owner has changed...
814            if(formerOwnerId != projectDto.OwnerUserId) {
815              // OBSOLETE: former owner looses permission and project-related jobs
816              //var formerPermissionItem = project.ProjectPermissions.Where(x => x.GrantedUserId == formerOwnerId).FirstOrDefault();
817              //if (formerPermissionItem != null) {
818              //  // remove permissions
819              //  project.ProjectPermissions.Remove(formerPermissionItem);
820              //  // remove jobs if former owner is no member of a still permitted group
821              //  var ugt = GetUserGroupTree();
822              //  var permittedGuids = new HashSet<Guid>(); // User- and Group-Guids
823              //  // get all member-Guids of all still permitted groups
824              //  foreach (var item in project.ProjectPermissions) {
825              //    permittedGuids.Add(item.GrantedUserId);
826              //    if(ugt.ContainsKey(item.GrantedUserId)) {
827              //      ugt[item.GrantedUserId].ToList().ForEach(x => permittedGuids.Add(x));
828              //    }
829
830              //    // check if former owner Guid is in Member-Guids
831              //    // if yes: do nothing, if not do:
832              //    if (!permittedGuids.Contains(formerOwnerId)) {
833              //      assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, new List<Guid> { formerOwnerId });
834              //    }
835              //  }
836              //}
837              // Add permission for new owner if not already done
838              if(!project.ProjectPermissions
839                .Select(pp => pp.GrantedUserId)
840                .Contains(projectDto.OwnerUserId)) {
841                project.ProjectPermissions.Add(new DA.ProjectPermission {
842                  GrantedUserId = projectDto.OwnerUserId,
843                  GrantedByUserId = UserManager.CurrentUserId
844                });
845              }
846            }
847
848          } else { // save new project
849            var newProject = projectDao.Save(projectDto.ToEntity());
850            newProject.ProjectPermissions.Clear();
851            newProject.ProjectPermissions.Add(new DA.ProjectPermission {
852              GrantedUserId = projectDto.OwnerUserId,
853              GrantedByUserId = UserManager.CurrentUserId
854            });
855          }
856          pm.SubmitChanges();
857        });
858      }
859    }
860
861    public void DeleteProject(Guid projectId) {
862      if (projectId == Guid.Empty) return;
863      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
864      // check if current (non-admin) user is owner of one of the projectDto's-parents
865      if (!RoleVerifier.IsInRole(HiveRoles.Administrator)) {
866        AuthorizationManager.AuthorizeForProjectAdministration(projectId, true);
867      }
868
869      var pm = PersistenceManager;
870      using (new PerformanceLogger("DeleteProject")) {
871        var projectDao = pm.ProjectDao;
872        var jobDao = pm.JobDao;
873        var assignedJobResourceDao = pm.AssignedJobResourceDao;
874        pm.UseTransaction(() => {
875          var projectIds = new HashSet<Guid> { projectId };
876          projectIds.Union(projectDao.GetChildProjectIdsById(projectId));
877
878          var jobs = jobDao.GetByProjectIds(projectIds)
879            .Select(x => x.ToDto())
880            .ToList();
881
882          if(jobs.Count > 0) {
883            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.");
884          } else {
885            assignedJobResourceDao.DeleteByProjectIds(projectIds);
886            projectDao.DeleteByIds(projectIds);
887            pm.SubmitChanges();
888          }
889        });
890      }
891    }
892
893    // query granted project for use (i.e. to calculate on)
894    public DT.Project GetProject(Guid projectId) {
895      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
896      var pm = PersistenceManager;
897      using (new PerformanceLogger("GetProject")) {
898        var projectDao = pm.ProjectDao;
899        var currentUserId = UserManager.CurrentUserId;
900        var userAndGroupIds = new List<Guid> { currentUserId };
901        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
902        return pm.UseTransaction(() => {
903          return projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
904          .Where(x => x.ProjectId == projectId)
905          .Select(x => x.ToDto())
906          .SingleOrDefault();
907        });
908      }
909    }
910
911    // query granted projects for use (i.e. to calculate on)
912    public IEnumerable<DT.Project> GetProjects() {
913      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
914      var pm = PersistenceManager;
915      using (new PerformanceLogger("GetProjects")) {
916        var projectDao = pm.ProjectDao;
917        var currentUserId = UserManager.CurrentUserId;
918        var userAndGroupIds = new List<Guid> { currentUserId };
919        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
920        return pm.UseTransaction(() => {
921          var projects = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
922            .Select(x => x.ToDto()).ToList();
923          var now = DateTime.Now;
924          return projects.Where(x => x.StartDate <= now && x.EndDate >= now).ToList();
925        });
926      }
927    }
928
929    public IEnumerable<DT.Project> GetProjectsForAdministration() {
930      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
931      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
932      var pm = PersistenceManager;
933      using (new PerformanceLogger("GetProjectsForAdministration")) {
934        var projectDao = pm.ProjectDao;
935       
936        return pm.UseTransaction(() => {
937          if(isAdministrator) {
938            return projectDao.GetAll().Select(x => x.ToDto()).ToList();
939          } else {
940            var currentUserId = UserManager.CurrentUserId;
941            return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId)
942              .Select(x => x.ToDto()).ToList();
943
944          }
945        });
946      }
947    }
948
949    public IDictionary<Guid, HashSet<Guid>> GetProjectGenealogy() {
950      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
951      var pm = PersistenceManager;
952      using(new PerformanceLogger("GetProjectGenealogy")) {
953        var projectDao = pm.ProjectDao;
954        var projectAncestors = new Dictionary<Guid, HashSet<Guid>>();
955        return pm.UseTransaction(() => {
956          var projects = projectDao.GetAll().ToList();
957          projects.ForEach(p => projectAncestors.Add(p.ProjectId, new HashSet<Guid>()));
958          foreach (var p in projects) {
959            var parentProject = p.ParentProject;
960            while(parentProject != null) {
961              projectAncestors[p.ProjectId].Add(parentProject.ProjectId);
962              parentProject = parentProject.ParentProject;
963            }
964          }
965          return projectAncestors;
966        });
967      }
968    }
969
970    public IDictionary<Guid, string> GetProjectNames() {
971      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
972      var pm = PersistenceManager;
973      using (new PerformanceLogger("GetProjectNames")) {
974        var projectDao = pm.ProjectDao;
975        var projectNames = new Dictionary<Guid, string>();
976        return pm.UseTransaction(() => {
977          projectDao
978            .GetAll().ToList()
979            .ForEach(p=> projectNames.Add(p.ProjectId, p.Name));
980          return projectNames;
981        });
982      }
983    }
984    #endregion
985
986    #region ProjectPermission Methods
987    public void SaveProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool reassign, bool cascading, bool reassignCascading) {
988      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
989      if (projectId == null || grantedUserIds == null) return;
990      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
991      var pm = PersistenceManager;
992      using (new PerformanceLogger("SaveProjectPermissions")) {
993        var projectDao = pm.ProjectDao;
994        var projectPermissionDao = pm.ProjectPermissionDao;
995        var assignedJobResourceDao = pm.AssignedJobResourceDao;
996
997        pm.UseTransaction(() => {
998          var project = projectDao.GetById(projectId);
999          if (project == null) return;
1000          var projectPermissions = project.ProjectPermissions.Select(x => x.GrantedUserId).ToArray();
1001          //var addedPermissions = grantedUserIds.Except(projectPermissions);
1002          var removedPermissions = projectPermissions.Except(grantedUserIds);
1003
1004          // remove job assignments and project permissions
1005          if (reassign) {
1006            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
1007            project.ProjectPermissions.Clear();
1008          } else {
1009
1010            var ugt = GetUserGroupTree();
1011            var permittedGuids = new HashSet<Guid>(); // User- and Group-Guids
1012            var notpermittedGuids = new HashSet<Guid>();
1013
1014            // remove job assignments:
1015            // (1) get all member-Guids of all still or fresh permitted user/groups
1016            foreach (var item in grantedUserIds) {
1017              permittedGuids.Add(item);
1018              if (ugt.ContainsKey(item)) {
1019                ugt[item].ToList().ForEach(x => permittedGuids.Add(x));
1020              }
1021            }
1022
1023            // (2) get all member-Guids of users and groups in removedPermissions
1024            foreach (var item in removedPermissions) {
1025              notpermittedGuids.Add(item);
1026              if (ugt.ContainsKey(item)) {
1027                ugt[item].ToList().ForEach(x => notpermittedGuids.Add(x));
1028              }
1029            }
1030
1031            // (3) get all Guids which are in removedPermissions but not in grantedUserIds
1032            var definatelyNotPermittedGuids = notpermittedGuids.Except(permittedGuids);
1033
1034            // (4) delete jobs of those
1035            assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, definatelyNotPermittedGuids);
1036
1037
1038            // remove project permissions
1039            foreach (var item in project.ProjectPermissions
1040              .Where(x => removedPermissions.Contains(x.GrantedUserId))
1041              .ToList()) {
1042              project.ProjectPermissions.Remove(item);
1043            }
1044          }
1045          pm.SubmitChanges();
1046
1047          // add project permissions
1048          foreach (var id in grantedUserIds) {
1049            if(project.ProjectPermissions.All(x => x.GrantedUserId != id)) {
1050              project.ProjectPermissions.Add(new DA.ProjectPermission {
1051                GrantedUserId = id,
1052                GrantedByUserId = UserManager.CurrentUserId
1053              });
1054            }
1055          }
1056          pm.SubmitChanges();
1057
1058          if (cascading) {
1059            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
1060            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
1061
1062            // remove job assignments
1063            if (reassignCascading) {
1064              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
1065            } else {
1066              assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, removedPermissions);
1067            }
1068
1069            foreach(var p in childProjects) {
1070              // remove project permissions
1071              if(reassignCascading) {
1072                p.ProjectPermissions.Clear();
1073              } else {
1074                foreach(var item in p.ProjectPermissions
1075                  .Where(x => removedPermissions.Contains(x.GrantedUserId))
1076                  .ToList()) {
1077                  p.ProjectPermissions.Remove(item);
1078                }
1079              }
1080              pm.SubmitChanges();
1081
1082              // add project permissions
1083              foreach (var id in grantedUserIds) {
1084                if (p.ProjectPermissions.All(x => x.GrantedUserId != id)) {
1085                  p.ProjectPermissions.Add(new DA.ProjectPermission {
1086                    GrantedUserId = id,
1087                    GrantedByUserId = UserManager.CurrentUserId
1088                  });
1089                }
1090              }
1091            }
1092          }
1093          pm.SubmitChanges();
1094        });
1095      }
1096    }
1097
1098    //private void GrantProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
1099    //  throw new NotImplementedException();
1100    //}
1101
1102    //private void RevokeProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
1103    //  RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1104    //  if (projectId == null || grantedUserIds == null || !grantedUserIds.Any()) return;
1105    //  AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
1106    //  var pm = PersistenceManager;
1107    //  using (new PerformanceLogger("RevokeProjectPermissions")) {
1108    //    var projectPermissionDao = pm.ProjectPermissionDao;
1109    //    var projectDao = pm.ProjectDao;
1110    //    var assignedJobResourceDao = pm.AssignedJobResourceDao;
1111    //    pm.UseTransaction(() => {
1112    //      if (cascading) {
1113    //        var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
1114    //        projectPermissionDao.DeleteByProjectIdsAndGrantedUserIds(childProjectIds, grantedUserIds);
1115    //        assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, grantedUserIds);
1116    //      }
1117    //      projectPermissionDao.DeleteByProjectIdAndGrantedUserIds(projectId, grantedUserIds);
1118    //      assignedJobResourceDao.DeleteByProjectIdAndUserIds(projectId, grantedUserIds);
1119    //      pm.SubmitChanges();
1120    //    });
1121    //  }
1122    //}
1123
1124    public IEnumerable<DT.ProjectPermission> GetProjectPermissions(Guid projectId) {
1125      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1126      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
1127      var pm = PersistenceManager;
1128      using (new PerformanceLogger("GetProjectPermissions")) {
1129        var projectPermissionDao = pm.ProjectPermissionDao;
1130        return pm.UseTransaction(() => projectPermissionDao.GetByProjectId(projectId)
1131          .Select(x => x.ToDto())
1132          .ToList()
1133        );
1134      }
1135    }
1136    #endregion
1137
1138    #region AssignedProjectResource Methods
1139    // basic: remove and add assignments (resourceIds) to projectId and its depending jobs
1140    // reassign: clear all assignments from project and its depending jobs, before adding new ones (resourceIds)
1141    // cascading: "basic" mode for child-projects
1142    // reassignCascading: "reassign" mode for child-projects
1143    public void SaveProjectResourceAssignments(Guid projectId, List<Guid> resourceIds, bool reassign, bool cascading, bool reassignCascading) {
1144      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1145      if (projectId == null || resourceIds == null) return;
1146      AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
1147      var pm = PersistenceManager;
1148      using (new PerformanceLogger("SaveProjectResourceAssignments")) {
1149        var projectDao = pm.ProjectDao;
1150        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1151        var assignedJobResourceDao = pm.AssignedJobResourceDao;
1152        pm.UseTransaction(() => {
1153          var project = projectDao.GetById(projectId);
1154          var assignedResources = project.AssignedProjectResources.Select(x => x.ResourceId).ToArray();
1155          var removedAssignments = assignedResources.Except(resourceIds);
1156
1157          // remove job and project assignments
1158          if (reassign) {
1159            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
1160            project.AssignedProjectResources.Clear();
1161          } else {
1162            assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, removedAssignments);
1163            foreach (var item in project.AssignedProjectResources
1164              .Where(x => removedAssignments.Contains(x.ResourceId))
1165              .ToList()) {
1166              project.AssignedProjectResources.Remove(item);
1167            }
1168          }
1169          pm.SubmitChanges();
1170
1171          // add project assignments
1172          foreach (var id in resourceIds) {
1173            if (project.AssignedProjectResources.All(x => x.ResourceId != id)) {
1174              project.AssignedProjectResources.Add(new DA.AssignedProjectResource {
1175                ResourceId = id
1176              });
1177            }
1178          }
1179          pm.SubmitChanges();
1180
1181          if (cascading) {
1182            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
1183
1184            // remove job assignments
1185            if (reassignCascading) {
1186              assignedJobResourceDao.DeleteByProjectIds(childProjects.Select(x => x.ProjectId).ToList());
1187            } else {
1188              var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
1189              assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, removedAssignments);
1190            }
1191            foreach (var p in childProjects) {
1192              // remove project assignments
1193              if (reassignCascading) {
1194                p.AssignedProjectResources.Clear();
1195              } else {
1196                foreach (var item in p.AssignedProjectResources
1197                  .Where(x => removedAssignments.Contains(x.ResourceId))
1198                  .ToList()) {
1199                  p.AssignedProjectResources.Remove(item);
1200                }
1201              }
1202              pm.SubmitChanges();
1203
1204              // add project assignments
1205              foreach (var id in resourceIds) {
1206                if(p.AssignedProjectResources.All(x => x.ResourceId != id)) {
1207                  p.AssignedProjectResources.Add(new DA.AssignedProjectResource {
1208                    ResourceId = id
1209                  });
1210                }
1211              }
1212            }
1213          }
1214          pm.SubmitChanges();
1215        });
1216      }
1217    }
1218
1219    //private void AssignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
1220    //  throw new NotImplementedException();
1221    //}
1222
1223    //private void UnassignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
1224    //  RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1225    //  if (projectId == null || resourceIds == null || !resourceIds.Any()) return;
1226    //  AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
1227    //  var pm = PersistenceManager;
1228    //  using (new PerformanceLogger("UnassignProjectResources")) {
1229    //    var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1230    //    var assignedJobResourceDao = pm.AssignedJobResourceDao;
1231    //    var projectDao = pm.ProjectDao;
1232    //    pm.UseTransaction(() => {
1233    //      if (cascading) {
1234    //        var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
1235    //        assignedProjectResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
1236    //        assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
1237    //      }
1238    //      assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
1239    //      assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
1240    //      pm.SubmitChanges();
1241    //    });
1242    //  }
1243    //}
1244
1245    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProject(Guid projectId) {
1246      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1247      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, projectId);
1248      var pm = PersistenceManager;
1249      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
1250        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1251        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
1252          .Select(x => x.ToDto())
1253          .ToList()
1254        );
1255      }
1256    }
1257
1258    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectAdministration(Guid projectId) {
1259      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1260      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
1261      var pm = PersistenceManager;
1262      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
1263        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1264        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
1265          .Select(x => x.ToDto())
1266          .ToList()
1267        );
1268      }
1269    }
1270
1271    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectsAdministration(IEnumerable<Guid> projectIds) {
1272      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1273      foreach(var id in projectIds)
1274        AuthorizationManager.AuthorizeForProjectAdministration(id, false);
1275
1276      var pm = PersistenceManager;
1277      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
1278        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1279        var assignments = new List<DT.AssignedProjectResource>();
1280        pm.UseTransaction(() => {
1281          foreach (var id in projectIds) {
1282            assignments.AddRange(assignedProjectResourceDao.GetByProjectId(id)
1283              .Select(x => x.ToDto()));
1284          }
1285        });
1286        return assignments.Distinct();
1287      }
1288    }
1289
1290    #endregion
1291
1292    #region Slave Methods
1293    public Guid AddSlave(DT.Slave slaveDto) {
1294      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1295      var pm = PersistenceManager;
1296      using (new PerformanceLogger("AddSlave")) {
1297        var slaveDao = pm.SlaveDao;
1298        return pm.UseTransaction(() => {
1299          var slave = slaveDao.Save(slaveDto.ToEntity());
1300          pm.SubmitChanges();
1301          return slave.ResourceId;
1302        });
1303      }
1304    }
1305
1306    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
1307      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1308      var pm = PersistenceManager;
1309      using (new PerformanceLogger("AddSlaveGroup")) {
1310        var slaveGroupDao = pm.SlaveGroupDao;
1311        return pm.UseTransaction(() => {
1312          if (slaveGroupDto.Id == Guid.Empty) {
1313            slaveGroupDto.Id = Guid.NewGuid();
1314          }
1315          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
1316          pm.SubmitChanges();
1317          return slaveGroup.ResourceId;
1318        });
1319      }
1320    }
1321
1322    public DT.Slave GetSlave(Guid slaveId) {
1323      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1324      var pm = PersistenceManager;
1325      using (new PerformanceLogger("GetSlave")) {
1326        var slaveDao = pm.SlaveDao;
1327        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
1328      }
1329    }
1330
1331    // query granted slaves for use (i.e. to calculate on)
1332    public IEnumerable<DT.Slave> GetSlaves() {
1333      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1334      var pm = PersistenceManager;
1335      using (new PerformanceLogger("GetSlaves")) {
1336        var slaveDao = pm.SlaveDao;
1337        var projectDao = pm.ProjectDao;
1338        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1339
1340        // collect user information
1341        var currentUserId = UserManager.CurrentUserId;
1342        var userAndGroupIds = new List<Guid> { currentUserId };
1343        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
1344
1345        return pm.UseTransaction(() => {
1346          var slaves = slaveDao.GetAll()
1347            .Select(x => x.ToDto())
1348            .ToList();
1349          var grantedProjectIds = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
1350            .Select(x => x.ProjectId)
1351            .ToList();
1352          var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourcesByProjectIds(grantedProjectIds)
1353            .Select(x => x.ResourceId)
1354            .ToList();
1355
1356          return slaves
1357            .Where(x => grantedResourceIds.Contains(x.Id))
1358            .ToList();
1359        });
1360      }
1361    }
1362
1363    // query granted slave groups for use (i.e. to calculate on)
1364    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
1365      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1366      var pm = PersistenceManager;
1367      using (new PerformanceLogger("GetSlaveGroups")) {
1368        var slaveGroupDao = pm.SlaveGroupDao;
1369        var projectDao = pm.ProjectDao;
1370        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1371
1372        // collect user information
1373        var currentUserId = UserManager.CurrentUserId;
1374        var userAndGroupIds = new List<Guid> { currentUserId };
1375        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
1376
1377        return pm.UseTransaction(() => {
1378          var slaveGroups = slaveGroupDao.GetAll()
1379            .Select(x => x.ToDto())
1380            .ToList();
1381          var grantedProjectIds = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
1382            .Select(x => x.ProjectId)
1383            .ToList();
1384          var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourcesByProjectIds(grantedProjectIds)
1385            .Select(x => x.ResourceId)
1386            .ToList();
1387
1388          return slaveGroups
1389            .Where(x => grantedResourceIds.Contains(x.Id))
1390            .ToList();
1391        });
1392      }
1393    }
1394
1395    // query granted slaves for resource administration
1396    public IEnumerable<DT.Slave> GetSlavesForAdministration() {
1397      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1398      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
1399      var pm = PersistenceManager;
1400      using (new PerformanceLogger("GetSlavesForAdministration")) {
1401        var slaveDao = pm.SlaveDao;
1402        var currentUserId = UserManager.CurrentUserId;
1403
1404        if (isAdministrator) {
1405          return pm.UseTransaction(() => {
1406            return slaveDao.GetAll()
1407              .Select(x => x.ToDto())
1408              .ToList();
1409          });
1410        } else {
1411          var slaves = slaveDao.GetAll()
1412            .Select(x => x.ToDto())
1413            .ToList();
1414          var projectDao = pm.ProjectDao;
1415          var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1416          var projects = projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).ToList();
1417          var resourceIds = assignedProjectResourceDao
1418            .GetAllGrantedResourcesByProjectIds(projects.Select(x => x.ProjectId).ToList())
1419            .Select(x => x.ResourceId)
1420            .ToList();
1421
1422          return slaves
1423            .Where(x => resourceIds.Contains(x.Id))
1424            .ToList();
1425        }
1426      }
1427    }
1428
1429    // query granted slave groups for resource administration
1430    public IEnumerable<DT.SlaveGroup> GetSlaveGroupsForAdministration() {
1431      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1432      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
1433      var pm = PersistenceManager;
1434      using (new PerformanceLogger("GetSlaveGroupsForAdministration")) {
1435        var slaveGroupDao = pm.SlaveGroupDao;
1436        var currentUserId = UserManager.CurrentUserId;
1437
1438        if (isAdministrator) {
1439          return pm.UseTransaction(() => {
1440            return slaveGroupDao.GetAll()
1441              .Select(x => x.ToDto())
1442              .ToList();
1443          });
1444        } else {
1445          var slaveGroups = slaveGroupDao.GetAll()
1446            .Select(x => x.ToDto())
1447            .ToList();
1448          var projectDao = pm.ProjectDao;
1449          var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1450          var projects = projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).ToList();
1451          var resourceIds = assignedProjectResourceDao
1452            .GetAllGrantedResourcesByProjectIds(projects.Select(x => x.ProjectId).ToList())
1453            .Select(x => x.ResourceId)
1454            .ToList();
1455
1456          return slaveGroups
1457            .Where(x => resourceIds.Contains(x.Id))
1458            .ToList();
1459        }
1460      }
1461    }
1462
1463    public IDictionary<Guid, HashSet<Guid>> GetResourceGenealogy() {
1464      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1465      var pm = PersistenceManager;
1466      using (new PerformanceLogger("GetResourceGenealogy")) {
1467        var resourceDao = pm.ResourceDao;
1468        var resourceAncestors = new Dictionary<Guid, HashSet<Guid>>();
1469        return pm.UseTransaction(() => {
1470          var resources = resourceDao.GetAll().ToList();
1471          resources.ForEach(r => resourceAncestors.Add(r.ResourceId, new HashSet<Guid>()));
1472         
1473          foreach(var r in resources) {
1474            var parentResource = r.ParentResource;
1475            while(parentResource != null) {
1476              resourceAncestors[r.ResourceId].Add(parentResource.ResourceId);
1477              parentResource = parentResource.ParentResource;
1478            }
1479          }
1480          return resourceAncestors;
1481        });
1482      }
1483    }
1484
1485    public void UpdateSlave(DT.Slave slaveDto) {
1486      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1487      if (slaveDto == null) return;
1488      AuthorizationManager.AuthorizeForResourceAdministration(slaveDto.Id);
1489      var pm = PersistenceManager;
1490      using (new PerformanceLogger("UpdateSlave")) {
1491        var slaveDao = pm.SlaveDao;
1492        pm.UseTransaction(() => {
1493          var slave = slaveDao.GetById(slaveDto.Id);
1494          if (slave != null) {
1495            slaveDto.CopyToEntity(slave);
1496          } else {
1497            slaveDao.Save(slaveDto.ToEntity());
1498          }
1499          pm.SubmitChanges();
1500        });
1501      }
1502    }
1503
1504    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
1505      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1506      if (slaveGroupDto == null) return;
1507      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupDto.Id);
1508      var pm = PersistenceManager;
1509      using (new PerformanceLogger("UpdateSlaveGroup")) {
1510        var slaveGroupDao = pm.SlaveGroupDao;
1511        pm.UseTransaction(() => {
1512          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
1513          if (slaveGroup != null) {
1514            slaveGroupDto.CopyToEntity(slaveGroup);
1515          } else {
1516            slaveGroupDao.Save(slaveGroupDto.ToEntity());
1517          }
1518          pm.SubmitChanges();
1519        });
1520      }
1521    }
1522
1523    public void DeleteSlave(Guid slaveId) {
1524      if (slaveId == Guid.Empty) return;
1525      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1526      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
1527      var pm = PersistenceManager;
1528      using (new PerformanceLogger("DeleteSlave")) {
1529        var slaveDao = pm.SlaveDao;
1530        pm.UseTransaction(() => {
1531          slaveDao.Delete(slaveId);
1532          pm.SubmitChanges();
1533        });
1534      }
1535    }
1536
1537    public void DeleteSlaveGroup(Guid slaveGroupId) {
1538      if (slaveGroupId == Guid.Empty) return;
1539      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1540      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
1541      var pm = PersistenceManager;
1542      using (new PerformanceLogger("DeleteSlaveGroup")) {
1543        var resourceDao = pm.ResourceDao;
1544        pm.UseTransaction(() => {
1545          var resourceIds = new HashSet<Guid> { slaveGroupId };
1546          resourceIds.Union(resourceDao.GetChildResourceIdsById(slaveGroupId));
1547          resourceDao.DeleteByIds(resourceIds);
1548          pm.SubmitChanges();
1549        });
1550      }
1551    }
1552
1553    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
1554      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1555      var pm = PersistenceManager;
1556      using (new PerformanceLogger("AddResourceToGroup")) {
1557        var resourceDao = pm.ResourceDao;
1558        pm.UseTransaction(() => {
1559          var resource = resourceDao.GetById(resourceId);
1560          resource.ParentResourceId = slaveGroupId;
1561          pm.SubmitChanges();
1562        });
1563      }
1564    }
1565
1566    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
1567      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1568      var pm = PersistenceManager;
1569      using (new PerformanceLogger("RemoveResourceFromGroup")) {
1570        var resourceDao = pm.ResourceDao;
1571        pm.UseTransaction(() => {
1572          var resource = resourceDao.GetById(resourceId);
1573          resource.ParentResourceId = null;
1574          pm.SubmitChanges();
1575        });
1576      }
1577    }
1578
1579    public Guid GetResourceId(string resourceName) {
1580      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1581      var pm = PersistenceManager;
1582      using (new PerformanceLogger("GetResourceId")) {
1583        var resourceDao = pm.ResourceDao;
1584        return pm.UseTransaction(() => {
1585          var resource = resourceDao.GetByName(resourceName);
1586          return resource != null ? resource.ResourceId : Guid.Empty;
1587        });
1588      }
1589    }
1590
1591    public void TriggerEventManager(bool force) {
1592      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1593      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
1594      bool cleanup;
1595      var pm = PersistenceManager;
1596      using (new PerformanceLogger("TriggerEventManager")) {
1597        cleanup = false;
1598        var lifecycleDao = pm.LifecycleDao;
1599        pm.UseTransaction(() => {
1600          var lastLifecycle = lifecycleDao.GetLastLifecycle();
1601          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
1602          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
1603            lifecycleDao.UpdateLifecycle();
1604            cleanup = true;
1605            pm.SubmitChanges();
1606          }
1607        }, true);
1608      }
1609      if (cleanup) {
1610        EventManager.Cleanup();
1611      }
1612    }
1613
1614    public int GetNewHeartbeatInterval(Guid slaveId) {
1615      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
1616      var pm = PersistenceManager;
1617      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
1618        var slaveDao = pm.SlaveDao;
1619        return pm.UseTransaction(() => {
1620          var slave = slaveDao.GetById(slaveId);
1621          if (slave != null) {
1622            return slave.HbInterval;
1623          }
1624          return -1;
1625        });
1626      }
1627    }
1628    #endregion
1629
1630    #region Downtime Methods
1631    public Guid AddDowntime(DT.Downtime downtimeDto) {
1632      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1633      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
1634      var pm = PersistenceManager;
1635      using (new PerformanceLogger("AddDowntime")) {
1636        var downtimeDao = pm.DowntimeDao;
1637        return pm.UseTransaction(() => {
1638          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
1639          pm.SubmitChanges();
1640          return downtime.ResourceId;
1641        });
1642      }
1643    }
1644
1645    public void DeleteDowntime(Guid downtimeId) {
1646      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1647      var pm = PersistenceManager;
1648      using (new PerformanceLogger("DeleteDowntime")) {
1649        var downtimeDao = pm.DowntimeDao;
1650        pm.UseTransaction(() => {
1651          downtimeDao.Delete(downtimeId);
1652          pm.SubmitChanges();
1653        });
1654      }
1655    }
1656
1657    public void UpdateDowntime(DT.Downtime downtimeDto) {
1658      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1659      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
1660      var pm = PersistenceManager;
1661      using (new PerformanceLogger("UpdateDowntime")) {
1662        var downtimeDao = pm.DowntimeDao;
1663        pm.UseTransaction(() => {
1664          var downtime = downtimeDao.GetById(downtimeDto.Id);
1665          if (downtime != null) {
1666            downtimeDto.CopyToEntity(downtime);
1667          } else {
1668            downtimeDao.Save(downtimeDto.ToEntity());
1669          }
1670          pm.SubmitChanges();
1671        });
1672      }
1673    }
1674
1675    public IEnumerable<DT.Downtime> GetDowntimesForResource(Guid resourceId) {
1676      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1677      var pm = PersistenceManager;
1678      using (new PerformanceLogger("GetDowntimesForResource")) {
1679        var downtimeDao = pm.DowntimeDao;
1680        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
1681          .Select(x => x.ToDto())
1682          .ToList()
1683        );
1684      }
1685    }
1686    #endregion
1687
1688    #region User Methods
1689    public string GetUsernameByUserId(Guid userId) {
1690      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1691      var user = UserManager.GetUserById(userId);
1692      return user != null ? user.UserName : null;
1693    }
1694
1695    public Guid GetUserIdByUsername(string username) {
1696      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1697      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
1698      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
1699    }
1700   
1701    public Dictionary<Guid, HashSet<Guid>> GetUserGroupTree() {
1702      var userGroupTree = new Dictionary<Guid, HashSet<Guid>>();
1703      var userGroupMapping = UserManager.GetUserGroupMapping();
1704
1705      foreach(var ugm in userGroupMapping) {
1706        if (ugm.Parent == null || ugm.Child == null) continue;
1707
1708        if (!userGroupTree.ContainsKey(ugm.Parent)) {
1709          userGroupTree.Add(ugm.Parent, new HashSet<Guid>());
1710        }
1711        userGroupTree[ugm.Parent].Add(ugm.Child);
1712      }
1713
1714      return userGroupTree;
1715    }
1716
1717    public bool CheckAccessToAdminAreaGranted() {
1718      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1719      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
1720      var pm = PersistenceManager;
1721      using(new PerformanceLogger("CheckAccessToAdminAreaGranted")) {
1722        if (isAdministrator) {
1723          return true;
1724        } else {
1725          var projectDao = pm.ProjectDao;
1726          var currentUserId = UserManager.CurrentUserId;
1727          return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).Any();
1728        }
1729      }
1730    }
1731    #endregion
1732
1733    #region UserPriorities Methods
1734    public IEnumerable<DT.UserPriority> GetUserPriorities() {
1735      var pm = PersistenceManager;
1736      using (new PerformanceLogger("GetUserPriorities")) {
1737        var userPriorityDao = pm.UserPriorityDao;
1738        return pm.UseTransaction(() => userPriorityDao.GetAll()
1739          .Select(x => x.ToDto())
1740          .ToList()
1741        );
1742      }
1743    }
1744    #endregion
1745
1746    #region Private Helper Methods
1747    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
1748      var stateLogDao = pm.StateLogDao;
1749      var taskStateEntity = taskState.ToEntity();
1750
1751      if (task.State == DA.TaskState.Transferring && taskStateEntity == DA.TaskState.Paused && task.Command == null) {
1752        // slave paused and uploaded the task (no user-command) -> set waiting.
1753        taskStateEntity = DA.TaskState.Waiting;
1754      }
1755
1756      stateLogDao.Save(new DA.StateLog {
1757        State = taskStateEntity,
1758        DateTime = DateTime.Now,
1759        TaskId = task.TaskId,
1760        UserId = userId,
1761        SlaveId = slaveId,
1762        Exception = exception
1763      });
1764
1765      task.State = taskStateEntity;
1766
1767      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
1768          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
1769          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
1770        task.Command = null;
1771      }
1772    }
1773
1774    private void CheckProjectAvailability(IPersistenceManager pm, Guid projectId, DateTime date) {
1775      var projectDao = pm.ProjectDao;
1776      using (new PerformanceLogger("UpdateJob")) {
1777        var project = pm.UseTransaction(() => {
1778          return projectDao.GetById(projectId);
1779        });
1780        if (project != null) {
1781          if (project.StartDate > date) throw new ArgumentException("Cannot add job to specified project. The start date of the project is still in the future.");
1782          else if (project.EndDate < date) throw new ArgumentException("Cannot add job to specified project. The end date of the project is already in the past.");
1783        } else {
1784          throw new ArgumentException("Cannot add job to specified project. The project seems not to be available anymore.");
1785        }
1786      }
1787    }
1788
1789    private void EvaluateJobs(IPersistenceManager pm, IEnumerable<DT.Job> jobs) {
1790      if (jobs == null || !jobs.Any()) return;
1791
1792      var currentUserId = UserManager.CurrentUserId;     
1793      var taskDao = pm.TaskDao;
1794      var jobPermissionDao = pm.JobPermissionDao;
1795
1796      var statistics = taskDao.GetAll()
1797        .Where(x => jobs.Select(y => y.Id).Contains(x.JobId))
1798        .GroupBy(x => x.JobId)
1799        .Select(x => new {
1800          x.Key,
1801          TotalCount = x.Count(),
1802          CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
1803          FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
1804        })
1805        .ToList();
1806
1807      foreach (var job in jobs) {
1808        var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
1809        if (statistic != null) {
1810          job.JobCount = statistic.TotalCount;
1811          job.CalculatingCount = statistic.CalculatingCount;
1812          job.FinishedCount = statistic.FinishedCount;
1813        }
1814
1815        job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
1816
1817        if (currentUserId == job.OwnerUserId) {
1818          job.Permission = Permission.Full;
1819        } else {
1820          var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
1821          job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
1822        }
1823      }
1824    }
1825    #endregion
1826  }
1827}
Note: See TracBrowser for help on using the repository browser.