Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/NewHiveService.cs @ 12776

Last change on this file since 12776 was 12776, checked in by dglaser, 9 years ago

#2388:

HeuristicLab.Services.Hive-3.3:

  • HiveStatisticsGenerator.cs: Jobs that are deleted are now automatically marked as completed in the hive statistics tables. This was added because when a job got paused and deleted afterwards, it would still show up as ongoing job in the hive statistics.
  • Minor changes in NewHiveService.cs

HeuristicLab.Services.WebApp.Statistics-3.3:

  • Expired slaves are now shown as offline (previously the last known state was shown)
  • Adjusted dialog height

HeuristicLab.Services.WebApp-3.3:

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