Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 15628

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

#2839

  • updated TaskDao towards independency of the formerly used Task-Resource assignment entity
  • updated several permission/assignment handling service methods for client
  • added AssignedJobResource DTO
File size: 59.4 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, IEnumerable<Guid> resourceIds) {
73      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
74      var pm = PersistenceManager;
75      using (new PerformanceLogger("AddTask")) {
76        var taskDao = pm.TaskDao;
77        var stateLogDao = pm.StateLogDao;
78
79        var newTask = task.ToEntity();
80        newTask.JobData = taskData.ToEntity();
81        newTask.JobData.LastUpdate = DateTime.Now;
82        newTask.AssignedTaskResources.AddRange(resourceIds.Select(
83          x => new DA.AssignedTaskResource {
84            ResourceId = x
85          }));
86        newTask.State = DA.TaskState.Waiting;
87        return pm.UseTransaction(() => {
88          taskDao.Save(newTask);
89          pm.SubmitChanges();
90          stateLogDao.Save(new DA.StateLog {
91            State = DA.TaskState.Waiting,
92            DateTime = DateTime.Now,
93            TaskId = newTask.TaskId,
94            UserId = UserManager.CurrentUserId,
95            SlaveId = null,
96            Exception = null
97          });
98          pm.SubmitChanges();
99          return newTask.TaskId;
100        }, false, true);
101      }
102    }
103
104    public Guid AddTask(DT.Task task, DT.TaskData taskData) {
105      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
106      var pm = PersistenceManager;
107      using (new PerformanceLogger("AddTask")) {
108        var taskDao = pm.TaskDao;
109        var stateLogDao = pm.StateLogDao;
110        var newTask = task.ToEntity();
111        newTask.JobData = taskData.ToEntity();
112        newTask.JobData.LastUpdate = DateTime.Now;
113        newTask.State = DA.TaskState.Waiting;
114        return pm.UseTransaction(() => {
115          taskDao.Save(newTask);
116          pm.SubmitChanges();
117          stateLogDao.Save(new DA.StateLog {
118            State = DA.TaskState.Waiting,
119            DateTime = DateTime.Now,
120            TaskId = newTask.TaskId,
121            UserId = UserManager.CurrentUserId,
122            SlaveId = null,
123            Exception = null
124          });
125          pm.SubmitChanges();
126          return newTask.TaskId;
127        }, false, true);
128      }
129    }
130
131    public Guid AddChildTask(Guid parentTaskId, DT.Task task, DT.TaskData taskData) {
132      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
133      task.ParentTaskId = parentTaskId;
134      return AddTask(task, taskData);
135    }
136
137    public DT.Task GetTask(Guid taskId) {
138      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
139      AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
140      var pm = PersistenceManager;
141      using (new PerformanceLogger("GetTask")) {
142        var taskDao = pm.TaskDao;
143        return pm.UseTransaction(() => {
144          var task = taskDao.GetById(taskId);
145          return task.ToDto();
146        });
147      }
148    }
149
150    public IEnumerable<DT.LightweightTask> GetLightweightJobTasks(Guid jobId) {
151      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
152      AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
153      var pm = PersistenceManager;
154      using (new PerformanceLogger("GetLightweightJobTasks")) {
155        var taskDao = pm.TaskDao;
156        return pm.UseTransaction(() => {
157          return taskDao.GetByJobId(jobId)
158            .ToList()
159            .Select(x => new DT.LightweightTask {
160              Id = x.TaskId,
161              ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
162              ParentTaskId = x.ParentTaskId,
163              StateLog = x.StateLogs.OrderBy(y => y.DateTime)
164                                    .Select(z => z.ToDto())
165                                    .ToList(),
166              State = x.State.ToDto(),
167              Command = x.Command.ToDto(),
168              LastTaskDataUpdate = x.JobData.LastUpdate
169            })
170            .ToList();
171        }, false, true);
172      }
173    }
174
175    public IEnumerable<DT.LightweightTask> GetLightweightJobTasksWithoutStateLog(Guid jobId) {
176      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
177      AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
178      var pm = PersistenceManager;
179      using (new PerformanceLogger("GetLightweightJobTasksWithoutStateLog")) {
180        var taskDao = pm.TaskDao;
181        return pm.UseTransaction(() => {
182          return taskDao.GetByJobId(jobId)
183            .ToList()
184            .Select(x => new DT.LightweightTask {
185              Id = x.TaskId,
186              ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
187              ParentTaskId = x.ParentTaskId,
188              StateLog = new List<DT.StateLog>(),
189              State = x.State.ToDto(),
190              Command = x.Command.ToDto(),
191              LastTaskDataUpdate = x.JobData.LastUpdate
192            })
193            .ToList();
194        }, false, true);
195      }
196    }
197
198    public DT.TaskData GetTaskData(Guid taskId) {
199      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
200      AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
201      var pm = PersistenceManager;
202      using (new PerformanceLogger("GetTaskData")) {
203        var taskDataDao = pm.TaskDataDao;
204        return pm.UseTransaction(() => taskDataDao.GetById(taskId).ToDto());
205      }
206    }
207
208    public void UpdateTask(DT.Task taskDto) {
209      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
210      AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
211      var pm = PersistenceManager;
212      using (new PerformanceLogger("UpdateTask")) {
213        var taskDao = pm.TaskDao;
214        pm.UseTransaction(() => {
215          var task = taskDao.GetById(taskDto.Id);
216          taskDto.CopyToEntity(task);
217          pm.SubmitChanges();
218        });
219      }
220    }
221
222    public void UpdateTaskData(DT.Task taskDto, DT.TaskData taskDataDto) {
223      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
224      AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
225      var pm = PersistenceManager;
226      using (new PerformanceLogger("UpdateTaskData")) {
227        var taskDao = pm.TaskDao;
228        var taskDataDao = pm.TaskDataDao;
229        pm.UseTransaction(() => {
230          var task = taskDao.GetById(taskDto.Id);
231          var taskData = taskDataDao.GetById(taskDataDto.TaskId);
232          taskDto.CopyToEntity(task);
233          taskDataDto.CopyToEntity(taskData);
234          taskData.LastUpdate = DateTime.Now;
235          pm.SubmitChanges();
236        });
237      }
238    }
239
240    public DT.Task UpdateTaskState(Guid taskId, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
241      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
242      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
243      var pm = PersistenceManager;
244      using (new PerformanceLogger("UpdateTaskState")) {
245        var taskDao = pm.TaskDao;
246        return pm.UseTransaction(() => {
247          var task = taskDao.GetById(taskId);
248          UpdateTaskState(pm, task, taskState, slaveId, userId, exception);
249          pm.SubmitChanges();
250          return task.ToDto();
251        });
252      }
253    }
254    #endregion
255
256    #region Task Control Methods
257    public void StopTask(Guid taskId) {
258      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
259      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
260      var pm = PersistenceManager;
261      using (new PerformanceLogger("StopTask")) {
262        var taskDao = pm.TaskDao;
263        pm.UseTransaction(() => {
264          var task = taskDao.GetById(taskId);
265          if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
266            task.Command = DA.Command.Stop;
267          } else if (task.State != DA.TaskState.Aborted
268                     && task.State != DA.TaskState.Finished
269                     && task.State != DA.TaskState.Failed) {
270            UpdateTaskState(pm, task, DT.TaskState.Aborted, null, null, string.Empty);
271          }
272          pm.SubmitChanges();
273        });
274      }
275    }
276
277    public void PauseTask(Guid taskId) {
278      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
279      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
280      var pm = PersistenceManager;
281      using (new PerformanceLogger("PauseTask")) {
282        var taskDao = pm.TaskDao;
283        pm.UseTransaction(() => {
284          var task = taskDao.GetById(taskId);
285          if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
286            task.Command = DA.Command.Pause;
287          } else if (task.State != DA.TaskState.Paused
288                     && task.State != DA.TaskState.Aborted
289                     && task.State != DA.TaskState.Finished
290                     && task.State != DA.TaskState.Failed) {
291            UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
292          }
293          pm.SubmitChanges();
294        });
295      }
296    }
297
298    public void RestartTask(Guid taskId) {
299      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
300      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
301      var pm = PersistenceManager;
302      using (new PerformanceLogger("RestartTask")) {
303        var taskDao = pm.TaskDao;
304        pm.UseTransaction(() => {
305          var task = taskDao.GetById(taskId);
306          task.Command = null;
307          UpdateTaskState(pm, task, DT.TaskState.Waiting, null, UserManager.CurrentUserId, string.Empty);
308          pm.SubmitChanges();
309        });
310      }
311    }
312    #endregion
313
314    #region Job Methods
315    public DT.Job GetJob(Guid id) {
316      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
317      AuthorizationManager.AuthorizeForJob(id, DT.Permission.Read);
318      var pm = PersistenceManager;
319      using (new PerformanceLogger("GetJob")) {
320        var jobDao = pm.JobDao;
321        var jobPermissionDao = pm.JobPermissionDao;
322        var taskDao = pm.TaskDao;
323        var currentUserId = UserManager.CurrentUserId;
324        return pm.UseTransaction(() => {
325          var job = jobDao.GetById(id).ToDto();
326          if (job != null) {
327            var statistics = taskDao.GetByJobId(job.Id)
328              .GroupBy(x => x.JobId)
329              .Select(x => new {
330                TotalCount = x.Count(),
331                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
332                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
333              }).FirstOrDefault();
334            if (statistics != null) {
335              job.JobCount = statistics.TotalCount;
336              job.CalculatingCount = statistics.CalculatingCount;
337              job.FinishedCount = statistics.FinishedCount;
338            }
339            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
340            if (currentUserId == job.OwnerUserId) {
341              job.Permission = Permission.Full;
342            } else {
343              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
344              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
345            }
346          }
347          return job;
348        });
349      }
350    }
351
352    public IEnumerable<DT.Job> GetJobs() {
353      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
354      var pm = PersistenceManager;
355      using (new PerformanceLogger("GetJobs")) {
356        // TODO-JAN: optimization potential - avoid using too many joins in linq
357        var jobDao = pm.JobDao;
358        var jobPermissionDao = pm.JobPermissionDao;
359        var taskDao = pm.TaskDao;
360        var currentUserId = UserManager.CurrentUserId;
361        return pm.UseTransaction(() => {
362          var jobs = jobDao.GetAll()
363            .Where(x => x.OwnerUserId == currentUserId
364                     || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
365                                                 && y.GrantedUserId == currentUserId) > 0)
366            .Select(x => x.ToDto())
367            .ToList();
368          // calculate stats only for owned & permitted jobs; TODO: query only needed ones, not all
369          var statistics = taskDao.GetAll()
370              .Where(x => jobs.Select(y => y.Id).Contains(x.JobId))
371              .GroupBy(x => x.JobId)
372              .Select(x => new {
373                x.Key,
374                TotalCount = x.Count(),
375                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
376                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
377              })
378              .ToList();
379          foreach (var job in jobs) {
380            var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
381            if (statistic != null) {
382              job.JobCount = statistic.TotalCount;
383              job.CalculatingCount = statistic.CalculatingCount;
384              job.FinishedCount = statistic.FinishedCount;
385            }
386            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
387            if (currentUserId == job.OwnerUserId) {
388              job.Permission = Permission.Full;
389            } else {
390              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
391              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
392            }
393          }
394          return jobs;
395        });
396      }
397    }
398
399    public Guid AddJob(DT.Job jobDto) {
400      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
401      var pm = PersistenceManager;
402      using (new PerformanceLogger("AddJob")) {
403        var jobDao = pm.JobDao;
404        var userPriorityDao = pm.UserPriorityDao;
405        return pm.UseTransaction(() => {
406          jobDto.OwnerUserId = UserManager.CurrentUserId;
407          jobDto.DateCreated = DateTime.Now;
408          var job = jobDao.Save(jobDto.ToEntity());
409          if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
410            userPriorityDao.Save(new DA.UserPriority {
411              UserId = jobDto.OwnerUserId,
412              DateEnqueued = jobDto.DateCreated
413            });
414          }
415          pm.SubmitChanges();
416          return job.JobId;
417        });
418      }
419    }
420
421    public Guid AddJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
422      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
423      // check user - project
424      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
425      // check project - resources
426      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
427      var pm = PersistenceManager;
428      using (new PerformanceLogger("AddJob")) {
429        var jobDao = pm.JobDao;
430        var userPriorityDao = pm.UserPriorityDao;
431
432        return pm.UseTransaction(() => {
433          var newJob = jobDto.ToEntity();
434          newJob.OwnerUserId = UserManager.CurrentUserId;
435          newJob.DateCreated = DateTime.Now;
436
437          // add resource assignments
438          newJob.AssignedJobResources.AddRange(resourceIds.Select(
439            x => new DA.AssignedJobResource {
440              ResourceId = x
441            }));
442
443          var job = jobDao.Save(newJob);
444          if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
445            userPriorityDao.Save(new DA.UserPriority {
446              UserId = jobDto.OwnerUserId,
447              DateEnqueued = jobDto.DateCreated
448            });
449          }
450          pm.SubmitChanges();
451          return job.JobId;
452        });
453      }
454    }
455
456    public void UpdateJob(DT.Job jobDto) {
457      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
458      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
459      var pm = PersistenceManager;
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          }
469          jobDto.CopyToEntity(job);
470          if (!exists) {
471            jobDao.Save(job);
472          }
473          pm.SubmitChanges();
474        });
475      }
476    }
477
478    public void UpdateJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
479      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
480      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
481      // check user - project permission
482      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
483      // check project - resources permission
484      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
485
486      var pm = PersistenceManager;
487      using (new PerformanceLogger("UpdateJob")) {
488        bool exists = true;
489        var jobDao = pm.JobDao;
490        pm.UseTransaction(() => {
491          var job = jobDao.GetById(jobDto.Id);
492          if (job == null) {
493            exists = false;
494            job = new DA.Job();
495          }
496          jobDto.CopyToEntity(job);
497
498          if (!exists) {
499            // add resource assignments
500            job.AssignedJobResources.AddRange(resourceIds.Select(
501              x => new DA.AssignedJobResource {
502                ResourceId = x
503              }));
504            jobDao.Save(job);
505          } else {
506            var addedJobResourceIds = resourceIds.Except(job.AssignedJobResources.Select(x => x.ResourceId));
507            var removedJobResourceIds = job.AssignedJobResources.Select(x => x.ResourceId).Except(resourceIds);
508           
509            // remove resource assignments
510            foreach(var rid in removedJobResourceIds) {
511              var ajr = job.AssignedJobResources.Where(x => x.ResourceId == rid).SingleOrDefault();
512              if (ajr != null) job.AssignedJobResources.Remove(ajr);
513            }
514
515            // add resource assignments
516            job.AssignedJobResources.AddRange(addedJobResourceIds.Select(
517              x => new DA.AssignedJobResource {
518                ResourceId = x
519              }));
520          }
521          pm.SubmitChanges();
522        });
523      }
524    }
525
526    public void DeleteJob(Guid jobId) {
527      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
528      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
529      var pm = PersistenceManager;
530      using (new PerformanceLogger("DeleteJob")) {
531        var jobDao = pm.JobDao;
532        pm.UseTransaction(() => {
533          // not necessary anymore: child tasks will be deleted by db-trigger
534          // now: tasks are deleted by jobId
535          // entries in AssignedJobResource will be deleted by foreign key clause CASCADE ON DELETE
536          jobDao.Delete(jobId);
537          pm.SubmitChanges();
538        });
539      }
540    }
541
542    public IEnumerable<DT.AssignedJobResource> GetAssignedResourcesForJob(Guid jobId) {
543      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
544      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
545      var pm = PersistenceManager;
546      var assignedJobResourceDao = pm.AssignedJobResourceDao;
547      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
548        return pm.UseTransaction(() =>
549          assignedJobResourceDao.GetByJobId(jobId)
550          .Select(x => x.ToDto())
551          .ToList()
552        );
553      }
554    }
555    #endregion
556
557    #region JobPermission Methods
558    public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
559      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
560      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
561      var pm = PersistenceManager;
562      using (new PerformanceLogger("GrantPermission")) {
563        var jobPermissionDao = pm.JobPermissionDao;
564        var currentUserId = UserManager.CurrentUserId;
565        pm.UseTransaction(() => {
566          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
567          pm.SubmitChanges();
568        });
569      }
570    }
571
572    public void RevokePermission(Guid jobId, Guid grantedUserId) {
573      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
574      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
575      var pm = PersistenceManager;
576      using (new PerformanceLogger("RevokePermission")) {
577        var jobPermissionDao = pm.JobPermissionDao;
578        var currentUserId = UserManager.CurrentUserId;
579        pm.UseTransaction(() => {
580          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
581          pm.SubmitChanges();
582        });
583      }
584    }
585
586    public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
587      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
588      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
589      var pm = PersistenceManager;
590      using (new PerformanceLogger("GetJobPermissions")) {
591        var jobPermissionDao = pm.JobPermissionDao;
592        return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
593          .Select(x => x.ToDto())
594          .ToList()
595        );
596      }
597    }
598
599    // BackwardsCompatibility3.3
600    #region Backwards compatible code, remove with 3.4
601    public bool IsAllowedPrivileged() {
602      return true;
603    }
604    #endregion
605    #endregion
606
607    #region Login Methods
608    public void Hello(DT.Slave slaveInfo) {
609      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
610      if (UserManager.CurrentUser.UserName != "hiveslave") {
611        slaveInfo.OwnerUserId = UserManager.CurrentUserId;
612      }
613      var pm = PersistenceManager;
614      using (new PerformanceLogger("Hello")) {
615        var slaveDao = pm.SlaveDao;
616        pm.UseTransaction(() => {
617          var slave = slaveDao.GetById(slaveInfo.Id);
618          if (slave == null) {
619            slaveDao.Save(slaveInfo.ToEntity());
620          } else {
621            bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
622            Guid? oldParentResourceId = slave.ParentResourceId;
623            slaveInfo.CopyToEntity(slave);
624            slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
625            slave.ParentResourceId = oldParentResourceId;
626            slave.LastHeartbeat = DateTime.Now;
627            slave.SlaveState = DA.SlaveState.Idle;
628          }
629          pm.SubmitChanges();
630        });
631      }
632    }
633
634    public void GoodBye(Guid slaveId) {
635      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
636      var pm = PersistenceManager;
637      using (new PerformanceLogger("GoodBye")) {
638        var slaveDao = pm.SlaveDao;
639        pm.UseTransaction(() => {
640          var slave = slaveDao.GetById(slaveId);
641          if (slave != null) {
642            slave.SlaveState = DA.SlaveState.Offline;
643            pm.SubmitChanges();
644          }
645        });
646      }
647    }
648    #endregion
649
650    #region Heartbeat Methods
651    public List<MessageContainer> Heartbeat(DT.Heartbeat heartbeat) {
652      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
653      List<MessageContainer> result = new List<MessageContainer>();
654      try {
655        using (new PerformanceLogger("ProcessHeartbeat")) {
656          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
657        }
658      } catch (Exception ex) {
659        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
660      }
661      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
662        TriggerEventManager(false);
663      }
664      return result;
665    }
666    #endregion
667
668    #region Plugin Methods
669    public DT.Plugin GetPlugin(Guid pluginId) {
670      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
671      var pm = PersistenceManager;
672      using (new PerformanceLogger("GetPlugin")) {
673        var pluginDao = pm.PluginDao;
674        return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
675      }
676    }
677
678    public Guid AddPlugin(DT.Plugin plugin, List<DT.PluginData> pluginData) {
679      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
680      var pm = PersistenceManager;
681      using (new PerformanceLogger("AddPlugin")) {
682        var pluginDao = pm.PluginDao;
683        plugin.UserId = UserManager.CurrentUserId;
684        plugin.DateCreated = DateTime.Now;
685        return pm.UseTransaction(() => {
686          var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
687          if (pluginEntity != null) {
688            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(pluginEntity.PluginId));
689          }
690          pluginEntity = plugin.ToEntity();
691          foreach (var data in pluginData) {
692            data.PluginId = default(Guid); // real id will be assigned from linq2sql
693            pluginEntity.PluginData.Add(data.ToEntity());
694          }
695          pluginDao.Save(pluginEntity);
696          pm.SubmitChanges();
697          return pluginEntity.PluginId;
698        });
699      }
700    }
701
702    public IEnumerable<DT.Plugin> GetPlugins() {
703      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
704      var pm = PersistenceManager;
705      using (new PerformanceLogger("GetPlugins")) {
706        var pluginDao = pm.PluginDao;
707        return pm.UseTransaction(() => pluginDao.GetAll()
708          .Where(x => x.Hash != null)
709          .Select(x => x.ToDto())
710          .ToList()
711        );
712      }
713    }
714
715    public IEnumerable<DT.PluginData> GetPluginDatas(List<Guid> pluginIds) {
716      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
717      var pm = PersistenceManager;
718      using (new PerformanceLogger("GetPluginDatas")) {
719        var pluginDataDao = pm.PluginDataDao;
720        return pm.UseTransaction(() => pluginDataDao.GetAll()
721            .Where(x => pluginIds.Contains(x.PluginId))
722            .Select(x => x.ToDto())
723            .ToList()
724        );
725      }
726    }
727    #endregion
728
729    #region Project Methods
730    public Guid AddProject(DT.Project projectDto) {
731      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
732      var pm = PersistenceManager;
733      using (new PerformanceLogger("AddProject")) {
734        var projectDao = pm.ProjectDao;
735        return pm.UseTransaction(() => {
736          var project = projectDao.Save(projectDto.ToEntity());
737          pm.SubmitChanges();
738          return project.ProjectId;
739        });
740      }
741    }
742
743    public void UpdateProject(DT.Project projectDto) {
744      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
745      var pm = PersistenceManager;
746      using (new PerformanceLogger("UpdateProject")) {
747        var projectDao = pm.ProjectDao;
748        pm.UseTransaction(() => {
749          var project = projectDao.GetById(projectDto.Id);
750          if (project != null) {
751            projectDto.CopyToEntity(project);
752          } else {
753            projectDao.Save(projectDto.ToEntity());
754          }
755          pm.SubmitChanges();
756        });
757      }
758    }
759
760    public void DeleteProject(Guid projectId) {
761      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
762      var pm = PersistenceManager;
763      using (new PerformanceLogger("DeleteProject")) {
764        var projectDao = pm.ProjectDao;
765        var assignedJobResourceDao = pm.AssignedJobResourceDao;
766        pm.UseTransaction(() => {
767          assignedJobResourceDao.DeleteByProjectId(projectId);
768          projectDao.Delete(projectId);
769          pm.SubmitChanges();
770        });
771      }
772    }
773
774    public DT.Project GetProject(Guid projectId) {
775      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
776      var pm = PersistenceManager;
777      using (new PerformanceLogger("GetProject")) {
778        var projectDao = pm.ProjectDao;
779        return pm.UseTransaction(() => projectDao.GetById(projectId).ToDto());
780      }
781    }
782
783    // query granted projects for use (i.e. to calculate on)
784    public IEnumerable<DT.Project> GetProjects() {
785      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
786      //bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
787      var pm = PersistenceManager;
788      using (new PerformanceLogger("GetProjects")) {
789        var projectDao = pm.ProjectDao;
790        //var projectPermissionDao = pm.ProjectPermissionDao;
791        var currentUserId = UserManager.CurrentUserId;
792        var userAndGroupIds = new List<Guid> { currentUserId };
793        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
794        return pm.UseTransaction(() => {
795          return projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
796            .Select(x => x.ToDto()).ToList();
797        });
798      }
799    }
800
801    public IEnumerable<DT.Project> GetProjectsForAdministration() {
802      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
803      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
804      var pm = PersistenceManager;
805      using (new PerformanceLogger("GetProjectsForAdministration")) {
806        var projectDao = pm.ProjectDao;
807        //var projectPermissionDao = pm.ProjectPermissionDao;
808       
809        return pm.UseTransaction(() => {
810          if(isAdministrator) {
811            return projectDao.GetAll().Select(x => x.ToDto()).ToList();
812          } else {
813            var currentUserId = UserManager.CurrentUserId;
814            return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId)
815              .Select(x => x.ToDto()).ToList();
816
817          }
818
819          //var projectPermissions = projectPermissionDao.GetAll();
820          //return projectDao.GetAll().ToList()
821          //  .Where(x => isAdministrator
822          //    || x.OwnerUserId == currentUserId
823          //    || UserManager.VerifyUser(currentUserId, projectPermissions
824          //        .Where(y => y.ProjectId == x.ProjectId)
825          //        .Select(z => z.GrantedUserId)
826          //        .ToList())
827          //    )
828          //  .Select(x => x.ToDto())
829          //  .ToList();
830        });
831      }
832    }
833    #endregion
834
835    #region ProjectPermission Methods
836    public void SaveProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool reassign, bool cascading, bool reassignCascading) {
837      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
838      if (projectId == null || grantedUserIds == null) return;
839      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
840      var pm = PersistenceManager;
841      using (new PerformanceLogger("GrantProjectPermissions")) {
842        var projectDao = pm.ProjectDao;
843        var projectPermissionDao = pm.ProjectPermissionDao;
844        var assignedJobResourceDao = pm.AssignedJobResourceDao;
845
846        pm.UseTransaction(() => {
847          var project = projectDao.GetById(projectId);
848          if (project == null) return;
849          //if (project.ProjectPermissions == null) project.ProjectPermissions = new System.Data.Linq.EntitySet<DA.ProjectPermission>();
850          var projectPermissions = project.ProjectPermissions.Select(x => x.GrantedUserId);
851          var addedPermissions = grantedUserIds.Except(projectPermissions);
852          var removedPermissions = projectPermissions.Except(grantedUserIds);
853
854          // remove job assignments and project permissions
855          if (reassign) {
856            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
857            project.ProjectPermissions.Clear();
858          } else {
859            assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, removedPermissions);
860            foreach(var item in project.ProjectPermissions.ToList().Where(x => removedPermissions.Contains(x.GrantedUserId))) {
861              project.ProjectPermissions.Remove(item);
862            }
863          }
864          pm.SubmitChanges();
865
866          // add project permissions
867          foreach (var id in grantedUserIds) {
868            if(project.ProjectPermissions.All(x => x.GrantedUserId != id)) {
869              project.ProjectPermissions.Add(new DA.ProjectPermission {
870                GrantedUserId = id,
871                GrantedByUserId = UserManager.CurrentUserId
872              });
873            }
874          }
875          pm.SubmitChanges();
876
877          if (cascading) {
878            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
879            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
880
881            // remove job assignments
882            if (reassignCascading) {
883              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
884            } else {
885              assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, removedPermissions);
886            }
887
888            foreach(var p in childProjects) {
889              // remove project permissions
890              if(reassignCascading) {
891                p.ProjectPermissions.Clear();
892              } else {
893                foreach(var item in p.ProjectPermissions.ToList().Where(x => removedPermissions.Contains(x.GrantedUserId))) {
894                  p.ProjectPermissions.Remove(item);
895                }
896              }
897              pm.SubmitChanges();
898
899              // add project permissions
900              foreach (var id in grantedUserIds) {
901                if (p.ProjectPermissions.All(x => x.GrantedUserId != id)) {
902                  p.ProjectPermissions.Add(new DA.ProjectPermission {
903                    GrantedUserId = id,
904                    GrantedByUserId = UserManager.CurrentUserId
905                  });
906                }
907              }
908            }
909          }
910          pm.SubmitChanges();
911        });
912      }
913    }
914
915    public void GrantProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
916      throw new NotImplementedException();
917    }
918
919    public void RevokeProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
920      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
921      if (projectId == null || grantedUserIds == null || !grantedUserIds.Any()) return;
922      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
923      var pm = PersistenceManager;
924      using (new PerformanceLogger("RevokeProjectPermissions")) {
925        var projectPermissionDao = pm.ProjectPermissionDao;
926        var projectDao = pm.ProjectDao;
927        var assignedJobResourceDao = pm.AssignedJobResourceDao;
928        pm.UseTransaction(() => {
929          if (cascading) {
930            var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
931            projectPermissionDao.DeleteByProjectIdsAndGrantedUserIds(childProjectIds, grantedUserIds);
932            assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, grantedUserIds);
933          }
934          projectPermissionDao.DeleteByProjectIdAndGrantedUserIds(projectId, grantedUserIds);
935          assignedJobResourceDao.DeleteByProjectIdAndUserIds(projectId, grantedUserIds);
936          pm.SubmitChanges();
937        });
938      }
939    }
940
941    public IEnumerable<DT.ProjectPermission> GetProjectPermissions(Guid projectId) {
942      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
943      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
944      var pm = PersistenceManager;
945      using (new PerformanceLogger("GetProjectPermissions")) {
946        var projectPermissionDao = pm.ProjectPermissionDao;
947        return pm.UseTransaction(() => projectPermissionDao.GetByProjectId(projectId)
948          .Select(x => x.ToDto())
949          .ToList()
950        );
951      }
952    }
953    #endregion
954
955    #region AssignedProjectResource Methods
956    // basic: remove and add assignments (resourceIds) to projectId and its depending jobs
957    // reassign: clear all assignments from project and its depending jobs, before adding new ones (resourceIds)
958    // cascading: "basic" mode for child-projects
959    // reassignCascading: "reassign" mode for child-projects
960    public void SaveProjectResourceAssignments(Guid projectId, List<Guid> resourceIds, bool reassign, bool cascading, bool reassignCascading) {
961      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
962      if (projectId == null || resourceIds == null) return;
963      AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
964      var pm = PersistenceManager;
965      using (new PerformanceLogger("AssignProjectResources")) {
966        var projectDao = pm.ProjectDao;
967        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
968        var assignedJobResourceDao = pm.AssignedJobResourceDao;
969        pm.UseTransaction(() => {
970          var project = projectDao.GetById(projectId);
971          var assignedResources = project.AssignedProjectResources.Select(x => x.ResourceId);
972          var addedAssignments = resourceIds.Except(assignedResources);
973          var removedAssignments = assignedResources.Except(resourceIds);
974
975          // remove job and project assignments
976          if (reassign) {
977            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
978            //assignedProjectResourceDao.DeleteByProjectIds(new List<Guid> { projectId });
979            project.AssignedProjectResources.Clear();
980          } else {
981            assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, removedAssignments);
982            //assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(projectId, removedAssignments);
983            foreach (var item in project.AssignedProjectResources.ToList().Where(x => removedAssignments.Contains(x.ResourceId))) {
984              project.AssignedProjectResources.Remove(item);
985            }
986          }
987          pm.SubmitChanges();
988
989          // add project assignments
990          foreach (var id in resourceIds) {
991            if (project.AssignedProjectResources.All(x => x.ResourceId != id)) {
992              project.AssignedProjectResources.Add(new DA.AssignedProjectResource {
993                ResourceId = id
994              });
995            }
996          }
997          pm.SubmitChanges();
998
999          if (cascading) {
1000            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
1001
1002            // remove job assignments
1003            if (reassignCascading) {
1004              assignedJobResourceDao.DeleteByProjectIds(childProjects.Select(x => x.ProjectId).ToList());
1005            } else {
1006              var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
1007              assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, removedAssignments);
1008            }
1009            foreach (var p in childProjects) {
1010              // remove project assignments
1011              if (reassignCascading) {
1012                //assignedProjectResourceDao.DeleteByProjectIds(new List<Guid> { p.ProjectId });
1013                p.AssignedProjectResources.Clear();
1014              } else {
1015                //assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(p.ProjectId, removedAssignments);
1016                foreach (var item in p.AssignedProjectResources.ToList().Where(x => removedAssignments.Contains(x.ResourceId))) {
1017                  p.AssignedProjectResources.Remove(item);
1018                }
1019              }
1020              pm.SubmitChanges();
1021
1022              // add project assignments
1023              foreach (var id in resourceIds) {
1024                if(p.AssignedProjectResources.All(x => x.ResourceId != id)) {
1025                  p.AssignedProjectResources.Add(new DA.AssignedProjectResource {
1026                    ResourceId = id
1027                  });
1028                }
1029              }
1030            }
1031          }
1032          pm.SubmitChanges();
1033        });
1034      }
1035    }
1036
1037    public void AssignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
1038      throw new NotImplementedException();
1039    }
1040
1041    // basic: unassign resourceIds from project and depending jobs
1042    // cascading: unassign resourceIds from all child-projects and their depending jobs
1043    public void UnassignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
1044      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1045      if (projectId == null || resourceIds == null || !resourceIds.Any()) return;
1046      AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
1047      var pm = PersistenceManager;
1048      using (new PerformanceLogger("UnassignProjectResources")) {
1049        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1050        var assignedJobResourceDao = pm.AssignedJobResourceDao;
1051        var projectDao = pm.ProjectDao;
1052        pm.UseTransaction(() => {
1053          if (cascading) {
1054            var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
1055            assignedProjectResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
1056            assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
1057          }
1058          assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
1059          assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
1060          pm.SubmitChanges();
1061        });
1062      }
1063    }
1064
1065    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProject(Guid projectId) {
1066      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1067      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, projectId);
1068      var pm = PersistenceManager;
1069      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
1070        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1071        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
1072          .Select(x => x.ToDto())
1073          .ToList()
1074        );
1075      }
1076    }
1077
1078    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectAdministration(Guid projectId) {
1079      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1080      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
1081      var pm = PersistenceManager;
1082      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
1083        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1084        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
1085          .Select(x => x.ToDto())
1086          .ToList()
1087        );
1088      }
1089    }
1090
1091    #endregion
1092
1093    #region Slave Methods
1094    public Guid AddSlave(DT.Slave slaveDto) {
1095      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1096      var pm = PersistenceManager;
1097      using (new PerformanceLogger("AddSlave")) {
1098        var slaveDao = pm.SlaveDao;
1099        return pm.UseTransaction(() => {
1100          var slave = slaveDao.Save(slaveDto.ToEntity());
1101          pm.SubmitChanges();
1102          return slave.ResourceId;
1103        });
1104      }
1105    }
1106
1107    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
1108      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1109      var pm = PersistenceManager;
1110      using (new PerformanceLogger("AddSlaveGroup")) {
1111        var slaveGroupDao = pm.SlaveGroupDao;
1112        return pm.UseTransaction(() => {
1113          if (slaveGroupDto.Id == Guid.Empty) {
1114            slaveGroupDto.Id = Guid.NewGuid();
1115          }
1116          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
1117          pm.SubmitChanges();
1118          return slaveGroup.ResourceId;
1119        });
1120      }
1121    }
1122
1123    public DT.Slave GetSlave(Guid slaveId) {
1124      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1125      var pm = PersistenceManager;
1126      using (new PerformanceLogger("GetSlave")) {
1127        var slaveDao = pm.SlaveDao;
1128        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
1129      }
1130    }
1131
1132    public IEnumerable<DT.Slave> GetSlaves() {
1133      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1134      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
1135      var pm = PersistenceManager;
1136      using (new PerformanceLogger("GetSlaves")) {
1137        var slaveDao = pm.SlaveDao;
1138        //var projectPermissionDao = pm.ProjectPermissionDao;
1139        var currentUserId = UserManager.CurrentUserId;
1140        return pm.UseTransaction(() => {
1141            return slaveDao.GetAll().ToList()
1142              .Where( x => isAdministrator
1143              || x.OwnerUserId == null
1144              || x.OwnerUserId == currentUserId)
1145              .Select(x => x.ToDto())
1146              .ToList();
1147          //var projectPermissions = projectPermissionDao.GetAll();
1148          //return slaveDao.GetAll().ToList()
1149          //  .Where(x => isAdministrator
1150          //    || x.OwnerUserId == null
1151          //    || x.OwnerUserId == currentUserId
1152          //    || UserManager.VerifyUser(currentUserId, projectPermissions
1153          //        //.Where(y => y.ResourceId == x.ResourceId)
1154          //        .Select(z => z.GrantedUserId)
1155          //        .ToList())
1156          //    )
1157          //  .Select(x => x.ToDto())
1158          //  .ToList();
1159        });
1160      }
1161    }
1162
1163    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
1164      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1165      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
1166      var pm = PersistenceManager;
1167      using (new PerformanceLogger("GetSlaveGroups")) {
1168        var slaveGroupDao = pm.SlaveGroupDao;
1169        var projectPermissionDao = pm.ProjectPermissionDao;
1170        var currentUserId = UserManager.CurrentUserId;
1171        return pm.UseTransaction(() => {
1172          //var projectPermissions = projectPermissionDao.GetAll();
1173          return slaveGroupDao.GetAll().ToList()
1174            .Where(x => isAdministrator
1175              || x.OwnerUserId == null
1176              || x.OwnerUserId == currentUserId
1177              //|| UserManager.VerifyUser(currentUserId, projectPermissions
1178              //    //.Where(y => y.ResourceId == x.ResourceId)
1179              //    .Select(z => z.GrantedUserId)
1180              //    .ToList())
1181             )
1182            .Select(x => x.ToDto())
1183            .ToList();
1184        });
1185      }
1186    }
1187
1188    public void UpdateSlave(DT.Slave slaveDto) {
1189      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1190      var pm = PersistenceManager;
1191      using (new PerformanceLogger("UpdateSlave")) {
1192        var slaveDao = pm.SlaveDao;
1193        pm.UseTransaction(() => {
1194          var slave = slaveDao.GetById(slaveDto.Id);
1195          if (slave != null) {
1196            slaveDto.CopyToEntity(slave);
1197          } else {
1198            slaveDao.Save(slaveDto.ToEntity());
1199          }
1200          pm.SubmitChanges();
1201        });
1202      }
1203    }
1204
1205    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
1206      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1207      var pm = PersistenceManager;
1208      using (new PerformanceLogger("UpdateSlaveGroup")) {
1209        var slaveGroupDao = pm.SlaveGroupDao;
1210        pm.UseTransaction(() => {
1211          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
1212          if (slaveGroup != null) {
1213            slaveGroupDto.CopyToEntity(slaveGroup);
1214          } else {
1215            slaveGroupDao.Save(slaveGroupDto.ToEntity());
1216          }
1217          pm.SubmitChanges();
1218        });
1219      }
1220    }
1221
1222    public void DeleteSlave(Guid slaveId) {
1223      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1224      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
1225      var pm = PersistenceManager;
1226      using (new PerformanceLogger("DeleteSlave")) {
1227        var slaveDao = pm.SlaveDao;
1228        pm.UseTransaction(() => {
1229          slaveDao.Delete(slaveId);
1230          pm.SubmitChanges();
1231        });
1232      }
1233    }
1234
1235    public void DeleteSlaveGroup(Guid slaveGroupId) {
1236      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1237      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
1238      var pm = PersistenceManager;
1239      using (new PerformanceLogger("DeleteSlaveGroup")) {
1240        var slaveGroupDao = pm.SlaveGroupDao;
1241        pm.UseTransaction(() => {
1242          slaveGroupDao.Delete(slaveGroupId);
1243          pm.SubmitChanges();
1244        });
1245      }
1246    }
1247
1248    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
1249      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1250      var pm = PersistenceManager;
1251      using (new PerformanceLogger("AddResourceToGroup")) {
1252        var resourceDao = pm.ResourceDao;
1253        pm.UseTransaction(() => {
1254          var resource = resourceDao.GetById(resourceId);
1255          resource.ParentResourceId = slaveGroupId;
1256          pm.SubmitChanges();
1257        });
1258      }
1259    }
1260
1261    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
1262      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1263      var pm = PersistenceManager;
1264      using (new PerformanceLogger("RemoveResourceFromGroup")) {
1265        var resourceDao = pm.ResourceDao;
1266        pm.UseTransaction(() => {
1267          var resource = resourceDao.GetById(resourceId);
1268          resource.ParentResourceId = null;
1269          pm.SubmitChanges();
1270        });
1271      }
1272    }
1273
1274    public Guid GetResourceId(string resourceName) {
1275      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1276      var pm = PersistenceManager;
1277      using (new PerformanceLogger("GetResourceId")) {
1278        var resourceDao = pm.ResourceDao;
1279        return pm.UseTransaction(() => {
1280          var resource = resourceDao.GetByName(resourceName);
1281          return resource != null ? resource.ResourceId : Guid.Empty;
1282        });
1283      }
1284    }
1285
1286    public void TriggerEventManager(bool force) {
1287      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1288      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
1289      bool cleanup;
1290      var pm = PersistenceManager;
1291      using (new PerformanceLogger("TriggerEventManager")) {
1292        cleanup = false;
1293        var lifecycleDao = pm.LifecycleDao;
1294        pm.UseTransaction(() => {
1295          var lastLifecycle = lifecycleDao.GetLastLifecycle();
1296          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
1297          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
1298            lifecycleDao.UpdateLifecycle();
1299            cleanup = true;
1300            pm.SubmitChanges();
1301          }
1302        }, true);
1303      }
1304      if (cleanup) {
1305        EventManager.Cleanup();
1306      }
1307    }
1308
1309    public int GetNewHeartbeatInterval(Guid slaveId) {
1310      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
1311      var pm = PersistenceManager;
1312      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
1313        var slaveDao = pm.SlaveDao;
1314        return pm.UseTransaction(() => {
1315          var slave = slaveDao.GetById(slaveId);
1316          if (slave != null) {
1317            return slave.HbInterval;
1318          }
1319          return -1;
1320        });
1321      }
1322    }
1323    #endregion
1324
1325    #region Downtime Methods
1326    public Guid AddDowntime(DT.Downtime downtimeDto) {
1327      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1328      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
1329      var pm = PersistenceManager;
1330      using (new PerformanceLogger("AddDowntime")) {
1331        var downtimeDao = pm.DowntimeDao;
1332        return pm.UseTransaction(() => {
1333          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
1334          pm.SubmitChanges();
1335          return downtime.ResourceId;
1336        });
1337      }
1338    }
1339
1340    public void DeleteDowntime(Guid downtimeId) {
1341      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1342      var pm = PersistenceManager;
1343      using (new PerformanceLogger("DeleteDowntime")) {
1344        var downtimeDao = pm.DowntimeDao;
1345        pm.UseTransaction(() => {
1346          downtimeDao.Delete(downtimeId);
1347          pm.SubmitChanges();
1348        });
1349      }
1350    }
1351
1352    public void UpdateDowntime(DT.Downtime downtimeDto) {
1353      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1354      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
1355      var pm = PersistenceManager;
1356      using (new PerformanceLogger("UpdateDowntime")) {
1357        var downtimeDao = pm.DowntimeDao;
1358        pm.UseTransaction(() => {
1359          var downtime = downtimeDao.GetById(downtimeDto.Id);
1360          if (downtime != null) {
1361            downtimeDto.CopyToEntity(downtime);
1362          } else {
1363            downtimeDao.Save(downtimeDto.ToEntity());
1364          }
1365          pm.SubmitChanges();
1366        });
1367      }
1368    }
1369
1370    public IEnumerable<DT.Downtime> GetDowntimesForResource(Guid resourceId) {
1371      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1372      var pm = PersistenceManager;
1373      using (new PerformanceLogger("GetDowntimesForResource")) {
1374        var downtimeDao = pm.DowntimeDao;
1375        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
1376          .Select(x => x.ToDto())
1377          .ToList()
1378        );
1379      }
1380    }
1381    #endregion
1382
1383    #region User Methods
1384    public string GetUsernameByUserId(Guid userId) {
1385      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1386      var user = UserManager.GetUserById(userId);
1387      return user != null ? user.UserName : null;
1388    }
1389
1390    public Guid GetUserIdByUsername(string username) {
1391      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1392      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
1393      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
1394    }
1395   
1396    public Dictionary<Guid, HashSet<Guid>> GetUserGroupTree() {
1397      var userGroupTree = new Dictionary<Guid, HashSet<Guid>>();
1398      var userGroupMapping = UserManager.GetUserGroupMapping();
1399
1400      foreach(var ugm in userGroupMapping) {
1401        if (ugm.Parent == null || ugm.Child == null) continue;
1402
1403        if (!userGroupTree.ContainsKey(ugm.Parent)) {
1404          userGroupTree.Add(ugm.Parent, new HashSet<Guid>());
1405        }
1406        userGroupTree[ugm.Parent].Add(ugm.Child);
1407      }
1408
1409      return userGroupTree;
1410    }
1411    #endregion
1412
1413    #region UserPriorities Methods
1414    public IEnumerable<DT.UserPriority> GetUserPriorities() {
1415      var pm = PersistenceManager;
1416      using (new PerformanceLogger("GetUserPriorities")) {
1417        var userPriorityDao = pm.UserPriorityDao;
1418        return pm.UseTransaction(() => userPriorityDao.GetAll()
1419          .Select(x => x.ToDto())
1420          .ToList()
1421        );
1422      }
1423    }
1424    #endregion
1425
1426    #region Private Helper Methods
1427    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
1428      var stateLogDao = pm.StateLogDao;
1429      var taskStateEntity = taskState.ToEntity();
1430
1431      if (task.State == DA.TaskState.Transferring && taskStateEntity == DA.TaskState.Paused && task.Command == null) {
1432        // slave paused and uploaded the task (no user-command) -> set waiting.
1433        taskStateEntity = DA.TaskState.Waiting;
1434      }
1435
1436      stateLogDao.Save(new DA.StateLog {
1437        State = taskStateEntity,
1438        DateTime = DateTime.Now,
1439        TaskId = task.TaskId,
1440        UserId = userId,
1441        SlaveId = slaveId,
1442        Exception = exception
1443      });
1444
1445      task.State = taskStateEntity;
1446
1447      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
1448          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
1449          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
1450        task.Command = null;
1451      }
1452    }
1453
1454    #endregion
1455  }
1456}
Note: See TracBrowser for help on using the repository browser.