Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2839: finalized ProjectJobsView

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