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

Last change on this file since 15630 was 15630, checked in by jzenisek, 3 years ago

#2839

  • updated Heartbeat processing (regarding: checking against AssignedJobResources and handling of the updated Job deletion routine)
  • updated Job deletion routine(still in progress at GenerateStatistics)
File size: 60.1 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.State == DA.JobState.Online
364                          && (x.OwnerUserId == currentUserId
365                            || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
366                              && y.GrantedUserId == currentUserId) > 0)
367                          )
368            .Select(x => x.ToDto())
369            .ToList();
370          // calculate stats only for owned & permitted jobs; TODO: query only needed ones, not all
371          var statistics = taskDao.GetAll()
372              .Where(x => jobs.Select(y => y.Id).Contains(x.JobId))
373              .GroupBy(x => x.JobId)
374              .Select(x => new {
375                x.Key,
376                TotalCount = x.Count(),
377                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
378                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
379              })
380              .ToList();
381          foreach (var job in jobs) {
382            var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
383            if (statistic != null) {
384              job.JobCount = statistic.TotalCount;
385              job.CalculatingCount = statistic.CalculatingCount;
386              job.FinishedCount = statistic.FinishedCount;
387            }
388            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
389            if (currentUserId == job.OwnerUserId) {
390              job.Permission = Permission.Full;
391            } else {
392              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
393              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
394            }
395          }
396          return jobs;
397        });
398      }
399    }
400
401    public Guid AddJob(DT.Job jobDto) {
402      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
403      var pm = PersistenceManager;
404      using (new PerformanceLogger("AddJob")) {
405        var jobDao = pm.JobDao;
406        var userPriorityDao = pm.UserPriorityDao;
407        return pm.UseTransaction(() => {
408          jobDto.OwnerUserId = UserManager.CurrentUserId;
409          jobDto.DateCreated = DateTime.Now;
410          var job = jobDao.Save(jobDto.ToEntity());
411          if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
412            userPriorityDao.Save(new DA.UserPriority {
413              UserId = jobDto.OwnerUserId,
414              DateEnqueued = jobDto.DateCreated
415            });
416          }
417          pm.SubmitChanges();
418          return job.JobId;
419        });
420      }
421    }
422
423    public Guid AddJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
424      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
425      // check user - project
426      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
427      // check project - resources
428      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
429      var pm = PersistenceManager;
430      using (new PerformanceLogger("AddJob")) {
431        var jobDao = pm.JobDao;
432        var userPriorityDao = pm.UserPriorityDao;
433
434        return pm.UseTransaction(() => {
435          var newJob = jobDto.ToEntity();
436          newJob.OwnerUserId = UserManager.CurrentUserId;
437          newJob.DateCreated = DateTime.Now;
438
439          // add resource assignments
440          newJob.AssignedJobResources.AddRange(resourceIds.Select(
441            x => new DA.AssignedJobResource {
442              ResourceId = x
443            }));
444
445          var job = jobDao.Save(newJob);
446          if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
447            userPriorityDao.Save(new DA.UserPriority {
448              UserId = jobDto.OwnerUserId,
449              DateEnqueued = jobDto.DateCreated
450            });
451          }
452          pm.SubmitChanges();
453          return job.JobId;
454        });
455      }
456    }
457
458    public void UpdateJob(DT.Job jobDto) {
459      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
460      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
461      var pm = PersistenceManager;
462      using (new PerformanceLogger("UpdateJob")) {
463        bool exists = true;
464        var jobDao = pm.JobDao;
465        pm.UseTransaction(() => {
466          var job = jobDao.GetById(jobDto.Id);
467          if (job == null) {
468            exists = false;
469            job = new DA.Job();
470          }
471          jobDto.CopyToEntity(job);
472          if (!exists) {
473            jobDao.Save(job);
474          }
475          pm.SubmitChanges();
476        });
477      }
478    }
479
480    public void UpdateJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
481      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
482      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
483      // check user - project permission
484      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
485      // check project - resources permission
486      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
487
488      var pm = PersistenceManager;
489      using (new PerformanceLogger("UpdateJob")) {
490        bool exists = true;
491        var jobDao = pm.JobDao;
492        pm.UseTransaction(() => {
493          var job = jobDao.GetById(jobDto.Id);
494          if (job == null) {
495            exists = false;
496            job = new DA.Job();
497          }
498          jobDto.CopyToEntity(job);
499
500          if (!exists) {
501            // add resource assignments
502            job.AssignedJobResources.AddRange(resourceIds.Select(
503              x => new DA.AssignedJobResource {
504                ResourceId = x
505              }));
506            jobDao.Save(job);
507          } else {
508            var addedJobResourceIds = resourceIds.Except(job.AssignedJobResources.Select(x => x.ResourceId));
509            var removedJobResourceIds = job.AssignedJobResources.Select(x => x.ResourceId).Except(resourceIds);
510           
511            // remove resource assignments
512            foreach(var rid in removedJobResourceIds) {
513              var ajr = job.AssignedJobResources.Where(x => x.ResourceId == rid).SingleOrDefault();
514              if (ajr != null) job.AssignedJobResources.Remove(ajr);
515            }
516
517            // add resource assignments
518            job.AssignedJobResources.AddRange(addedJobResourceIds.Select(
519              x => new DA.AssignedJobResource {
520                ResourceId = x
521              }));
522          }
523          pm.SubmitChanges();
524        });
525      }
526    }
527
528    public void UpdateJobState(Guid jobId, DT.JobState jobState) {
529      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
530      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
531      var pm = PersistenceManager;
532      using (new PerformanceLogger("UpdateJobState")) {
533        var jobDao = pm.JobDao;
534        pm.UseTransaction(() => {
535          var job = jobDao.GetById(jobId);
536          if(job != null) {
537            var jobStateEntity = jobState.ToEntity();
538            // note: allow solely state changes from "Online" to "StatisticsPending"
539            // and from "StatisticsPending" to "DeletionPending"
540            if (job.State == DA.JobState.Online && jobStateEntity == DA.JobState.StatisticsPending) {
541              job.State = jobStateEntity;
542              foreach(var task in job.Tasks
543              .Where(x => x.State == DA.TaskState.Waiting
544                || x.State == DA.TaskState.Paused
545                || x.State == DA.TaskState.Offline)) {
546                task.State = DA.TaskState.Aborted;
547              }
548              pm.SubmitChanges();
549            } else if(job.State == DA.JobState.StatisticsPending && jobStateEntity == DA.JobState.DeletionPending) {
550              job.State = jobStateEntity;
551              pm.SubmitChanges();
552            }
553          }
554        });
555      }
556    }
557
558    public IEnumerable<DT.AssignedJobResource> GetAssignedResourcesForJob(Guid jobId) {
559      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
560      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
561      var pm = PersistenceManager;
562      var assignedJobResourceDao = pm.AssignedJobResourceDao;
563      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
564        return pm.UseTransaction(() =>
565          assignedJobResourceDao.GetByJobId(jobId)
566          .Select(x => x.ToDto())
567          .ToList()
568        );
569      }
570    }
571    #endregion
572
573    #region JobPermission Methods
574    public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
575      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
576      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
577      var pm = PersistenceManager;
578      using (new PerformanceLogger("GrantPermission")) {
579        var jobPermissionDao = pm.JobPermissionDao;
580        var currentUserId = UserManager.CurrentUserId;
581        pm.UseTransaction(() => {
582          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
583          pm.SubmitChanges();
584        });
585      }
586    }
587
588    public void RevokePermission(Guid jobId, Guid grantedUserId) {
589      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
590      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
591      var pm = PersistenceManager;
592      using (new PerformanceLogger("RevokePermission")) {
593        var jobPermissionDao = pm.JobPermissionDao;
594        var currentUserId = UserManager.CurrentUserId;
595        pm.UseTransaction(() => {
596          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
597          pm.SubmitChanges();
598        });
599      }
600    }
601
602    public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
603      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
604      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
605      var pm = PersistenceManager;
606      using (new PerformanceLogger("GetJobPermissions")) {
607        var jobPermissionDao = pm.JobPermissionDao;
608        return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
609          .Select(x => x.ToDto())
610          .ToList()
611        );
612      }
613    }
614
615    // BackwardsCompatibility3.3
616    #region Backwards compatible code, remove with 3.4
617    public bool IsAllowedPrivileged() {
618      return true;
619    }
620    #endregion
621    #endregion
622
623    #region Login Methods
624    public void Hello(DT.Slave slaveInfo) {
625      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
626      if (UserManager.CurrentUser.UserName != "hiveslave") {
627        slaveInfo.OwnerUserId = UserManager.CurrentUserId;
628      }
629      var pm = PersistenceManager;
630      using (new PerformanceLogger("Hello")) {
631        var slaveDao = pm.SlaveDao;
632        pm.UseTransaction(() => {
633          var slave = slaveDao.GetById(slaveInfo.Id);
634          if (slave == null) {
635            slaveDao.Save(slaveInfo.ToEntity());
636          } else {
637            bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
638            Guid? oldParentResourceId = slave.ParentResourceId;
639            slaveInfo.CopyToEntity(slave);
640            slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
641            slave.ParentResourceId = oldParentResourceId;
642            slave.LastHeartbeat = DateTime.Now;
643            slave.SlaveState = DA.SlaveState.Idle;
644          }
645          pm.SubmitChanges();
646        });
647      }
648    }
649
650    public void GoodBye(Guid slaveId) {
651      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
652      var pm = PersistenceManager;
653      using (new PerformanceLogger("GoodBye")) {
654        var slaveDao = pm.SlaveDao;
655        pm.UseTransaction(() => {
656          var slave = slaveDao.GetById(slaveId);
657          if (slave != null) {
658            slave.SlaveState = DA.SlaveState.Offline;
659            pm.SubmitChanges();
660          }
661        });
662      }
663    }
664    #endregion
665
666    #region Heartbeat Methods
667    public List<MessageContainer> Heartbeat(DT.Heartbeat heartbeat) {
668      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
669      List<MessageContainer> result = new List<MessageContainer>();
670      try {
671        using (new PerformanceLogger("ProcessHeartbeat")) {
672          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
673        }
674      } catch (Exception ex) {
675        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
676      }
677      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
678        TriggerEventManager(false);
679      }
680      return result;
681    }
682    #endregion
683
684    #region Plugin Methods
685    public DT.Plugin GetPlugin(Guid pluginId) {
686      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
687      var pm = PersistenceManager;
688      using (new PerformanceLogger("GetPlugin")) {
689        var pluginDao = pm.PluginDao;
690        return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
691      }
692    }
693
694    public Guid AddPlugin(DT.Plugin plugin, List<DT.PluginData> pluginData) {
695      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
696      var pm = PersistenceManager;
697      using (new PerformanceLogger("AddPlugin")) {
698        var pluginDao = pm.PluginDao;
699        plugin.UserId = UserManager.CurrentUserId;
700        plugin.DateCreated = DateTime.Now;
701        return pm.UseTransaction(() => {
702          var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
703          if (pluginEntity != null) {
704            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(pluginEntity.PluginId));
705          }
706          pluginEntity = plugin.ToEntity();
707          foreach (var data in pluginData) {
708            data.PluginId = default(Guid); // real id will be assigned from linq2sql
709            pluginEntity.PluginData.Add(data.ToEntity());
710          }
711          pluginDao.Save(pluginEntity);
712          pm.SubmitChanges();
713          return pluginEntity.PluginId;
714        });
715      }
716    }
717
718    public IEnumerable<DT.Plugin> GetPlugins() {
719      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
720      var pm = PersistenceManager;
721      using (new PerformanceLogger("GetPlugins")) {
722        var pluginDao = pm.PluginDao;
723        return pm.UseTransaction(() => pluginDao.GetAll()
724          .Where(x => x.Hash != null)
725          .Select(x => x.ToDto())
726          .ToList()
727        );
728      }
729    }
730
731    public IEnumerable<DT.PluginData> GetPluginDatas(List<Guid> pluginIds) {
732      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
733      var pm = PersistenceManager;
734      using (new PerformanceLogger("GetPluginDatas")) {
735        var pluginDataDao = pm.PluginDataDao;
736        return pm.UseTransaction(() => pluginDataDao.GetAll()
737            .Where(x => pluginIds.Contains(x.PluginId))
738            .Select(x => x.ToDto())
739            .ToList()
740        );
741      }
742    }
743    #endregion
744
745    #region Project Methods
746    public Guid AddProject(DT.Project projectDto) {
747      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
748      var pm = PersistenceManager;
749      using (new PerformanceLogger("AddProject")) {
750        var projectDao = pm.ProjectDao;
751        return pm.UseTransaction(() => {
752          var project = projectDao.Save(projectDto.ToEntity());
753          pm.SubmitChanges();
754          return project.ProjectId;
755        });
756      }
757    }
758
759    public void UpdateProject(DT.Project projectDto) {
760      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
761      var pm = PersistenceManager;
762      using (new PerformanceLogger("UpdateProject")) {
763        var projectDao = pm.ProjectDao;
764        pm.UseTransaction(() => {
765          var project = projectDao.GetById(projectDto.Id);
766          if (project != null) {
767            projectDto.CopyToEntity(project);
768          } else {
769            projectDao.Save(projectDto.ToEntity());
770          }
771          pm.SubmitChanges();
772        });
773      }
774    }
775
776    public void DeleteProject(Guid projectId) {
777      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
778      var pm = PersistenceManager;
779      using (new PerformanceLogger("DeleteProject")) {
780        var projectDao = pm.ProjectDao;
781        var assignedJobResourceDao = pm.AssignedJobResourceDao;
782        pm.UseTransaction(() => {
783          assignedJobResourceDao.DeleteByProjectId(projectId);
784          projectDao.Delete(projectId);
785          pm.SubmitChanges();
786        });
787      }
788    }
789
790    public DT.Project GetProject(Guid projectId) {
791      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
792      var pm = PersistenceManager;
793      using (new PerformanceLogger("GetProject")) {
794        var projectDao = pm.ProjectDao;
795        return pm.UseTransaction(() => projectDao.GetById(projectId).ToDto());
796      }
797    }
798
799    // query granted projects for use (i.e. to calculate on)
800    public IEnumerable<DT.Project> GetProjects() {
801      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
802      //bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
803      var pm = PersistenceManager;
804      using (new PerformanceLogger("GetProjects")) {
805        var projectDao = pm.ProjectDao;
806        //var projectPermissionDao = pm.ProjectPermissionDao;
807        var currentUserId = UserManager.CurrentUserId;
808        var userAndGroupIds = new List<Guid> { currentUserId };
809        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
810        return pm.UseTransaction(() => {
811          return projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
812            .Select(x => x.ToDto()).ToList();
813        });
814      }
815    }
816
817    public IEnumerable<DT.Project> GetProjectsForAdministration() {
818      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
819      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
820      var pm = PersistenceManager;
821      using (new PerformanceLogger("GetProjectsForAdministration")) {
822        var projectDao = pm.ProjectDao;
823        //var projectPermissionDao = pm.ProjectPermissionDao;
824       
825        return pm.UseTransaction(() => {
826          if(isAdministrator) {
827            return projectDao.GetAll().Select(x => x.ToDto()).ToList();
828          } else {
829            var currentUserId = UserManager.CurrentUserId;
830            return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId)
831              .Select(x => x.ToDto()).ToList();
832
833          }
834
835          //var projectPermissions = projectPermissionDao.GetAll();
836          //return projectDao.GetAll().ToList()
837          //  .Where(x => isAdministrator
838          //    || x.OwnerUserId == currentUserId
839          //    || UserManager.VerifyUser(currentUserId, projectPermissions
840          //        .Where(y => y.ProjectId == x.ProjectId)
841          //        .Select(z => z.GrantedUserId)
842          //        .ToList())
843          //    )
844          //  .Select(x => x.ToDto())
845          //  .ToList();
846        });
847      }
848    }
849    #endregion
850
851    #region ProjectPermission Methods
852    public void SaveProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool reassign, bool cascading, bool reassignCascading) {
853      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
854      if (projectId == null || grantedUserIds == null) return;
855      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
856      var pm = PersistenceManager;
857      using (new PerformanceLogger("GrantProjectPermissions")) {
858        var projectDao = pm.ProjectDao;
859        var projectPermissionDao = pm.ProjectPermissionDao;
860        var assignedJobResourceDao = pm.AssignedJobResourceDao;
861
862        pm.UseTransaction(() => {
863          var project = projectDao.GetById(projectId);
864          if (project == null) return;
865          //if (project.ProjectPermissions == null) project.ProjectPermissions = new System.Data.Linq.EntitySet<DA.ProjectPermission>();
866          var projectPermissions = project.ProjectPermissions.Select(x => x.GrantedUserId);
867          var addedPermissions = grantedUserIds.Except(projectPermissions);
868          var removedPermissions = projectPermissions.Except(grantedUserIds);
869
870          // remove job assignments and project permissions
871          if (reassign) {
872            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
873            project.ProjectPermissions.Clear();
874          } else {
875            assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, removedPermissions);
876            foreach(var item in project.ProjectPermissions.ToList().Where(x => removedPermissions.Contains(x.GrantedUserId))) {
877              project.ProjectPermissions.Remove(item);
878            }
879          }
880          pm.SubmitChanges();
881
882          // add project permissions
883          foreach (var id in grantedUserIds) {
884            if(project.ProjectPermissions.All(x => x.GrantedUserId != id)) {
885              project.ProjectPermissions.Add(new DA.ProjectPermission {
886                GrantedUserId = id,
887                GrantedByUserId = UserManager.CurrentUserId
888              });
889            }
890          }
891          pm.SubmitChanges();
892
893          if (cascading) {
894            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
895            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
896
897            // remove job assignments
898            if (reassignCascading) {
899              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
900            } else {
901              assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, removedPermissions);
902            }
903
904            foreach(var p in childProjects) {
905              // remove project permissions
906              if(reassignCascading) {
907                p.ProjectPermissions.Clear();
908              } else {
909                foreach(var item in p.ProjectPermissions.ToList().Where(x => removedPermissions.Contains(x.GrantedUserId))) {
910                  p.ProjectPermissions.Remove(item);
911                }
912              }
913              pm.SubmitChanges();
914
915              // add project permissions
916              foreach (var id in grantedUserIds) {
917                if (p.ProjectPermissions.All(x => x.GrantedUserId != id)) {
918                  p.ProjectPermissions.Add(new DA.ProjectPermission {
919                    GrantedUserId = id,
920                    GrantedByUserId = UserManager.CurrentUserId
921                  });
922                }
923              }
924            }
925          }
926          pm.SubmitChanges();
927        });
928      }
929    }
930
931    public void GrantProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
932      throw new NotImplementedException();
933    }
934
935    public void RevokeProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
936      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
937      if (projectId == null || grantedUserIds == null || !grantedUserIds.Any()) return;
938      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
939      var pm = PersistenceManager;
940      using (new PerformanceLogger("RevokeProjectPermissions")) {
941        var projectPermissionDao = pm.ProjectPermissionDao;
942        var projectDao = pm.ProjectDao;
943        var assignedJobResourceDao = pm.AssignedJobResourceDao;
944        pm.UseTransaction(() => {
945          if (cascading) {
946            var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
947            projectPermissionDao.DeleteByProjectIdsAndGrantedUserIds(childProjectIds, grantedUserIds);
948            assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, grantedUserIds);
949          }
950          projectPermissionDao.DeleteByProjectIdAndGrantedUserIds(projectId, grantedUserIds);
951          assignedJobResourceDao.DeleteByProjectIdAndUserIds(projectId, grantedUserIds);
952          pm.SubmitChanges();
953        });
954      }
955    }
956
957    public IEnumerable<DT.ProjectPermission> GetProjectPermissions(Guid projectId) {
958      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
959      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
960      var pm = PersistenceManager;
961      using (new PerformanceLogger("GetProjectPermissions")) {
962        var projectPermissionDao = pm.ProjectPermissionDao;
963        return pm.UseTransaction(() => projectPermissionDao.GetByProjectId(projectId)
964          .Select(x => x.ToDto())
965          .ToList()
966        );
967      }
968    }
969    #endregion
970
971    #region AssignedProjectResource Methods
972    // basic: remove and add assignments (resourceIds) to projectId and its depending jobs
973    // reassign: clear all assignments from project and its depending jobs, before adding new ones (resourceIds)
974    // cascading: "basic" mode for child-projects
975    // reassignCascading: "reassign" mode for child-projects
976    public void SaveProjectResourceAssignments(Guid projectId, List<Guid> resourceIds, bool reassign, bool cascading, bool reassignCascading) {
977      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
978      if (projectId == null || resourceIds == null) return;
979      AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
980      var pm = PersistenceManager;
981      using (new PerformanceLogger("AssignProjectResources")) {
982        var projectDao = pm.ProjectDao;
983        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
984        var assignedJobResourceDao = pm.AssignedJobResourceDao;
985        pm.UseTransaction(() => {
986          var project = projectDao.GetById(projectId);
987          var assignedResources = project.AssignedProjectResources.Select(x => x.ResourceId);
988          var addedAssignments = resourceIds.Except(assignedResources);
989          var removedAssignments = assignedResources.Except(resourceIds);
990
991          // remove job and project assignments
992          if (reassign) {
993            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
994            //assignedProjectResourceDao.DeleteByProjectIds(new List<Guid> { projectId });
995            project.AssignedProjectResources.Clear();
996          } else {
997            assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, removedAssignments);
998            //assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(projectId, removedAssignments);
999            foreach (var item in project.AssignedProjectResources.ToList().Where(x => removedAssignments.Contains(x.ResourceId))) {
1000              project.AssignedProjectResources.Remove(item);
1001            }
1002          }
1003          pm.SubmitChanges();
1004
1005          // add project assignments
1006          foreach (var id in resourceIds) {
1007            if (project.AssignedProjectResources.All(x => x.ResourceId != id)) {
1008              project.AssignedProjectResources.Add(new DA.AssignedProjectResource {
1009                ResourceId = id
1010              });
1011            }
1012          }
1013          pm.SubmitChanges();
1014
1015          if (cascading) {
1016            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
1017
1018            // remove job assignments
1019            if (reassignCascading) {
1020              assignedJobResourceDao.DeleteByProjectIds(childProjects.Select(x => x.ProjectId).ToList());
1021            } else {
1022              var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
1023              assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, removedAssignments);
1024            }
1025            foreach (var p in childProjects) {
1026              // remove project assignments
1027              if (reassignCascading) {
1028                //assignedProjectResourceDao.DeleteByProjectIds(new List<Guid> { p.ProjectId });
1029                p.AssignedProjectResources.Clear();
1030              } else {
1031                //assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(p.ProjectId, removedAssignments);
1032                foreach (var item in p.AssignedProjectResources.ToList().Where(x => removedAssignments.Contains(x.ResourceId))) {
1033                  p.AssignedProjectResources.Remove(item);
1034                }
1035              }
1036              pm.SubmitChanges();
1037
1038              // add project assignments
1039              foreach (var id in resourceIds) {
1040                if(p.AssignedProjectResources.All(x => x.ResourceId != id)) {
1041                  p.AssignedProjectResources.Add(new DA.AssignedProjectResource {
1042                    ResourceId = id
1043                  });
1044                }
1045              }
1046            }
1047          }
1048          pm.SubmitChanges();
1049        });
1050      }
1051    }
1052
1053    public void AssignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
1054      throw new NotImplementedException();
1055    }
1056
1057    // basic: unassign resourceIds from project and depending jobs
1058    // cascading: unassign resourceIds from all child-projects and their depending jobs
1059    public void UnassignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
1060      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1061      if (projectId == null || resourceIds == null || !resourceIds.Any()) return;
1062      AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
1063      var pm = PersistenceManager;
1064      using (new PerformanceLogger("UnassignProjectResources")) {
1065        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1066        var assignedJobResourceDao = pm.AssignedJobResourceDao;
1067        var projectDao = pm.ProjectDao;
1068        pm.UseTransaction(() => {
1069          if (cascading) {
1070            var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
1071            assignedProjectResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
1072            assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
1073          }
1074          assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
1075          assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
1076          pm.SubmitChanges();
1077        });
1078      }
1079    }
1080
1081    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProject(Guid projectId) {
1082      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1083      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, projectId);
1084      var pm = PersistenceManager;
1085      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
1086        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1087        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
1088          .Select(x => x.ToDto())
1089          .ToList()
1090        );
1091      }
1092    }
1093
1094    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectAdministration(Guid projectId) {
1095      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1096      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
1097      var pm = PersistenceManager;
1098      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
1099        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
1100        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
1101          .Select(x => x.ToDto())
1102          .ToList()
1103        );
1104      }
1105    }
1106
1107    #endregion
1108
1109    #region Slave Methods
1110    public Guid AddSlave(DT.Slave slaveDto) {
1111      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1112      var pm = PersistenceManager;
1113      using (new PerformanceLogger("AddSlave")) {
1114        var slaveDao = pm.SlaveDao;
1115        return pm.UseTransaction(() => {
1116          var slave = slaveDao.Save(slaveDto.ToEntity());
1117          pm.SubmitChanges();
1118          return slave.ResourceId;
1119        });
1120      }
1121    }
1122
1123    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
1124      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1125      var pm = PersistenceManager;
1126      using (new PerformanceLogger("AddSlaveGroup")) {
1127        var slaveGroupDao = pm.SlaveGroupDao;
1128        return pm.UseTransaction(() => {
1129          if (slaveGroupDto.Id == Guid.Empty) {
1130            slaveGroupDto.Id = Guid.NewGuid();
1131          }
1132          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
1133          pm.SubmitChanges();
1134          return slaveGroup.ResourceId;
1135        });
1136      }
1137    }
1138
1139    public DT.Slave GetSlave(Guid slaveId) {
1140      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1141      var pm = PersistenceManager;
1142      using (new PerformanceLogger("GetSlave")) {
1143        var slaveDao = pm.SlaveDao;
1144        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
1145      }
1146    }
1147
1148    public IEnumerable<DT.Slave> GetSlaves() {
1149      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1150      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
1151      var pm = PersistenceManager;
1152      using (new PerformanceLogger("GetSlaves")) {
1153        var slaveDao = pm.SlaveDao;
1154        //var projectPermissionDao = pm.ProjectPermissionDao;
1155        var currentUserId = UserManager.CurrentUserId;
1156        return pm.UseTransaction(() => {
1157            return slaveDao.GetAll().ToList()
1158              .Where( x => isAdministrator
1159              || x.OwnerUserId == null
1160              || x.OwnerUserId == currentUserId)
1161              .Select(x => x.ToDto())
1162              .ToList();
1163          //var projectPermissions = projectPermissionDao.GetAll();
1164          //return slaveDao.GetAll().ToList()
1165          //  .Where(x => isAdministrator
1166          //    || x.OwnerUserId == null
1167          //    || x.OwnerUserId == currentUserId
1168          //    || UserManager.VerifyUser(currentUserId, projectPermissions
1169          //        //.Where(y => y.ResourceId == x.ResourceId)
1170          //        .Select(z => z.GrantedUserId)
1171          //        .ToList())
1172          //    )
1173          //  .Select(x => x.ToDto())
1174          //  .ToList();
1175        });
1176      }
1177    }
1178
1179    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
1180      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1181      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
1182      var pm = PersistenceManager;
1183      using (new PerformanceLogger("GetSlaveGroups")) {
1184        var slaveGroupDao = pm.SlaveGroupDao;
1185        var projectPermissionDao = pm.ProjectPermissionDao;
1186        var currentUserId = UserManager.CurrentUserId;
1187        return pm.UseTransaction(() => {
1188          //var projectPermissions = projectPermissionDao.GetAll();
1189          return slaveGroupDao.GetAll().ToList()
1190            .Where(x => isAdministrator
1191              || x.OwnerUserId == null
1192              || x.OwnerUserId == currentUserId
1193              //|| UserManager.VerifyUser(currentUserId, projectPermissions
1194              //    //.Where(y => y.ResourceId == x.ResourceId)
1195              //    .Select(z => z.GrantedUserId)
1196              //    .ToList())
1197             )
1198            .Select(x => x.ToDto())
1199            .ToList();
1200        });
1201      }
1202    }
1203
1204    public void UpdateSlave(DT.Slave slaveDto) {
1205      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1206      var pm = PersistenceManager;
1207      using (new PerformanceLogger("UpdateSlave")) {
1208        var slaveDao = pm.SlaveDao;
1209        pm.UseTransaction(() => {
1210          var slave = slaveDao.GetById(slaveDto.Id);
1211          if (slave != null) {
1212            slaveDto.CopyToEntity(slave);
1213          } else {
1214            slaveDao.Save(slaveDto.ToEntity());
1215          }
1216          pm.SubmitChanges();
1217        });
1218      }
1219    }
1220
1221    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
1222      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1223      var pm = PersistenceManager;
1224      using (new PerformanceLogger("UpdateSlaveGroup")) {
1225        var slaveGroupDao = pm.SlaveGroupDao;
1226        pm.UseTransaction(() => {
1227          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
1228          if (slaveGroup != null) {
1229            slaveGroupDto.CopyToEntity(slaveGroup);
1230          } else {
1231            slaveGroupDao.Save(slaveGroupDto.ToEntity());
1232          }
1233          pm.SubmitChanges();
1234        });
1235      }
1236    }
1237
1238    public void DeleteSlave(Guid slaveId) {
1239      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1240      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
1241      var pm = PersistenceManager;
1242      using (new PerformanceLogger("DeleteSlave")) {
1243        var slaveDao = pm.SlaveDao;
1244        pm.UseTransaction(() => {
1245          slaveDao.Delete(slaveId);
1246          pm.SubmitChanges();
1247        });
1248      }
1249    }
1250
1251    public void DeleteSlaveGroup(Guid slaveGroupId) {
1252      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1253      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
1254      var pm = PersistenceManager;
1255      using (new PerformanceLogger("DeleteSlaveGroup")) {
1256        var slaveGroupDao = pm.SlaveGroupDao;
1257        pm.UseTransaction(() => {
1258          slaveGroupDao.Delete(slaveGroupId);
1259          pm.SubmitChanges();
1260        });
1261      }
1262    }
1263
1264    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
1265      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1266      var pm = PersistenceManager;
1267      using (new PerformanceLogger("AddResourceToGroup")) {
1268        var resourceDao = pm.ResourceDao;
1269        pm.UseTransaction(() => {
1270          var resource = resourceDao.GetById(resourceId);
1271          resource.ParentResourceId = slaveGroupId;
1272          pm.SubmitChanges();
1273        });
1274      }
1275    }
1276
1277    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
1278      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1279      var pm = PersistenceManager;
1280      using (new PerformanceLogger("RemoveResourceFromGroup")) {
1281        var resourceDao = pm.ResourceDao;
1282        pm.UseTransaction(() => {
1283          var resource = resourceDao.GetById(resourceId);
1284          resource.ParentResourceId = null;
1285          pm.SubmitChanges();
1286        });
1287      }
1288    }
1289
1290    public Guid GetResourceId(string resourceName) {
1291      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1292      var pm = PersistenceManager;
1293      using (new PerformanceLogger("GetResourceId")) {
1294        var resourceDao = pm.ResourceDao;
1295        return pm.UseTransaction(() => {
1296          var resource = resourceDao.GetByName(resourceName);
1297          return resource != null ? resource.ResourceId : Guid.Empty;
1298        });
1299      }
1300    }
1301
1302    public void TriggerEventManager(bool force) {
1303      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1304      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
1305      bool cleanup;
1306      var pm = PersistenceManager;
1307      using (new PerformanceLogger("TriggerEventManager")) {
1308        cleanup = false;
1309        var lifecycleDao = pm.LifecycleDao;
1310        pm.UseTransaction(() => {
1311          var lastLifecycle = lifecycleDao.GetLastLifecycle();
1312          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
1313          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
1314            lifecycleDao.UpdateLifecycle();
1315            cleanup = true;
1316            pm.SubmitChanges();
1317          }
1318        }, true);
1319      }
1320      if (cleanup) {
1321        EventManager.Cleanup();
1322      }
1323    }
1324
1325    public int GetNewHeartbeatInterval(Guid slaveId) {
1326      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
1327      var pm = PersistenceManager;
1328      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
1329        var slaveDao = pm.SlaveDao;
1330        return pm.UseTransaction(() => {
1331          var slave = slaveDao.GetById(slaveId);
1332          if (slave != null) {
1333            return slave.HbInterval;
1334          }
1335          return -1;
1336        });
1337      }
1338    }
1339    #endregion
1340
1341    #region Downtime Methods
1342    public Guid AddDowntime(DT.Downtime downtimeDto) {
1343      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1344      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
1345      var pm = PersistenceManager;
1346      using (new PerformanceLogger("AddDowntime")) {
1347        var downtimeDao = pm.DowntimeDao;
1348        return pm.UseTransaction(() => {
1349          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
1350          pm.SubmitChanges();
1351          return downtime.ResourceId;
1352        });
1353      }
1354    }
1355
1356    public void DeleteDowntime(Guid downtimeId) {
1357      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1358      var pm = PersistenceManager;
1359      using (new PerformanceLogger("DeleteDowntime")) {
1360        var downtimeDao = pm.DowntimeDao;
1361        pm.UseTransaction(() => {
1362          downtimeDao.Delete(downtimeId);
1363          pm.SubmitChanges();
1364        });
1365      }
1366    }
1367
1368    public void UpdateDowntime(DT.Downtime downtimeDto) {
1369      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1370      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
1371      var pm = PersistenceManager;
1372      using (new PerformanceLogger("UpdateDowntime")) {
1373        var downtimeDao = pm.DowntimeDao;
1374        pm.UseTransaction(() => {
1375          var downtime = downtimeDao.GetById(downtimeDto.Id);
1376          if (downtime != null) {
1377            downtimeDto.CopyToEntity(downtime);
1378          } else {
1379            downtimeDao.Save(downtimeDto.ToEntity());
1380          }
1381          pm.SubmitChanges();
1382        });
1383      }
1384    }
1385
1386    public IEnumerable<DT.Downtime> GetDowntimesForResource(Guid resourceId) {
1387      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1388      var pm = PersistenceManager;
1389      using (new PerformanceLogger("GetDowntimesForResource")) {
1390        var downtimeDao = pm.DowntimeDao;
1391        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
1392          .Select(x => x.ToDto())
1393          .ToList()
1394        );
1395      }
1396    }
1397    #endregion
1398
1399    #region User Methods
1400    public string GetUsernameByUserId(Guid userId) {
1401      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1402      var user = UserManager.GetUserById(userId);
1403      return user != null ? user.UserName : null;
1404    }
1405
1406    public Guid GetUserIdByUsername(string username) {
1407      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1408      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
1409      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
1410    }
1411   
1412    public Dictionary<Guid, HashSet<Guid>> GetUserGroupTree() {
1413      var userGroupTree = new Dictionary<Guid, HashSet<Guid>>();
1414      var userGroupMapping = UserManager.GetUserGroupMapping();
1415
1416      foreach(var ugm in userGroupMapping) {
1417        if (ugm.Parent == null || ugm.Child == null) continue;
1418
1419        if (!userGroupTree.ContainsKey(ugm.Parent)) {
1420          userGroupTree.Add(ugm.Parent, new HashSet<Guid>());
1421        }
1422        userGroupTree[ugm.Parent].Add(ugm.Child);
1423      }
1424
1425      return userGroupTree;
1426    }
1427    #endregion
1428
1429    #region UserPriorities Methods
1430    public IEnumerable<DT.UserPriority> GetUserPriorities() {
1431      var pm = PersistenceManager;
1432      using (new PerformanceLogger("GetUserPriorities")) {
1433        var userPriorityDao = pm.UserPriorityDao;
1434        return pm.UseTransaction(() => userPriorityDao.GetAll()
1435          .Select(x => x.ToDto())
1436          .ToList()
1437        );
1438      }
1439    }
1440    #endregion
1441
1442    #region Private Helper Methods
1443    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
1444      var stateLogDao = pm.StateLogDao;
1445      var taskStateEntity = taskState.ToEntity();
1446
1447      if (task.State == DA.TaskState.Transferring && taskStateEntity == DA.TaskState.Paused && task.Command == null) {
1448        // slave paused and uploaded the task (no user-command) -> set waiting.
1449        taskStateEntity = DA.TaskState.Waiting;
1450      }
1451
1452      stateLogDao.Save(new DA.StateLog {
1453        State = taskStateEntity,
1454        DateTime = DateTime.Now,
1455        TaskId = task.TaskId,
1456        UserId = userId,
1457        SlaveId = slaveId,
1458        Exception = exception
1459      });
1460
1461      task.State = taskStateEntity;
1462
1463      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
1464          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
1465          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
1466        task.Command = null;
1467      }
1468    }
1469
1470    #endregion
1471  }
1472}
Note: See TracBrowser for help on using the repository browser.