Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 12926 was 12926, checked in by jkarder, 9 years ago

#2355:

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