Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 13007

Last change on this file since 13007 was 13007, checked in by ascheibe, 9 years ago

#2479 merged r12972 into stable

File size: 39.1 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            }
[12962]313            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
[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            }
[12962]357            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
[12691]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
[12963]471    // BackwardsCompatibility3.3
472    #region Backwards compatible code, remove with 3.4
[12584]473    public bool IsAllowedPrivileged() {
[12963]474      return true;
[12584]475    }
[12691]476    #endregion
[12963]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);
[13007]631          pm.SubmitChanges();
[12691]632        });
633      }
[12584]634    }
635
[12776]636    public IEnumerable<DT.ResourcePermission> GetResourcePermissions(Guid resourceId) {
[12691]637      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[12857]638      var pm = PersistenceManager;
[12691]639      using (new PerformanceLogger("GetResourcePermissions")) {
640        var resourcePermissionDao = pm.ResourcePermissionDao;
641        return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
642          .Select(x => x.ToDto())
643          .ToList()
644        );
645      }
[12584]646    }
[12691]647    #endregion
[12584]648
[12691]649    #region Slave Methods
650    public Guid AddSlave(DT.Slave slaveDto) {
651      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
[12857]652      var pm = PersistenceManager;
[12691]653      using (new PerformanceLogger("AddSlave")) {
654        var slaveDao = pm.SlaveDao;
655        return pm.UseTransaction(() => {
656          var slave = slaveDao.Save(slaveDto.ToEntity());
657          pm.SubmitChanges();
658          return slave.ResourceId;
659        });
660      }
[12584]661    }
662
[12691]663    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
664      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[12857]665      var pm = PersistenceManager;
[12691]666      using (new PerformanceLogger("AddSlaveGroup")) {
667        var slaveGroupDao = pm.SlaveGroupDao;
668        return pm.UseTransaction(() => {
669          if (slaveGroupDto.Id == Guid.Empty) {
670            slaveGroupDto.Id = Guid.NewGuid();
671          }
672          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
673          pm.SubmitChanges();
674          return slaveGroup.ResourceId;
675        });
676      }
[12584]677    }
678
[12776]679    public DT.Slave GetSlave(Guid slaveId) {
[12691]680      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
[12857]681      var pm = PersistenceManager;
[12691]682      using (new PerformanceLogger("GetSlave")) {
683        var slaveDao = pm.SlaveDao;
684        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
685      }
[12584]686    }
687
[12776]688    public IEnumerable<DT.Slave> GetSlaves() {
[12691]689      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
690      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
[12857]691      var pm = PersistenceManager;
[12691]692      using (new PerformanceLogger("GetSlaves")) {
693        var slaveDao = pm.SlaveDao;
694        var resourcePermissionDao = pm.ResourcePermissionDao;
695        var currentUserId = UserManager.CurrentUserId;
696        return pm.UseTransaction(() => {
697          var resourcePermissions = resourcePermissionDao.GetAll();
698          return slaveDao.GetAll()
699            .Where(x => isAdministrator
700              || x.OwnerUserId == null
701              || x.OwnerUserId == currentUserId
702              || UserManager.VerifyUser(currentUserId, resourcePermissions
703                  .Where(y => y.ResourceId == x.ResourceId)
704                  .Select(z => z.GrantedUserId)
705                  .ToList())
706              )
707            .Select(x => x.ToDto())
708            .ToList();
709        });
710      }
[12584]711    }
712
[12776]713    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
[12691]714      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
715      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
[12857]716      var pm = PersistenceManager;
[12691]717      using (new PerformanceLogger("GetSlaveGroups")) {
718        var slaveGroupDao = pm.SlaveGroupDao;
719        var resourcePermissionDao = pm.ResourcePermissionDao;
720        var currentUserId = UserManager.CurrentUserId;
721        return pm.UseTransaction(() => {
722          var resourcePermissions = resourcePermissionDao.GetAll();
723          return slaveGroupDao.GetAll()
724            .Where(x => isAdministrator
725              || x.OwnerUserId == null
726              || x.OwnerUserId == currentUserId
727              || UserManager.VerifyUser(currentUserId, resourcePermissions
728                  .Where(y => y.ResourceId == x.ResourceId)
729                  .Select(z => z.GrantedUserId)
730                  .ToList())
731              )
732            .Select(x => x.ToDto())
733            .ToList();
734        });
735      }
[12584]736    }
737
[12691]738    public void UpdateSlave(DT.Slave slaveDto) {
739      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[12857]740      var pm = PersistenceManager;
[12691]741      using (new PerformanceLogger("UpdateSlave")) {
742        var slaveDao = pm.SlaveDao;
743        pm.UseTransaction(() => {
744          var slave = slaveDao.GetById(slaveDto.Id);
745          if (slave != null) {
746            slaveDto.CopyToEntity(slave);
747          } else {
748            slaveDao.Save(slaveDto.ToEntity());
749          }
750          pm.SubmitChanges();
751        });
752      }
[12584]753    }
754
[12691]755    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
756      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[12857]757      var pm = PersistenceManager;
[12691]758      using (new PerformanceLogger("UpdateSlaveGroup")) {
759        var slaveGroupDao = pm.SlaveGroupDao;
760        pm.UseTransaction(() => {
761          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
762          if (slaveGroup != null) {
763            slaveGroupDto.CopyToEntity(slaveGroup);
764          } else {
765            slaveGroupDao.Save(slaveGroupDto.ToEntity());
766          }
767          pm.SubmitChanges();
768        });
769      }
[12584]770    }
771
772    public void DeleteSlave(Guid slaveId) {
[12691]773      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
774      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
[12857]775      var pm = PersistenceManager;
[12691]776      using (new PerformanceLogger("DeleteSlave")) {
777        var slaveDao = pm.SlaveDao;
778        pm.UseTransaction(() => {
779          slaveDao.Delete(slaveId);
[13007]780          pm.SubmitChanges();
[12691]781        });
782      }
[12584]783    }
784
785    public void DeleteSlaveGroup(Guid slaveGroupId) {
[12691]786      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
787      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
[12857]788      var pm = PersistenceManager;
[12691]789      using (new PerformanceLogger("DeleteSlaveGroup")) {
790        var slaveGroupDao = pm.SlaveGroupDao;
791        pm.UseTransaction(() => {
792          slaveGroupDao.Delete(slaveGroupId);
[13007]793          pm.SubmitChanges();
[12691]794        });
795      }
[12584]796    }
797
798    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
[12691]799      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
[12857]800      var pm = PersistenceManager;
[12691]801      using (new PerformanceLogger("AddResourceToGroup")) {
802        var resourceDao = pm.ResourceDao;
803        pm.UseTransaction(() => {
804          var resource = resourceDao.GetById(resourceId);
805          resource.ParentResourceId = slaveGroupId;
806          pm.SubmitChanges();
807        });
808      }
[12584]809    }
810
811    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
[12691]812      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
[12857]813      var pm = PersistenceManager;
[12691]814      using (new PerformanceLogger("RemoveResourceFromGroup")) {
815        var resourceDao = pm.ResourceDao;
816        pm.UseTransaction(() => {
817          var resource = resourceDao.GetById(resourceId);
818          resource.ParentResourceId = null;
819          pm.SubmitChanges();
820        });
821      }
[12584]822    }
823
824    public Guid GetResourceId(string resourceName) {
[12691]825      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[12857]826      var pm = PersistenceManager;
[12691]827      using (new PerformanceLogger("GetResourceId")) {
828        var resourceDao = pm.ResourceDao;
829        return pm.UseTransaction(() => {
830          var resource = resourceDao.GetByName(resourceName);
831          return resource != null ? resource.ResourceId : Guid.Empty;
832        });
833      }
[12584]834    }
835
836    public void TriggerEventManager(bool force) {
[12857]837      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
[12691]838      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
839      bool cleanup;
[12857]840      var pm = PersistenceManager;
[12691]841      using (new PerformanceLogger("TriggerEventManager")) {
842        cleanup = false;
843        var lifecycleDao = pm.LifecycleDao;
844        pm.UseTransaction(() => {
845          var lastLifecycle = lifecycleDao.GetLastLifecycle();
846          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
847          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
848            lifecycleDao.UpdateLifecycle();
849            cleanup = true;
850            pm.SubmitChanges();
851          }
852        }, true);
853      }
854      if (cleanup) {
855        EventManager.Cleanup();
856      }
[12584]857    }
858
859    public int GetNewHeartbeatInterval(Guid slaveId) {
[12691]860      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
[12857]861      var pm = PersistenceManager;
[12691]862      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
863        var slaveDao = pm.SlaveDao;
864        return pm.UseTransaction(() => {
865          var slave = slaveDao.GetById(slaveId);
866          if (slave != null) {
867            return slave.HbInterval;
868          }
869          return -1;
870        });
871      }
[12584]872    }
[12691]873    #endregion
[12584]874
[12691]875    #region Downtime Methods
876    public Guid AddDowntime(DT.Downtime downtimeDto) {
877      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
878      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
[12857]879      var pm = PersistenceManager;
[12691]880      using (new PerformanceLogger("AddDowntime")) {
881        var downtimeDao = pm.DowntimeDao;
882        return pm.UseTransaction(() => {
883          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
884          pm.SubmitChanges();
885          return downtime.ResourceId;
886        });
887      }
[12584]888    }
889
890    public void DeleteDowntime(Guid downtimeId) {
[12691]891      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[12857]892      var pm = PersistenceManager;
[12691]893      using (new PerformanceLogger("DeleteDowntime")) {
894        var downtimeDao = pm.DowntimeDao;
895        pm.UseTransaction(() => {
896          downtimeDao.Delete(downtimeId);
897          pm.SubmitChanges();
898        });
899      }
[12584]900    }
901
[12691]902    public void UpdateDowntime(DT.Downtime downtimeDto) {
903      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
904      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
[12857]905      var pm = PersistenceManager;
[12691]906      using (new PerformanceLogger("UpdateDowntime")) {
907        var downtimeDao = pm.DowntimeDao;
908        pm.UseTransaction(() => {
909          var downtime = downtimeDao.GetById(downtimeDto.Id);
910          if (downtime != null) {
911            downtimeDto.CopyToEntity(downtime);
912          } else {
913            downtimeDao.Save(downtimeDto.ToEntity());
914          }
915          pm.SubmitChanges();
916        });
917      }
[12584]918    }
919
[12776]920    public IEnumerable<DT.Downtime> GetDowntimesForResource(Guid resourceId) {
[12691]921      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[12857]922      var pm = PersistenceManager;
[12691]923      using (new PerformanceLogger("GetDowntimesForResource")) {
924        var downtimeDao = pm.DowntimeDao;
925        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
926          .Select(x => x.ToDto())
927          .ToList()
928        );
929      }
[12584]930    }
[12691]931    #endregion
[12584]932
[12691]933    #region User Methods
[12584]934    public string GetUsernameByUserId(Guid userId) {
[12691]935      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
936      var user = UserManager.GetUserById(userId);
937      return user != null ? user.UserName : null;
[12584]938    }
939
940    public Guid GetUserIdByUsername(string username) {
[12691]941      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
942      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
943      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
[12584]944    }
[12691]945    #endregion
[12584]946
[12691]947    #region UserPriorities Methods
[12776]948    public IEnumerable<DT.UserPriority> GetUserPriorities() {
[12857]949      var pm = PersistenceManager;
[12691]950      using (new PerformanceLogger("GetUserPriorities")) {
951        var userPriorityDao = pm.UserPriorityDao;
952        return pm.UseTransaction(() => userPriorityDao.GetAll()
953          .Select(x => x.ToDto())
954          .ToList()
955        );
956      }
[12584]957    }
[12691]958    #endregion
[12584]959
[12691]960    #region Private Helper Methods
961    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
962      var stateLogDao = pm.StateLogDao;
963      var taskStateEntity = taskState.ToEntity();
964      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
965          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
966          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
967        task.Command = null;
968      } else if (taskStateEntity == DA.TaskState.Paused && task.Command != null) {
[12857]969        // slave paused and uploaded the task (no user-command) -> set waiting.
[12691]970        taskStateEntity = DA.TaskState.Waiting;
971      }
972      stateLogDao.Save(new DA.StateLog {
973        State = taskStateEntity,
974        DateTime = DateTime.Now,
975        TaskId = task.TaskId,
976        UserId = userId,
977        SlaveId = slaveId,
978        Exception = exception
979      });
980      task.State = taskStateEntity;
981    }
982
983    private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
984      var resourceDao = pm.ResourceDao;
985      var resource = resourceDao.GetById(resourceId);
986      if (resource == null) throw new SecurityException("Not authorized");
987      if (resource.OwnerUserId != UserManager.CurrentUserId
988          && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
989        throw new SecurityException("Not authorized");
990      }
991      return resource;
992    }
993    #endregion
[12584]994  }
995}
Note: See TracBrowser for help on using the repository browser.