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

Last change on this file since 15658 was 15658, checked in by jzenisek, 20 months ago

#2839

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