Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 15041

Last change on this file since 15041 was 14901, checked in by jkarder, 7 years ago

#2784: fixed pausing of hive tasks

File size: 39.3 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 static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
44
45    private IPersistenceManager PersistenceManager {
46      get { return ServiceLocator.Instance.PersistenceManager; }
47    }
48
49    private IUserManager UserManager {
50      get { return ServiceLocator.Instance.UserManager; }
51    }
52
53    private IRoleVerifier RoleVerifier {
54      get { return ServiceLocator.Instance.RoleVerifier; }
55    }
56
57    private IAuthorizationManager AuthorizationManager {
58      get { return ServiceLocator.Instance.AuthorizationManager; }
59    }
60    private IEventManager EventManager {
61      get { return ServiceLocator.Instance.EventManager; }
62    }
63    private HeartbeatManager HeartbeatManager {
64      get { return ServiceLocator.Instance.HeartbeatManager; }
65    }
66
67    #region Task Methods
68    public Guid AddTask(DT.Task task, DT.TaskData taskData, IEnumerable<Guid> resourceIds) {
69      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
70      var pm = PersistenceManager;
71      using (new PerformanceLogger("AddTask")) {
72        var taskDao = pm.TaskDao;
73        var stateLogDao = pm.StateLogDao;
74        var newTask = task.ToEntity();
75        newTask.JobData = taskData.ToEntity();
76        newTask.JobData.LastUpdate = DateTime.Now;
77        newTask.AssignedResources.AddRange(resourceIds.Select(
78          x => new DA.AssignedResource {
79            ResourceId = x
80          }));
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      IEnumerable<Guid> resourceIds;
102      var pm = PersistenceManager;
103      using (new PerformanceLogger("AddChildTask")) {
104        var assignedResourceDao = pm.AssignedResourceDao;
105        resourceIds = pm.UseTransaction(() => {
106          return assignedResourceDao.GetByTaskId(parentTaskId)
107            .Select(x => x.ResourceId)
108            .ToList();
109        });
110      }
111      task.ParentTaskId = parentTaskId;
112      return AddTask(task, taskData, resourceIds);
113    }
114
115    public DT.Task GetTask(Guid taskId) {
116      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
117      AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
118      var pm = PersistenceManager;
119      using (new PerformanceLogger("GetTask")) {
120        var taskDao = pm.TaskDao;
121        return pm.UseTransaction(() => {
122          var task = taskDao.GetById(taskId);
123          return task.ToDto();
124        });
125      }
126    }
127
128    public IEnumerable<DT.LightweightTask> GetLightweightJobTasks(Guid jobId) {
129      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
130      AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
131      var pm = PersistenceManager;
132      using (new PerformanceLogger("GetLightweightJobTasks")) {
133        var taskDao = pm.TaskDao;
134        return pm.UseTransaction(() => {
135          return taskDao.GetByJobId(jobId)
136            .ToList()
137            .Select(x => new DT.LightweightTask {
138              Id = x.TaskId,
139              ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
140              ParentTaskId = x.ParentTaskId,
141              StateLog = x.StateLogs.OrderBy(y => y.DateTime)
142                                    .Select(z => z.ToDto())
143                                    .ToList(),
144              State = x.State.ToDto(),
145              Command = x.Command.ToDto(),
146              LastTaskDataUpdate = x.JobData.LastUpdate
147            })
148            .ToList();
149        }, false, true);
150      }
151    }
152
153    public IEnumerable<DT.LightweightTask> GetLightweightJobTasksWithoutStateLog(Guid jobId) {
154      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
155      AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
156      var pm = PersistenceManager;
157      using (new PerformanceLogger("GetLightweightJobTasksWithoutStateLog")) {
158        var taskDao = pm.TaskDao;
159        return pm.UseTransaction(() => {
160          return taskDao.GetByJobId(jobId)
161            .ToList()
162            .Select(x => new DT.LightweightTask {
163              Id = x.TaskId,
164              ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
165              ParentTaskId = x.ParentTaskId,
166              StateLog = new List<DT.StateLog>(),
167              State = x.State.ToDto(),
168              Command = x.Command.ToDto(),
169              LastTaskDataUpdate = x.JobData.LastUpdate
170            })
171            .ToList();
172        }, false, true);
173      }
174    }
175
176    public DT.TaskData GetTaskData(Guid taskId) {
177      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
178      AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
179      var pm = PersistenceManager;
180      using (new PerformanceLogger("GetTaskData")) {
181        var taskDataDao = pm.TaskDataDao;
182        return pm.UseTransaction(() => taskDataDao.GetById(taskId).ToDto());
183      }
184    }
185
186    public void UpdateTask(DT.Task taskDto) {
187      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
188      AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
189      var pm = PersistenceManager;
190      using (new PerformanceLogger("UpdateTask")) {
191        var taskDao = pm.TaskDao;
192        pm.UseTransaction(() => {
193          var task = taskDao.GetById(taskDto.Id);
194          taskDto.CopyToEntity(task);
195          pm.SubmitChanges();
196        });
197      }
198    }
199
200    public void UpdateTaskData(DT.Task taskDto, DT.TaskData taskDataDto) {
201      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
202      AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
203      var pm = PersistenceManager;
204      using (new PerformanceLogger("UpdateTaskData")) {
205        var taskDao = pm.TaskDao;
206        var taskDataDao = pm.TaskDataDao;
207        pm.UseTransaction(() => {
208          var task = taskDao.GetById(taskDto.Id);
209          var taskData = taskDataDao.GetById(taskDataDto.TaskId);
210          taskDto.CopyToEntity(task);
211          taskDataDto.CopyToEntity(taskData);
212          taskData.LastUpdate = DateTime.Now;
213          pm.SubmitChanges();
214        });
215      }
216    }
217
218    public DT.Task UpdateTaskState(Guid taskId, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
219      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
220      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
221      var pm = PersistenceManager;
222      using (new PerformanceLogger("UpdateTaskState")) {
223        var taskDao = pm.TaskDao;
224        return pm.UseTransaction(() => {
225          var task = taskDao.GetById(taskId);
226          UpdateTaskState(pm, task, taskState, slaveId, userId, exception);
227          pm.SubmitChanges();
228          return task.ToDto();
229        });
230      }
231    }
232    #endregion
233
234    #region Task Control Methods
235    public void StopTask(Guid taskId) {
236      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
237      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
238      var pm = PersistenceManager;
239      using (new PerformanceLogger("StopTask")) {
240        var taskDao = pm.TaskDao;
241        pm.UseTransaction(() => {
242          var task = taskDao.GetById(taskId);
243          if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
244            task.Command = DA.Command.Stop;
245          } else if (task.State != DA.TaskState.Aborted
246                     && task.State != DA.TaskState.Finished
247                     && task.State != DA.TaskState.Failed) {
248            UpdateTaskState(pm, task, DT.TaskState.Aborted, null, null, string.Empty);
249          }
250          pm.SubmitChanges();
251        });
252      }
253    }
254
255    public void PauseTask(Guid taskId) {
256      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
257      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
258      var pm = PersistenceManager;
259      using (new PerformanceLogger("PauseTask")) {
260        var taskDao = pm.TaskDao;
261        pm.UseTransaction(() => {
262          var task = taskDao.GetById(taskId);
263          if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
264            task.Command = DA.Command.Pause;
265          } else if (task.State != DA.TaskState.Aborted
266                     && task.State != DA.TaskState.Finished
267                     && task.State != DA.TaskState.Failed) {
268            UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
269          }
270          pm.SubmitChanges();
271        });
272      }
273    }
274
275    public void RestartTask(Guid taskId) {
276      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
277      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
278      var pm = PersistenceManager;
279      using (new PerformanceLogger("RestartTask")) {
280        var taskDao = pm.TaskDao;
281        pm.UseTransaction(() => {
282          var task = taskDao.GetById(taskId);
283          task.Command = null;
284          UpdateTaskState(pm, task, DT.TaskState.Waiting, null, UserManager.CurrentUserId, string.Empty);
285          pm.SubmitChanges();
286        });
287      }
288    }
289    #endregion
290
291    #region Job Methods
292    public DT.Job GetJob(Guid id) {
293      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
294      AuthorizationManager.AuthorizeForJob(id, DT.Permission.Read);
295      var pm = PersistenceManager;
296      using (new PerformanceLogger("GetJob")) {
297        var jobDao = pm.JobDao;
298        var jobPermissionDao = pm.JobPermissionDao;
299        var taskDao = pm.TaskDao;
300        var currentUserId = UserManager.CurrentUserId;
301        return pm.UseTransaction(() => {
302          var job = jobDao.GetById(id).ToDto();
303          if (job != null) {
304            var statistics = taskDao.GetByJobId(job.Id)
305              .GroupBy(x => x.JobId)
306              .Select(x => new {
307                TotalCount = x.Count(),
308                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
309                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
310              }).FirstOrDefault();
311            if (statistics != null) {
312              job.JobCount = statistics.TotalCount;
313              job.CalculatingCount = statistics.CalculatingCount;
314              job.FinishedCount = statistics.FinishedCount;
315            }
316            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
317            if (currentUserId == job.OwnerUserId) {
318              job.Permission = Permission.Full;
319            } else {
320              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
321              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
322            }
323          }
324          return job;
325        });
326      }
327    }
328
329    public IEnumerable<DT.Job> GetJobs() {
330      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
331      var pm = PersistenceManager;
332      using (new PerformanceLogger("GetJobs")) {
333        var jobDao = pm.JobDao;
334        var jobPermissionDao = pm.JobPermissionDao;
335        var taskDao = pm.TaskDao;
336        var currentUserId = UserManager.CurrentUserId;
337        return pm.UseTransaction(() => {
338          var jobs = jobDao.GetAll()
339            .Where(x => x.OwnerUserId == currentUserId
340                     || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
341                                                 && y.GrantedUserId == currentUserId) > 0)
342            .Select(x => x.ToDto())
343            .ToList();
344          var statistics = taskDao.GetAll()
345              .GroupBy(x => x.JobId)
346              .Select(x => new {
347                x.Key,
348                TotalCount = x.Count(),
349                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
350                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
351              })
352              .ToList();
353          foreach (var job in jobs) {
354            var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
355            if (statistic != null) {
356              job.JobCount = statistic.TotalCount;
357              job.CalculatingCount = statistic.CalculatingCount;
358              job.FinishedCount = statistic.FinishedCount;
359            }
360            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
361            if (currentUserId == job.OwnerUserId) {
362              job.Permission = Permission.Full;
363            } else {
364              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
365              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
366            }
367          }
368          return jobs;
369        });
370      }
371    }
372
373    public Guid AddJob(DT.Job jobDto) {
374      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
375      var pm = PersistenceManager;
376      using (new PerformanceLogger("AddJob")) {
377        var jobDao = pm.JobDao;
378        var userPriorityDao = pm.UserPriorityDao;
379        return pm.UseTransaction(() => {
380          jobDto.OwnerUserId = UserManager.CurrentUserId;
381          jobDto.DateCreated = DateTime.Now;
382          var job = jobDao.Save(jobDto.ToEntity());
383          if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
384            userPriorityDao.Save(new DA.UserPriority {
385              UserId = jobDto.OwnerUserId,
386              DateEnqueued = jobDto.DateCreated
387            });
388          }
389          pm.SubmitChanges();
390          return job.JobId;
391        });
392      }
393    }
394
395    public void UpdateJob(DT.Job jobDto) {
396      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
397      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
398      var pm = PersistenceManager;
399      using (new PerformanceLogger("UpdateJob")) {
400        bool exists = true;
401        var jobDao = pm.JobDao;
402        pm.UseTransaction(() => {
403          var job = jobDao.GetById(jobDto.Id);
404          if (job == null) {
405            exists = false;
406            job = new DA.Job();
407          }
408          jobDto.CopyToEntity(job);
409          if (!exists) {
410            jobDao.Save(job);
411          }
412          pm.SubmitChanges();
413        });
414      }
415    }
416
417    public void DeleteJob(Guid jobId) {
418      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
419      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
420      var pm = PersistenceManager;
421      using (new PerformanceLogger("DeleteJob")) {
422        var jobDao = pm.JobDao;
423        pm.UseTransaction(() => {
424          // child task will be deleted by db-trigger
425          jobDao.Delete(jobId);
426          pm.SubmitChanges();
427        });
428      }
429    }
430    #endregion
431
432    #region JobPermission Methods
433    public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
434      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
435      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
436      var pm = PersistenceManager;
437      using (new PerformanceLogger("GrantPermission")) {
438        var jobPermissionDao = pm.JobPermissionDao;
439        var currentUserId = UserManager.CurrentUserId;
440        pm.UseTransaction(() => {
441          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
442          pm.SubmitChanges();
443        });
444      }
445    }
446
447    public void RevokePermission(Guid jobId, Guid grantedUserId) {
448      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
449      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
450      var pm = PersistenceManager;
451      using (new PerformanceLogger("RevokePermission")) {
452        var jobPermissionDao = pm.JobPermissionDao;
453        var currentUserId = UserManager.CurrentUserId;
454        pm.UseTransaction(() => {
455          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
456          pm.SubmitChanges();
457        });
458      }
459    }
460
461    public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
462      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
463      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
464      var pm = PersistenceManager;
465      using (new PerformanceLogger("GetJobPermissions")) {
466        var jobPermissionDao = pm.JobPermissionDao;
467        return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
468          .Select(x => x.ToDto())
469          .ToList()
470        );
471      }
472    }
473
474    // BackwardsCompatibility3.3
475    #region Backwards compatible code, remove with 3.4
476    public bool IsAllowedPrivileged() {
477      return true;
478    }
479    #endregion
480    #endregion
481
482    #region Login Methods
483    public void Hello(DT.Slave slaveInfo) {
484      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
485      if (UserManager.CurrentUser.UserName != "hiveslave") {
486        slaveInfo.OwnerUserId = UserManager.CurrentUserId;
487      }
488      var pm = PersistenceManager;
489      using (new PerformanceLogger("Hello")) {
490        var slaveDao = pm.SlaveDao;
491        pm.UseTransaction(() => {
492          var slave = slaveDao.GetById(slaveInfo.Id);
493          if (slave == null) {
494            slaveDao.Save(slaveInfo.ToEntity());
495          } else {
496            bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
497            Guid? oldParentResourceId = slave.ParentResourceId;
498            slaveInfo.CopyToEntity(slave);
499            slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
500            slave.ParentResourceId = oldParentResourceId;
501            slave.LastHeartbeat = DateTime.Now;
502            slave.SlaveState = DA.SlaveState.Idle;
503          }
504          pm.SubmitChanges();
505        });
506      }
507    }
508
509    public void GoodBye(Guid slaveId) {
510      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
511      var pm = PersistenceManager;
512      using (new PerformanceLogger("GoodBye")) {
513        var slaveDao = pm.SlaveDao;
514        pm.UseTransaction(() => {
515          var slave = slaveDao.GetById(slaveId);
516          if (slave != null) {
517            slave.SlaveState = DA.SlaveState.Offline;
518            pm.SubmitChanges();
519          }
520        });
521      }
522    }
523    #endregion
524
525    #region Heartbeat Methods
526    public List<MessageContainer> Heartbeat(DT.Heartbeat heartbeat) {
527      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
528      List<MessageContainer> result = new List<MessageContainer>();
529      try {
530        using (new PerformanceLogger("ProcessHeartbeat")) {
531          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
532        }
533      }
534      catch (Exception ex) {
535        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
536      }
537      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
538        TriggerEventManager(false);
539      }
540      return result;
541    }
542    #endregion
543
544    #region Plugin Methods
545    public DT.Plugin GetPlugin(Guid pluginId) {
546      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
547      var pm = PersistenceManager;
548      using (new PerformanceLogger("GetPlugin")) {
549        var pluginDao = pm.PluginDao;
550        return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
551      }
552    }
553
554    public Guid AddPlugin(DT.Plugin plugin, List<DT.PluginData> pluginData) {
555      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
556      var pm = PersistenceManager;
557      using (new PerformanceLogger("AddPlugin")) {
558        var pluginDao = pm.PluginDao;
559        plugin.UserId = UserManager.CurrentUserId;
560        plugin.DateCreated = DateTime.Now;
561        return pm.UseTransaction(() => {
562          var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
563          if (pluginEntity != null) {
564            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(pluginEntity.PluginId));
565          }
566          pluginEntity = plugin.ToEntity();
567          foreach (var data in pluginData) {
568            data.PluginId = default(Guid); // real id will be assigned from linq2sql
569            pluginEntity.PluginData.Add(data.ToEntity());
570          }
571          pluginDao.Save(pluginEntity);
572          pm.SubmitChanges();
573          return pluginEntity.PluginId;
574        });
575      }
576    }
577
578    public IEnumerable<DT.Plugin> GetPlugins() {
579      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
580      var pm = PersistenceManager;
581      using (new PerformanceLogger("GetPlugins")) {
582        var pluginDao = pm.PluginDao;
583        return pm.UseTransaction(() => pluginDao.GetAll()
584          .Where(x => x.Hash != null)
585          .Select(x => x.ToDto())
586          .ToList()
587        );
588      }
589    }
590
591    public IEnumerable<DT.PluginData> GetPluginDatas(List<Guid> pluginIds) {
592      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
593      var pm = PersistenceManager;
594      using (new PerformanceLogger("GetPluginDatas")) {
595        var pluginDataDao = pm.PluginDataDao;
596        return pm.UseTransaction(() => pluginDataDao.GetAll()
597            .Where(x => pluginIds.Contains(x.PluginId))
598            .Select(x => x.ToDto())
599            .ToList()
600        );
601      }
602    }
603    #endregion
604
605    #region ResourcePermission Methods
606    public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
607      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
608      var pm = PersistenceManager;
609      using (new PerformanceLogger("GrantResourcePermissions")) {
610        pm.UseTransaction(() => {
611          var resource = AuthorizeForResource(pm, resourceId);
612          var resourcePermissions = resource.ResourcePermissions.ToList();
613          foreach (var id in grantedUserIds) {
614            if (resourcePermissions.All(x => x.GrantedUserId != id)) {
615              resource.ResourcePermissions.Add(new DA.ResourcePermission {
616                GrantedUserId = id,
617                GrantedByUserId = UserManager.CurrentUserId
618              });
619            }
620          }
621          pm.SubmitChanges();
622        });
623      }
624    }
625
626    public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
627      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
628      var pm = PersistenceManager;
629      using (new PerformanceLogger("RevokeResourcePermissions")) {
630        var resourcePermissionDao = pm.ResourcePermissionDao;
631        pm.UseTransaction(() => {
632          AuthorizeForResource(pm, resourceId);
633          resourcePermissionDao.DeleteByResourceAndGrantedUserId(resourceId, grantedUserIds);
634          pm.SubmitChanges();
635        });
636      }
637    }
638
639    public IEnumerable<DT.ResourcePermission> GetResourcePermissions(Guid resourceId) {
640      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
641      var pm = PersistenceManager;
642      using (new PerformanceLogger("GetResourcePermissions")) {
643        var resourcePermissionDao = pm.ResourcePermissionDao;
644        return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
645          .Select(x => x.ToDto())
646          .ToList()
647        );
648      }
649    }
650    #endregion
651
652    #region Slave Methods
653    public Guid AddSlave(DT.Slave slaveDto) {
654      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
655      var pm = PersistenceManager;
656      using (new PerformanceLogger("AddSlave")) {
657        var slaveDao = pm.SlaveDao;
658        return pm.UseTransaction(() => {
659          var slave = slaveDao.Save(slaveDto.ToEntity());
660          pm.SubmitChanges();
661          return slave.ResourceId;
662        });
663      }
664    }
665
666    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
667      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
668      var pm = PersistenceManager;
669      using (new PerformanceLogger("AddSlaveGroup")) {
670        var slaveGroupDao = pm.SlaveGroupDao;
671        return pm.UseTransaction(() => {
672          if (slaveGroupDto.Id == Guid.Empty) {
673            slaveGroupDto.Id = Guid.NewGuid();
674          }
675          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
676          pm.SubmitChanges();
677          return slaveGroup.ResourceId;
678        });
679      }
680    }
681
682    public DT.Slave GetSlave(Guid slaveId) {
683      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
684      var pm = PersistenceManager;
685      using (new PerformanceLogger("GetSlave")) {
686        var slaveDao = pm.SlaveDao;
687        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
688      }
689    }
690
691    public IEnumerable<DT.Slave> GetSlaves() {
692      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
693      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
694      var pm = PersistenceManager;
695      using (new PerformanceLogger("GetSlaves")) {
696        var slaveDao = pm.SlaveDao;
697        var resourcePermissionDao = pm.ResourcePermissionDao;
698        var currentUserId = UserManager.CurrentUserId;
699        return pm.UseTransaction(() => {
700          var resourcePermissions = resourcePermissionDao.GetAll();
701          return slaveDao.GetAll().ToList()
702            .Where(x => isAdministrator
703              || x.OwnerUserId == null
704              || x.OwnerUserId == currentUserId
705              || UserManager.VerifyUser(currentUserId, resourcePermissions
706                  .Where(y => y.ResourceId == x.ResourceId)
707                  .Select(z => z.GrantedUserId)
708                  .ToList())
709              )
710            .Select(x => x.ToDto())
711            .ToList();
712        });
713      }
714    }
715
716    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
717      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
718      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
719      var pm = PersistenceManager;
720      using (new PerformanceLogger("GetSlaveGroups")) {
721        var slaveGroupDao = pm.SlaveGroupDao;
722        var resourcePermissionDao = pm.ResourcePermissionDao;
723        var currentUserId = UserManager.CurrentUserId;
724        return pm.UseTransaction(() => {
725          var resourcePermissions = resourcePermissionDao.GetAll();
726          return slaveGroupDao.GetAll().ToList()
727            .Where(x => isAdministrator
728              || x.OwnerUserId == null
729              || x.OwnerUserId == currentUserId
730              || UserManager.VerifyUser(currentUserId, resourcePermissions
731                  .Where(y => y.ResourceId == x.ResourceId)
732                  .Select(z => z.GrantedUserId)
733                  .ToList())
734              )
735            .Select(x => x.ToDto())
736            .ToList();
737        });
738      }
739    }
740
741    public void UpdateSlave(DT.Slave slaveDto) {
742      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
743      var pm = PersistenceManager;
744      using (new PerformanceLogger("UpdateSlave")) {
745        var slaveDao = pm.SlaveDao;
746        pm.UseTransaction(() => {
747          var slave = slaveDao.GetById(slaveDto.Id);
748          if (slave != null) {
749            slaveDto.CopyToEntity(slave);
750          } else {
751            slaveDao.Save(slaveDto.ToEntity());
752          }
753          pm.SubmitChanges();
754        });
755      }
756    }
757
758    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
759      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
760      var pm = PersistenceManager;
761      using (new PerformanceLogger("UpdateSlaveGroup")) {
762        var slaveGroupDao = pm.SlaveGroupDao;
763        pm.UseTransaction(() => {
764          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
765          if (slaveGroup != null) {
766            slaveGroupDto.CopyToEntity(slaveGroup);
767          } else {
768            slaveGroupDao.Save(slaveGroupDto.ToEntity());
769          }
770          pm.SubmitChanges();
771        });
772      }
773    }
774
775    public void DeleteSlave(Guid slaveId) {
776      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
777      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
778      var pm = PersistenceManager;
779      using (new PerformanceLogger("DeleteSlave")) {
780        var slaveDao = pm.SlaveDao;
781        pm.UseTransaction(() => {
782          slaveDao.Delete(slaveId);
783          pm.SubmitChanges();
784        });
785      }
786    }
787
788    public void DeleteSlaveGroup(Guid slaveGroupId) {
789      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
790      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
791      var pm = PersistenceManager;
792      using (new PerformanceLogger("DeleteSlaveGroup")) {
793        var slaveGroupDao = pm.SlaveGroupDao;
794        pm.UseTransaction(() => {
795          slaveGroupDao.Delete(slaveGroupId);
796          pm.SubmitChanges();
797        });
798      }
799    }
800
801    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
802      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
803      var pm = PersistenceManager;
804      using (new PerformanceLogger("AddResourceToGroup")) {
805        var resourceDao = pm.ResourceDao;
806        pm.UseTransaction(() => {
807          var resource = resourceDao.GetById(resourceId);
808          resource.ParentResourceId = slaveGroupId;
809          pm.SubmitChanges();
810        });
811      }
812    }
813
814    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
815      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
816      var pm = PersistenceManager;
817      using (new PerformanceLogger("RemoveResourceFromGroup")) {
818        var resourceDao = pm.ResourceDao;
819        pm.UseTransaction(() => {
820          var resource = resourceDao.GetById(resourceId);
821          resource.ParentResourceId = null;
822          pm.SubmitChanges();
823        });
824      }
825    }
826
827    public Guid GetResourceId(string resourceName) {
828      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
829      var pm = PersistenceManager;
830      using (new PerformanceLogger("GetResourceId")) {
831        var resourceDao = pm.ResourceDao;
832        return pm.UseTransaction(() => {
833          var resource = resourceDao.GetByName(resourceName);
834          return resource != null ? resource.ResourceId : Guid.Empty;
835        });
836      }
837    }
838
839    public void TriggerEventManager(bool force) {
840      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
841      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
842      bool cleanup;
843      var pm = PersistenceManager;
844      using (new PerformanceLogger("TriggerEventManager")) {
845        cleanup = false;
846        var lifecycleDao = pm.LifecycleDao;
847        pm.UseTransaction(() => {
848          var lastLifecycle = lifecycleDao.GetLastLifecycle();
849          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
850          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
851            lifecycleDao.UpdateLifecycle();
852            cleanup = true;
853            pm.SubmitChanges();
854          }
855        }, true);
856      }
857      if (cleanup) {
858        EventManager.Cleanup();
859      }
860    }
861
862    public int GetNewHeartbeatInterval(Guid slaveId) {
863      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
864      var pm = PersistenceManager;
865      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
866        var slaveDao = pm.SlaveDao;
867        return pm.UseTransaction(() => {
868          var slave = slaveDao.GetById(slaveId);
869          if (slave != null) {
870            return slave.HbInterval;
871          }
872          return -1;
873        });
874      }
875    }
876    #endregion
877
878    #region Downtime Methods
879    public Guid AddDowntime(DT.Downtime downtimeDto) {
880      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
881      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
882      var pm = PersistenceManager;
883      using (new PerformanceLogger("AddDowntime")) {
884        var downtimeDao = pm.DowntimeDao;
885        return pm.UseTransaction(() => {
886          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
887          pm.SubmitChanges();
888          return downtime.ResourceId;
889        });
890      }
891    }
892
893    public void DeleteDowntime(Guid downtimeId) {
894      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
895      var pm = PersistenceManager;
896      using (new PerformanceLogger("DeleteDowntime")) {
897        var downtimeDao = pm.DowntimeDao;
898        pm.UseTransaction(() => {
899          downtimeDao.Delete(downtimeId);
900          pm.SubmitChanges();
901        });
902      }
903    }
904
905    public void UpdateDowntime(DT.Downtime downtimeDto) {
906      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
907      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
908      var pm = PersistenceManager;
909      using (new PerformanceLogger("UpdateDowntime")) {
910        var downtimeDao = pm.DowntimeDao;
911        pm.UseTransaction(() => {
912          var downtime = downtimeDao.GetById(downtimeDto.Id);
913          if (downtime != null) {
914            downtimeDto.CopyToEntity(downtime);
915          } else {
916            downtimeDao.Save(downtimeDto.ToEntity());
917          }
918          pm.SubmitChanges();
919        });
920      }
921    }
922
923    public IEnumerable<DT.Downtime> GetDowntimesForResource(Guid resourceId) {
924      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
925      var pm = PersistenceManager;
926      using (new PerformanceLogger("GetDowntimesForResource")) {
927        var downtimeDao = pm.DowntimeDao;
928        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
929          .Select(x => x.ToDto())
930          .ToList()
931        );
932      }
933    }
934    #endregion
935
936    #region User Methods
937    public string GetUsernameByUserId(Guid userId) {
938      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
939      var user = UserManager.GetUserById(userId);
940      return user != null ? user.UserName : null;
941    }
942
943    public Guid GetUserIdByUsername(string username) {
944      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
945      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
946      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
947    }
948    #endregion
949
950    #region UserPriorities Methods
951    public IEnumerable<DT.UserPriority> GetUserPriorities() {
952      var pm = PersistenceManager;
953      using (new PerformanceLogger("GetUserPriorities")) {
954        var userPriorityDao = pm.UserPriorityDao;
955        return pm.UseTransaction(() => userPriorityDao.GetAll()
956          .Select(x => x.ToDto())
957          .ToList()
958        );
959      }
960    }
961    #endregion
962
963    #region Private Helper Methods
964    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
965      var stateLogDao = pm.StateLogDao;
966      var taskStateEntity = taskState.ToEntity();
967
968      if (taskStateEntity == DA.TaskState.Paused && task.Command == null) {
969        // slave paused and uploaded the task (no user-command) -> set waiting.
970        taskStateEntity = DA.TaskState.Waiting;
971      }
972
973      stateLogDao.Save(new DA.StateLog {
974        State = taskStateEntity,
975        DateTime = DateTime.Now,
976        TaskId = task.TaskId,
977        UserId = userId,
978        SlaveId = slaveId,
979        Exception = exception
980      });
981
982      task.State = taskStateEntity;
983
984      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
985          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
986          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
987        task.Command = null;
988      }
989    }
990
991    private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
992      var resourceDao = pm.ResourceDao;
993      var resource = resourceDao.GetById(resourceId);
994      if (resource == null) throw new SecurityException("Not authorized");
995      if (resource.OwnerUserId != UserManager.CurrentUserId
996          && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
997        throw new SecurityException("Not authorized");
998      }
999      return resource;
1000    }
1001    #endregion
1002  }
1003}
Note: See TracBrowser for help on using the repository browser.