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

Last change on this file since 12691 was 12691, checked in by dglaser, 6 years ago

#2388:

HeuristicLab.Services.Access:
HeuristicLab.Services.Access.DataAccess:

  • Changed connection strings and certificates for local usage

HeuristicLab.Services.Hive.DataAccess:

  • Added compiled queries for frequently used queries
  • Integrated string queries from OptimizedHiveDao

HeuristicLab.Services.Hive:

  • Added NewHeartbeatManager.cs
  • Added NewRoundRobinTaskScheduler.cs
  • Added PerformanceLogger
  • Updated AuthoriziationManager
  • Updated NewHiveService
    • Added Regions
    • Implemented missing methods
    • Improved performance of several queries

HeuristicLab.Services.WebApp.Status:

  • Fixed a bug which caused an error when calculating the average waiting time.
File size: 41.1 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<Task> GetTasks() {
131      // unused
132      throw new NotImplementedException();
133    }
134
135    public IEnumerable<LightweightTask> GetLightweightTasks(IEnumerable<Guid> taskIds) {
136      // unused
137      throw new NotImplementedException();
138    }
139
140    public IEnumerable<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<Job> GetAllJobs() {
401      // unused
402      throw new NotImplementedException();
403    }
404
405    public Guid AddJob(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        return pm.UseTransaction(() => {
411          jobDto.OwnerUserId = UserManager.CurrentUserId;
412          jobDto.DateCreated = DateTime.Now;
413          var job = jobDao.Save(jobDto.ToEntity());
414          pm.SubmitChanges();
415          return job.JobId;
416        });
417      }
418    }
419
420    public void UpdateJob(DT.Job jobDto) {
421      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
422      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
423      using (var pm = PersistenceManager)
424      using (new PerformanceLogger("UpdateJob")) {
425        bool exists = true;
426        var jobDao = pm.JobDao;
427        pm.UseTransaction(() => {
428          var job = jobDao.GetById(jobDto.Id);
429          if (job == null) {
430            exists = false;
431            job = new DA.Job();
432          }
433          jobDto.CopyToEntity(job);
434          if (!exists) {
435            jobDao.Save(job);
436          }
437          pm.SubmitChanges();
438        });
439      }
440    }
441
442    public void DeleteJob(Guid jobId) {
443      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
444      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
445      using (var pm = PersistenceManager)
446      using (new PerformanceLogger("DeleteJob")) {
447        var jobDao = pm.JobDao;
448        pm.UseTransaction(() => {
449          jobDao.Delete(jobId);
450          pm.SubmitChanges();
451        });
452      }
453    }
454    #endregion
455
456    #region JobPermission Methods
457    public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
458      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
459      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
460      using (var pm = PersistenceManager)
461      using (new PerformanceLogger("GrantPermission")) {
462        var jobPermissionDao = pm.JobPermissionDao;
463        var currentUserId = UserManager.CurrentUserId;
464        pm.UseTransaction(() => {
465          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
466          pm.SubmitChanges();
467        });
468      }
469    }
470
471    public void RevokePermission(Guid jobId, Guid grantedUserId) {
472      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
473      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
474      using (var pm = PersistenceManager)
475      using (new PerformanceLogger("RevokePermission")) {
476        var jobPermissionDao = pm.JobPermissionDao;
477        var currentUserId = UserManager.CurrentUserId;
478        pm.UseTransaction(() => {
479          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
480          pm.SubmitChanges();
481        });
482      }
483    }
484
485    public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
486      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
487      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
488      using (var pm = PersistenceManager)
489      using (new PerformanceLogger("GetJobPermissions")) {
490        var jobPermissionDao = pm.JobPermissionDao;
491        return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
492          .Select(x => x.ToDto())
493          .ToList()
494        );
495      }
496    }
497
498    public bool IsAllowedPrivileged() {
499      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
500      return RoleVerifier.IsInRole(HiveRoles.IsAllowedPrivileged);
501    }
502    #endregion
503
504    #region Login Methods
505    public void Hello(DT.Slave slaveInfo) {
506      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
507      if (UserManager.CurrentUser.UserName != "hiveslave") {
508        slaveInfo.OwnerUserId = UserManager.CurrentUserId;
509      }
510      using (var pm = PersistenceManager)
511      using (new PerformanceLogger("Hello")) {
512        var slaveDao = pm.SlaveDao;
513        pm.UseTransaction(() => {
514          var slave = slaveDao.GetById(slaveInfo.Id);
515          if (slave == null) {
516            slaveDao.Save(slaveInfo.ToEntity());
517          } else {
518            bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
519            Guid? oldParentResourceId = slave.ParentResourceId;
520            slaveInfo.CopyToEntity(slave);
521            slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
522            slave.ParentResourceId = oldParentResourceId;
523            slave.LastHeartbeat = DateTime.Now;
524            slave.SlaveState = DA.SlaveState.Idle;
525          }
526          pm.SubmitChanges();
527        });
528      }
529    }
530
531    public void GoodBye(Guid slaveId) {
532      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
533      using (var pm = PersistenceManager)
534      using (new PerformanceLogger("GoodBye")) {
535        var slaveDao = pm.SlaveDao;
536        pm.UseTransaction(() => {
537          var slave = slaveDao.GetById(slaveId);
538          if (slave != null) {
539            slave.SlaveState = DA.SlaveState.Offline;
540            pm.SubmitChanges();
541          }
542        });
543      }
544    }
545    #endregion
546
547    #region Heartbeat Methods
548    public List<MessageContainer> Heartbeat(Heartbeat heartbeat) {
549      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
550      List<MessageContainer> result = new List<MessageContainer>();
551      try {
552        using (new PerformanceLogger("ProcessHeartbeat")) {
553          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
554        }
555      }
556      catch (Exception ex) {
557        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
558      }
559      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
560        TriggerEventManager(false);
561      }
562      return result;
563    }
564    #endregion
565
566    #region Plugin Methods
567    public Plugin GetPlugin(Guid pluginId) {
568      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
569      using (var pm = PersistenceManager)
570      using (new PerformanceLogger("GetPlugin")) {
571        var pluginDao = pm.PluginDao;
572        return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
573      }
574    }
575
576    public Plugin GetPluginByHash(byte[] hash) {
577      // unused
578      throw new NotImplementedException();
579    }
580
581    public Guid AddPlugin(Plugin plugin, List<PluginData> pluginData) {
582      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
583      using (var pm = PersistenceManager)
584      using (new PerformanceLogger("AddPlugin")) {
585        var pluginDao = pm.PluginDao;
586        plugin.UserId = UserManager.CurrentUserId;
587        plugin.DateCreated = DateTime.Now;
588        return pm.UseTransaction(() => {
589          var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
590          if (pluginEntity != null) {
591            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(pluginEntity.PluginId));
592          }
593          pluginEntity = plugin.ToEntity();
594          foreach (var data in pluginData) {
595            data.PluginId = default(Guid);
596            pluginEntity.PluginData.Add(data.ToEntity());
597          }
598          pluginDao.Save(pluginEntity);
599          pm.SubmitChanges();
600          return pluginEntity.PluginId;
601        });
602      }
603    }
604
605    public IEnumerable<Plugin> GetPlugins() {
606      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
607      using (var pm = PersistenceManager)
608      using (new PerformanceLogger("GetPlugins")) {
609        var pluginDao = pm.PluginDao;
610        return pm.UseTransaction(() => pluginDao.GetAll()
611          .Where(x => x.Hash != null)
612          .Select(x => x.ToDto())
613          .ToList()
614        );
615      }
616    }
617
618    public IEnumerable<PluginData> GetPluginDatas(List<Guid> pluginIds) {
619      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
620      using (var pm = PersistenceManager)
621      using (new PerformanceLogger("GetPluginDatas")) {
622        var pluginDataDao = pm.PluginDataDao;
623        return pm.UseTransaction(() => pluginDataDao.GetAll()
624            .Where(x => pluginIds.Contains(x.PluginId))
625            .Select(x => x.ToDto())
626            .ToList()
627        );
628      }
629    }
630
631    public void DeletePlugin(Guid pluginId) {
632      // unused
633      throw new NotImplementedException();
634    }
635    #endregion
636
637    #region ResourcePermission Methods
638    public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
639      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
640      using (var pm = PersistenceManager)
641      using (new PerformanceLogger("GrantResourcePermissions")) {
642        pm.UseTransaction(() => {
643          var resource = AuthorizeForResource(pm, resourceId);
644          var resourcePermissions = resource.ResourcePermissions.ToList();
645          foreach (var id in grantedUserIds) {
646            if (resourcePermissions.All(x => x.GrantedUserId != id)) {
647              resource.ResourcePermissions.Add(new DA.ResourcePermission {
648                GrantedUserId = id,
649                GrantedByUserId = UserManager.CurrentUserId
650              });
651            }
652          }
653          pm.SubmitChanges();
654        });
655      }
656    }
657
658    public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
659      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
660      using (var pm = PersistenceManager)
661      using (new PerformanceLogger("RevokeResourcePermissions")) {
662        var resourcePermissionDao = pm.ResourcePermissionDao;
663        pm.UseTransaction(() => {
664          AuthorizeForResource(pm, resourceId);
665          resourcePermissionDao.DeleteByResourceAndGrantedUserId(resourceId, grantedUserIds);
666        });
667      }
668    }
669
670    public IEnumerable<ResourcePermission> GetResourcePermissions(Guid resourceId) {
671      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
672      using (var pm = PersistenceManager)
673      using (new PerformanceLogger("GetResourcePermissions")) {
674        var resourcePermissionDao = pm.ResourcePermissionDao;
675        return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
676          .Select(x => x.ToDto())
677          .ToList()
678        );
679      }
680    }
681    #endregion
682
683    #region Resource Methods
684    public IEnumerable<Resource> GetChildResources(Guid resourceId) {
685      // unused
686      throw new NotImplementedException();
687    }
688    #endregion
689
690    #region Slave Methods
691    public Guid AddSlave(DT.Slave slaveDto) {
692      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
693      using (var pm = PersistenceManager)
694      using (new PerformanceLogger("AddSlave")) {
695        var slaveDao = pm.SlaveDao;
696        return pm.UseTransaction(() => {
697          var slave = slaveDao.Save(slaveDto.ToEntity());
698          pm.SubmitChanges();
699          return slave.ResourceId;
700        });
701      }
702    }
703
704    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
705      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
706      using (var pm = PersistenceManager)
707      using (new PerformanceLogger("AddSlaveGroup")) {
708        var slaveGroupDao = pm.SlaveGroupDao;
709        return pm.UseTransaction(() => {
710          if (slaveGroupDto.Id == Guid.Empty) {
711            slaveGroupDto.Id = Guid.NewGuid();
712          }
713          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
714          pm.SubmitChanges();
715          return slaveGroup.ResourceId;
716        });
717      }
718    }
719
720    public Slave GetSlave(Guid slaveId) {
721      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
722      using (var pm = PersistenceManager)
723      using (new PerformanceLogger("GetSlave")) {
724        var slaveDao = pm.SlaveDao;
725        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
726      }
727    }
728
729    public SlaveGroup GetSlaveGroup(Guid slaveGroupId) {
730      // unused
731      throw new NotImplementedException();
732    }
733
734    public IEnumerable<Slave> GetSlaves() {
735      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
736      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
737      using (var pm = PersistenceManager)
738      using (new PerformanceLogger("GetSlaves")) {
739        var slaveDao = pm.SlaveDao;
740        var resourcePermissionDao = pm.ResourcePermissionDao;
741        var currentUserId = UserManager.CurrentUserId;
742        return pm.UseTransaction(() => {
743          var resourcePermissions = resourcePermissionDao.GetAll();
744          return slaveDao.GetAll()
745            .Where(x => isAdministrator
746              || x.OwnerUserId == null
747              || x.OwnerUserId == currentUserId
748              || UserManager.VerifyUser(currentUserId, resourcePermissions
749                  .Where(y => y.ResourceId == x.ResourceId)
750                  .Select(z => z.GrantedUserId)
751                  .ToList())
752              )
753            .Select(x => x.ToDto())
754            .ToList();
755        });
756      }
757    }
758
759    public IEnumerable<SlaveGroup> GetSlaveGroups() {
760      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
761      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
762      using (var pm = PersistenceManager)
763      using (new PerformanceLogger("GetSlaveGroups")) {
764        var slaveGroupDao = pm.SlaveGroupDao;
765        var resourcePermissionDao = pm.ResourcePermissionDao;
766        var currentUserId = UserManager.CurrentUserId;
767        return pm.UseTransaction(() => {
768          var resourcePermissions = resourcePermissionDao.GetAll();
769          return slaveGroupDao.GetAll()
770            .Where(x => isAdministrator
771              || x.OwnerUserId == null
772              || x.OwnerUserId == currentUserId
773              || UserManager.VerifyUser(currentUserId, resourcePermissions
774                  .Where(y => y.ResourceId == x.ResourceId)
775                  .Select(z => z.GrantedUserId)
776                  .ToList())
777              )
778            .Select(x => x.ToDto())
779            .ToList();
780        });
781      }
782    }
783
784    public void UpdateSlave(DT.Slave slaveDto) {
785      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
786      using (var pm = PersistenceManager)
787      using (new PerformanceLogger("UpdateSlave")) {
788        var slaveDao = pm.SlaveDao;
789        pm.UseTransaction(() => {
790          var slave = slaveDao.GetById(slaveDto.Id);
791          if (slave != null) {
792            slaveDto.CopyToEntity(slave);
793          } else {
794            slaveDao.Save(slaveDto.ToEntity());
795          }
796          pm.SubmitChanges();
797        });
798      }
799    }
800
801    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
802      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
803      using (var pm = PersistenceManager)
804      using (new PerformanceLogger("UpdateSlaveGroup")) {
805        var slaveGroupDao = pm.SlaveGroupDao;
806        pm.UseTransaction(() => {
807          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
808          if (slaveGroup != null) {
809            slaveGroupDto.CopyToEntity(slaveGroup);
810          } else {
811            slaveGroupDao.Save(slaveGroupDto.ToEntity());
812          }
813          pm.SubmitChanges();
814        });
815      }
816    }
817
818    public void DeleteSlave(Guid slaveId) {
819      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
820      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
821      using (var pm = PersistenceManager)
822      using (new PerformanceLogger("DeleteSlave")) {
823        var slaveDao = pm.SlaveDao;
824        pm.UseTransaction(() => {
825          slaveDao.Delete(slaveId);
826        });
827      }
828    }
829
830    public void DeleteSlaveGroup(Guid slaveGroupId) {
831      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
832      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
833      using (var pm = PersistenceManager)
834      using (new PerformanceLogger("DeleteSlaveGroup")) {
835        var slaveGroupDao = pm.SlaveGroupDao;
836        pm.UseTransaction(() => {
837          slaveGroupDao.Delete(slaveGroupId);
838        });
839      }
840    }
841
842    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
843      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
844      using (var pm = PersistenceManager)
845      using (new PerformanceLogger("AddResourceToGroup")) {
846        var resourceDao = pm.ResourceDao;
847        pm.UseTransaction(() => {
848          var resource = resourceDao.GetById(resourceId);
849          resource.ParentResourceId = slaveGroupId;
850          pm.SubmitChanges();
851        });
852      }
853    }
854
855    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
856      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
857      using (var pm = PersistenceManager)
858      using (new PerformanceLogger("RemoveResourceFromGroup")) {
859        var resourceDao = pm.ResourceDao;
860        pm.UseTransaction(() => {
861          var resource = resourceDao.GetById(resourceId);
862          resource.ParentResourceId = null;
863          pm.SubmitChanges();
864        });
865      }
866    }
867
868    public Guid GetResourceId(string resourceName) {
869      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
870      using (var pm = PersistenceManager)
871      using (new PerformanceLogger("GetResourceId")) {
872        var resourceDao = pm.ResourceDao;
873        return pm.UseTransaction(() => {
874          var resource = resourceDao.GetByName(resourceName);
875          return resource != null ? resource.ResourceId : Guid.Empty;
876        });
877      }
878    }
879
880    public IEnumerable<Task> GetTasksByResourceId(Guid resourceId) {
881      // unused
882      throw new NotImplementedException();
883    }
884
885    public void TriggerEventManager(bool force) {
886      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Slave);
887      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
888      bool cleanup;
889      using (var pm = PersistenceManager)
890      using (new PerformanceLogger("TriggerEventManager")) {
891        cleanup = false;
892        var lifecycleDao = pm.LifecycleDao;
893        pm.UseTransaction(() => {
894          var lastLifecycle = lifecycleDao.GetLastLifecycle();
895          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
896          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
897            lifecycleDao.UpdateLifecycle();
898            cleanup = true;
899            pm.SubmitChanges();
900          }
901        }, true);
902      }
903      if (cleanup) {
904        EventManager.Cleanup();
905      }
906    }
907
908    public int GetNewHeartbeatInterval(Guid slaveId) {
909      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
910      using (var pm = PersistenceManager)
911      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
912        var slaveDao = pm.SlaveDao;
913        return pm.UseTransaction(() => {
914          var slave = slaveDao.GetById(slaveId);
915          if (slave != null) {
916            return slave.HbInterval;
917          }
918          return -1;
919        });
920      }
921    }
922    #endregion
923
924    #region Downtime Methods
925    public Guid AddDowntime(DT.Downtime downtimeDto) {
926      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
927      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
928      using (var pm = PersistenceManager)
929      using (new PerformanceLogger("AddDowntime")) {
930        var downtimeDao = pm.DowntimeDao;
931        return pm.UseTransaction(() => {
932          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
933          pm.SubmitChanges();
934          return downtime.ResourceId;
935        });
936      }
937    }
938
939    public void DeleteDowntime(Guid downtimeId) {
940      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
941      using (var pm = PersistenceManager)
942      using (new PerformanceLogger("DeleteDowntime")) {
943        var downtimeDao = pm.DowntimeDao;
944        pm.UseTransaction(() => {
945          downtimeDao.Delete(downtimeId);
946          pm.SubmitChanges();
947        });
948      }
949    }
950
951    public void UpdateDowntime(DT.Downtime downtimeDto) {
952      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
953      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
954      using (var pm = PersistenceManager)
955      using (new PerformanceLogger("UpdateDowntime")) {
956        var downtimeDao = pm.DowntimeDao;
957        pm.UseTransaction(() => {
958          var downtime = downtimeDao.GetById(downtimeDto.Id);
959          if (downtime != null) {
960            downtimeDto.CopyToEntity(downtime);
961          } else {
962            downtimeDao.Save(downtimeDto.ToEntity());
963          }
964          pm.SubmitChanges();
965        });
966      }
967    }
968
969    public IEnumerable<Downtime> GetDowntimesForResource(Guid resourceId) {
970      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
971      using (var pm = PersistenceManager)
972      using (new PerformanceLogger("GetDowntimesForResource")) {
973        var downtimeDao = pm.DowntimeDao;
974        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
975          .Select(x => x.ToDto())
976          .ToList()
977        );
978      }
979    }
980    #endregion
981
982    #region User Methods
983    public string GetUsernameByUserId(Guid userId) {
984      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
985      var user = UserManager.GetUserById(userId);
986      return user != null ? user.UserName : null;
987    }
988
989    public Guid GetUserIdByUsername(string username) {
990      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
991      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
992      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
993    }
994    #endregion
995
996    #region UserPriorities Methods
997    public IEnumerable<UserPriority> GetUserPriorities() {
998      using (var pm = PersistenceManager)
999      using (new PerformanceLogger("GetUserPriorities")) {
1000        var userPriorityDao = pm.UserPriorityDao;
1001        return pm.UseTransaction(() => userPriorityDao.GetAll()
1002          .Select(x => x.ToDto())
1003          .ToList()
1004        );
1005      }
1006    }
1007    #endregion
1008
1009    #region Statistics Methods
1010    public IEnumerable<Statistics> GetStatistics() {
1011      // unused
1012      throw new NotImplementedException();
1013    }
1014
1015    public IEnumerable<Statistics> GetStatisticsForTimePeriod(DateTime @from, DateTime to) {
1016      // unused
1017      throw new NotImplementedException();
1018    }
1019    #endregion
1020
1021    #region Private Helper Methods
1022    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
1023      var stateLogDao = pm.StateLogDao;
1024      var taskStateEntity = taskState.ToEntity();
1025      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
1026          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
1027          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
1028        task.Command = null;
1029      } else if (taskStateEntity == DA.TaskState.Paused && task.Command != null) {
1030        taskStateEntity = DA.TaskState.Waiting;
1031      }
1032      stateLogDao.Save(new DA.StateLog {
1033        State = taskStateEntity,
1034        DateTime = DateTime.Now,
1035        TaskId = task.TaskId,
1036        UserId = userId,
1037        SlaveId = slaveId,
1038        Exception = exception
1039      });
1040      task.State = taskStateEntity;
1041    }
1042
1043    private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
1044      var resourceDao = pm.ResourceDao;
1045      var resource = resourceDao.GetById(resourceId);
1046      if (resource == null) throw new SecurityException("Not authorized");
1047      if (resource.OwnerUserId != UserManager.CurrentUserId
1048          && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
1049        throw new SecurityException("Not authorized");
1050      }
1051      return resource;
1052    }
1053
1054    [MethodImpl(MethodImplOptions.NoInlining)]
1055    public string GetCurrentMethod() {
1056      StackTrace st = new StackTrace();
1057      StackFrame sf = st.GetFrame(1);
1058      return sf.GetMethod().Name;
1059    }
1060    #endregion
1061  }
1062}
Note: See TracBrowser for help on using the repository browser.