Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 9369

Last change on this file since 9369 was 9369, checked in by pfleck, 11 years ago

#2030
Aborted transactions are logged into file.
Enabled PerformanceCounter for Service-Operations.
New Slaves are assigned to HEAL ResourceGroup automatically.

File size: 31.2 KB
RevLine 
[6983]1#region License Information
2/* HeuristicLab
[7259]3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[6983]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.ServiceModel;
26using HeuristicLab.Services.Hive.DataTransfer;
27using HeuristicLab.Services.Hive.ServiceContracts;
28using DA = HeuristicLab.Services.Hive.DataAccess;
29using DT = HeuristicLab.Services.Hive.DataTransfer;
30
31
32namespace HeuristicLab.Services.Hive {
33
34  /// <summary>
35  /// Implementation of the Hive service (interface <see cref="IHiveService"/>).
36  /// We need 'IgnoreExtensionDataObject' Attribute for the slave to work.
37  /// </summary>
38  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
39  public class HiveService : IHiveService {
40    private IHiveDao dao {
41      get { return ServiceLocator.Instance.HiveDao; }
42    }
[8051]43    private Access.IRoleVerifier authen {
44      get { return ServiceLocator.Instance.RoleVerifier; }
[6983]45    }
46    private IAuthorizationManager author {
47      get { return ServiceLocator.Instance.AuthorizationManager; }
48    }
49    private DataAccess.ITransactionManager trans {
50      get { return ServiceLocator.Instance.TransactionManager; }
51    }
52    private IEventManager eventManager {
53      get { return ServiceLocator.Instance.EventManager; }
54    }
[8051]55    private Access.IUserManager userManager {
[6983]56      get { return ServiceLocator.Instance.UserManager; }
57    }
58    private HeartbeatManager heartbeatManager {
59      get { return ServiceLocator.Instance.HeartbeatManager; }
60    }
61
62    #region Task Methods
63    public Guid AddTask(Task task, TaskData taskData, IEnumerable<Guid> resourceIds) {
64      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
65      return trans.UseTransaction(() => {
66        task.Id = dao.AddTask(task);
67        taskData.TaskId = task.Id;
68        taskData.LastUpdate = DateTime.Now;
[9257]69        dao.AssignJobToResource(task.Id, resourceIds);
[6983]70        dao.AddTaskData(taskData);
71        dao.UpdateTaskState(task.Id, DA.TaskState.Waiting, null, userManager.CurrentUserId, null);
72        return taskData.TaskId;
73      }, false, true);
74    }
75
76    public Guid AddChildTask(Guid parentTaskId, Task task, TaskData taskData) {
77      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
78      return trans.UseTransaction(() => {
79        task.ParentTaskId = parentTaskId;
80        return AddTask(task, taskData, dao.GetAssignedResources(parentTaskId).Select(x => x.Id));
81      }, false, true);
82    }
83
84    public Task GetTask(Guid taskId) {
85      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
86      author.AuthorizeForTask(taskId, Permission.Read);
[7045]87
88      return trans.UseTransaction(() => {
89        return dao.GetTask(taskId);
90      }, false, false);
[6983]91    }
92
93    public IEnumerable<Task> GetTasks() {
94      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[9257]95      return trans.UseTransaction(() => {
96        var tasks = dao.GetTasks(x => true);
97        foreach (var task in tasks)
98          author.AuthorizeForTask(task.Id, Permission.Read);
99        return tasks;
100      });
[6983]101    }
102
103    public IEnumerable<LightweightTask> GetLightweightTasks(IEnumerable<Guid> taskIds) {
104      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[7045]105
106      return trans.UseTransaction(() => {
107        var tasks = dao.GetTasks(x => taskIds.Contains(x.TaskId)).Select(x => new LightweightTask(x)).ToArray();
108        foreach (var task in tasks)
109          author.AuthorizeForTask(task.Id, Permission.Read);
110        return tasks;
111      }, false, false);
[6983]112    }
113
114    public IEnumerable<LightweightTask> GetLightweightChildTasks(Guid? parentTaskId, bool recursive, bool includeParent) {
115      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[7045]116
117      return trans.UseTransaction(() => {
118        var tasks = GetChildTasks(parentTaskId, recursive, includeParent).Select(x => new LightweightTask(x)).ToArray();
119        foreach (var task in tasks)
120          author.AuthorizeForTask(task.Id, Permission.Read);
121        return tasks;
122      }, false, false);
[6983]123    }
124
125    public IEnumerable<LightweightTask> GetLightweightJobTasks(Guid jobId) {
126      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
127      author.AuthorizeForJob(jobId, Permission.Read);
[7045]128
129      return trans.UseTransaction(() => {
[9035]130        return dao.GetLightweightTasks(task => task.JobId == jobId).ToArray();
[9219]131      }, false, true);
132    }
133
134    public IEnumerable<LightweightTask> GetLightweightJobTasksWithoutStateLog(Guid jobId) {
135      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
136      author.AuthorizeForJob(jobId, Permission.Read);
137
138      return trans.UseTransaction(() => {
139        return dao.GetLightweightTasksWithoutStateLog(task => task.JobId == jobId).ToArray();
[7045]140      }, false, false);
[6983]141    }
142
143    public TaskData GetTaskData(Guid taskId) {
144      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
145      author.AuthorizeForTask(taskId, Permission.Read);
[9257]146
147      return trans.UseTransaction(() => {
148        return dao.GetTaskData(taskId);
149      });
[6983]150    }
151
152    public void UpdateTask(Task taskDto) {
153      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
154      author.AuthorizeForTask(taskDto.Id, Permission.Full);
[9257]155
[6983]156      trans.UseTransaction(() => {
[9123]157        dao.UpdateTaskAndPlugins(taskDto);
[6983]158      });
159    }
160
161    public void UpdateTaskData(Task task, TaskData taskData) {
162      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
163      author.AuthorizeForTask(task.Id, Permission.Full);
[9257]164
165      trans.UseTransaction(() => {
166        dao.UpdateTaskAndPlugins(task);
167      });
168
169      trans.UseTransaction(() => {
170        taskData.LastUpdate = DateTime.Now;
171        dao.UpdateTaskData(taskData);
172      });
[6983]173    }
174
175    public void DeleteTask(Guid taskId) {
176      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
177      author.AuthorizeForTask(taskId, Permission.Full);
178      trans.UseTransaction(() => {
179        dao.DeleteTask(taskId);
180      });
181    }
182
183    public void DeleteChildTasks(Guid parentTaskId) {
184      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
185      author.AuthorizeForTask(parentTaskId, Permission.Full);
186      trans.UseTransaction(() => {
187        var tasks = GetChildTasks(parentTaskId, true, false);
188        foreach (var task in tasks) {
189          dao.DeleteTask(task.Id);
190          dao.DeleteTaskData(task.Id);
191        };
192      });
193    }
194
195    public Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
196      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
197      author.AuthorizeForTask(taskId, Permission.Full);
198      return trans.UseTransaction(() => {
199        Task task = dao.UpdateTaskState(taskId, DataTransfer.Convert.ToEntity(taskState), slaveId, userId, exception);
200
201        if (task.Command.HasValue && task.Command.Value == Command.Pause && task.State == TaskState.Paused) {
202          task.Command = null;
203        } else if (task.Command.HasValue && task.Command.Value == Command.Abort && task.State == TaskState.Aborted) {
204          task.Command = null;
205        } else if (task.Command.HasValue && task.Command.Value == Command.Stop && task.State == TaskState.Aborted) {
206          task.Command = null;
207        } else if (taskState == TaskState.Paused && !task.Command.HasValue) {
208          // slave paused and uploaded the task (no user-command) -> set waiting.
209          task = dao.UpdateTaskState(taskId, DataTransfer.Convert.ToEntity(TaskState.Waiting), slaveId, userId, exception);
210        }
211
[9123]212        dao.UpdateTaskAndPlugins(task);
[6983]213        return task;
214      });
215    }
216
217    public IEnumerable<Task> GetTasksByResourceId(Guid resourceId) {
218      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
219      var tasks = trans.UseTransaction(() => dao.GetJobsByResourceId(resourceId));
220      foreach (var task in tasks)
221        author.AuthorizeForTask(task.Id, Permission.Read);
222      return tasks;
223    }
224    #endregion
225
226    #region Task Control Methods
227    public void StopTask(Guid taskId) {
228      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
229      author.AuthorizeForTask(taskId, Permission.Full);
230      trans.UseTransaction(() => {
231        var task = dao.GetTask(taskId);
232        if (task.State == TaskState.Calculating || task.State == TaskState.Transferring) {
233          task.Command = Command.Stop;
234          dao.UpdateTask(task);
235        } else {
236          if (task.State != TaskState.Aborted && task.State != TaskState.Finished && task.State != TaskState.Failed) {
237            task = UpdateTaskState(taskId, TaskState.Aborted, null, null, string.Empty);
238          }
239        }
240      });
241    }
242
243    public void PauseTask(Guid taskId) {
244      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
245      author.AuthorizeForTask(taskId, Permission.Full);
246      trans.UseTransaction(() => {
247        var job = dao.GetTask(taskId);
248        if (job.State == TaskState.Calculating || job.State == TaskState.Transferring) {
249          job.Command = Command.Pause;
250          dao.UpdateTask(job);
251        } else {
252          job = UpdateTaskState(taskId, TaskState.Paused, null, null, string.Empty);
253        }
254      });
255    }
256
257    public void RestartTask(Guid taskId) {
258      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
259      author.AuthorizeForTask(taskId, Permission.Full);
260      trans.UseTransaction(() => {
261        Task task = dao.UpdateTaskState(taskId, DA.TaskState.Waiting, null, userManager.CurrentUserId, string.Empty);
262        task.Command = null;
263        dao.UpdateTask(task);
264      });
265    }
266    #endregion
267
268    #region Job Methods
269    public Job GetJob(Guid id) {
270      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
271      author.AuthorizeForJob(id, Permission.Read);
[9232]272      return trans.UseTransaction(() => {
273        var job = dao.GetJobs(x =>
274              x.JobId == id
275              && (x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0)
276            ).FirstOrDefault();
277        if (job != null) {
278          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
279          job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
280        }
281        return job;
282      });
[6983]283    }
284
285    public IEnumerable<Job> GetJobs() {
286      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[9232]287      return trans.UseTransaction(() => {
288        var jobs = dao.GetJobs(x => x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0);
289        foreach (var job in jobs) {
290          author.AuthorizeForJob(job.Id, Permission.Read);
291          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
292          job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
293        }
294        return jobs;
295      });
[6983]296    }
297
298    public IEnumerable<Job> GetAllJobs() {
299      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
[9232]300      return trans.UseTransaction(() => {
301        var jobs = dao.GetJobs(x => true);
302        foreach (var job in jobs) { // no authorization here, since this method is admin-only! (admin is allowed to read all task)
303          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
304          job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
305        }
306        return jobs;
307      });
[6983]308    }
309
310    public Guid AddJob(Job jobDto) {
311      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
312      return trans.UseTransaction(() => {
313        jobDto.OwnerUserId = userManager.CurrentUserId;
314        jobDto.DateCreated = DateTime.Now;
315        return dao.AddJob(jobDto);
316      });
317    }
318
319    public void UpdateJob(Job jobDto) {
320      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
321      author.AuthorizeForJob(jobDto.Id, Permission.Full);
322      trans.UseTransaction(() => {
323        dao.UpdateJob(jobDto);
324      });
325    }
326
327    public void DeleteJob(Guid jobId) {
328      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
329      author.AuthorizeForJob(jobId, Permission.Full);
330      trans.UseTransaction(() => {
331        dao.DeleteJob(jobId); // child task will be deleted by db-trigger
332      });
333    }
334    #endregion
335
336    #region JobPermission Methods
337    public void GrantPermission(Guid jobId, Guid grantedUserId, Permission permission) {
338      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
339      trans.UseTransaction(() => {
340        Job job = dao.GetJob(jobId);
341        if (job == null) throw new FaultException<FaultReason>(new FaultReason("Could not find task with id " + jobId));
342        Permission perm = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
343        if (perm != Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to grant permissions for this experiment"));
344        dao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DT.Convert.ToEntity(permission));
345      });
346    }
347
348    public void RevokePermission(Guid jobId, Guid grantedUserId) {
349      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
350      trans.UseTransaction(() => {
351        Job job = dao.GetJob(jobId);
352        if (job == null) throw new FaultException<FaultReason>(new FaultReason("Could not find task with id " + jobId));
353        DA.Permission perm = dao.GetPermissionForJob(job.Id, userManager.CurrentUserId);
354        if (perm != DA.Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to grant permissions for this experiment"));
355        dao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DA.Permission.NotAllowed);
356      });
357    }
[7910]358
[6983]359    public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
360      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
361      return trans.UseTransaction(() => {
362        DA.Permission currentUserPermission = dao.GetPermissionForJob(jobId, userManager.CurrentUserId);
363        if (currentUserPermission != DA.Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to list permissions for this experiment"));
364        return dao.GetJobPermissions(x => x.JobId == jobId);
365      });
366    }
367
368    public bool IsAllowedPrivileged() {
369      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
370      return authen.IsInRole(HiveRoles.IsAllowedPrivileged);
371    }
372    #endregion
373
374    #region Login Methods
375    public void Hello(Slave slaveInfo) {
376      authen.AuthenticateForAnyRole(HiveRoles.Slave);
[7916]377      if (userManager.CurrentUser.UserName != "hiveslave")
378        slaveInfo.OwnerUserId = userManager.CurrentUserId;
379
[6983]380      trans.UseTransaction(() => {
381        var slave = dao.GetSlave(slaveInfo.Id);
382
383        if (slave == null) {
[9369]384          var healGroup = dao.GetResources(x => x.Name == "HEAL").First();
385          if (healGroup != null) {
386            slaveInfo.ParentResourceId = healGroup.Id;
387          }
[6983]388          dao.AddSlave(slaveInfo);
389        } else {
[7916]390          slave.Name = slaveInfo.Name;
391          slave.Description = slaveInfo.Description;
392          slave.OwnerUserId = slaveInfo.OwnerUserId;
[6983]393
[7916]394          slave.Cores = slaveInfo.Cores;
395          slave.CpuArchitecture = slaveInfo.CpuArchitecture;
396          slave.CpuSpeed = slaveInfo.CpuSpeed;
397          slave.FreeCores = slaveInfo.FreeCores;
398          slave.FreeMemory = slaveInfo.FreeMemory;
399          slave.Memory = slaveInfo.Memory;
400          slave.OperatingSystem = slaveInfo.OperatingSystem;
[6983]401
[7916]402          slave.LastHeartbeat = DateTime.Now;
403          slave.SlaveState = SlaveState.Idle;
[6983]404
405          // don't update those properties: dbSlave.IsAllowedToCalculate, dbSlave.ParentResourceId
406
[7916]407          dao.UpdateSlave(slave);
[6983]408        }
409      });
410    }
411
412    public void GoodBye(Guid slaveId) {
413      authen.AuthenticateForAnyRole(HiveRoles.Slave);
414      trans.UseTransaction(() => {
415        var slave = dao.GetSlave(slaveId);
416        if (slave != null) {
417          slave.SlaveState = SlaveState.Offline;
418          dao.UpdateSlave(slave);
419        }
420      });
421    }
422    #endregion
423
424    #region Heartbeat Methods
425    public List<MessageContainer> Heartbeat(Heartbeat heartbeat) {
426      authen.AuthenticateForAnyRole(HiveRoles.Slave);
[7189]427
[9257]428      List<MessageContainer> result = new List<MessageContainer>();
429      try {
430        result = heartbeatManager.ProcessHeartbeat(heartbeat);
431      }
432      catch (Exception ex) {
433        DA.LogFactory.GetLogger(this.GetType().Namespace).Log("Exception processing Heartbeat: " + ex.ToString());
434      }
[7189]435
436      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
437        TriggerEventManager(false);
438      }
439
440      return result;
[6983]441    }
442    #endregion
443
444    #region Plugin Methods
445    public Guid AddPlugin(Plugin plugin, List<PluginData> pluginDatas) {
446      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
447      return trans.UseTransaction(() => {
448        plugin.UserId = userManager.CurrentUserId;
449        plugin.DateCreated = DateTime.Now;
450
451        var existing = dao.GetPlugins(x => x.Hash != null).Where(x => x.Hash.SequenceEqual(plugin.Hash));
452        if (existing.Count() > 0) {
453          // a plugin already exists.
454          throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(existing.Single().Id));
455        }
456
457        Guid pluginId = dao.AddPlugin(plugin);
458        foreach (PluginData pluginData in pluginDatas) {
459          pluginData.PluginId = pluginId;
460          dao.AddPluginData(pluginData);
461        }
462        return pluginId;
463      });
464    }
465
466    public Plugin GetPlugin(Guid pluginId) {
467      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
[9257]468      return trans.UseTransaction(() => {
469        return dao.GetPlugin(pluginId);
470      });
[6983]471    }
472
473    public Plugin GetPluginByHash(byte[] hash) {
474      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
[9257]475      return trans.UseTransaction(() => {
476        return dao.GetPlugins(x => x.Hash == hash).FirstOrDefault();
477      });
[6983]478    }
479
480    // note: this is a possible security problem, since a client is able to download all plugins, which may contain proprietary code (which can be disassembled)
481    //       change so that only with GetPluginByHash it is possible to download plugins
482    public IEnumerable<Plugin> GetPlugins() {
483      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
[9257]484      return trans.UseTransaction(() => {
485        return dao.GetPlugins(x => x.Hash != null);
486      });
[6983]487    }
488
489    public IEnumerable<PluginData> GetPluginDatas(List<Guid> pluginIds) {
490      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
491      var pluginDatas = new List<PluginData>();
492      return trans.UseTransaction(() => {
493        foreach (Guid guid in pluginIds) {
494          pluginDatas.AddRange(dao.GetPluginDatas(x => x.PluginId == guid).ToList());
495        }
496        return pluginDatas;
497      });
498    }
499
500    public void DeletePlugin(Guid pluginId) {
501      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
[9257]502      trans.UseTransaction(() => {
503        dao.DeletePlugin(pluginId);
504      });
[6983]505    }
506    #endregion
507
[7916]508    #region ResourcePermission Methods
[8065]509    public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
[7916]510      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
511      trans.UseTransaction(() => {
512        Resource resource = dao.GetResource(resourceId);
513        if (resource == null) throw new FaultException<FaultReason>(new FaultReason("Could not find resource with id " + resourceId));
[8051]514        if (resource.OwnerUserId != userManager.CurrentUserId && !authen.IsInRole(HiveRoles.Administrator)) throw new FaultException<FaultReason>(new FaultReason("Not allowed to grant permission for this resource"));
515        foreach (Guid id in grantedUserIds)
516          dao.AddResourcePermission(new ResourcePermission { ResourceId = resourceId, GrantedByUserId = userManager.CurrentUserId, GrantedUserId = id });
[7916]517      });
518    }
519
[8065]520    public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
[7916]521      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
522      trans.UseTransaction(() => {
523        Resource resource = dao.GetResource(resourceId);
524        if (resource == null) throw new FaultException<FaultReason>(new FaultReason("Could not find resource with id " + resourceId));
[8051]525        if (resource.OwnerUserId != userManager.CurrentUserId && !authen.IsInRole(HiveRoles.Administrator)) throw new FaultException<FaultReason>(new FaultReason("Not allowed to revoke permission for this resource"));
526        foreach (Guid id in grantedUserIds)
527          dao.DeleteResourcePermission(resourceId, id);
[7916]528      });
529    }
530
531    public IEnumerable<ResourcePermission> GetResourcePermissions(Guid resourceId) {
532      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
533      return trans.UseTransaction(() => {
534        Resource resource = dao.GetResource(resourceId);
535        if (resource == null) throw new FaultException<FaultReason>(new FaultReason("Could not find resource with id " + resourceId));
536        return dao.GetResourcePermissions(x => x.ResourceId == resourceId);
537      });
538    }
539    #endregion
540
[9123]541    #region Resource Methods
542    public IEnumerable<Resource> GetChildResources(Guid resourceId) {
[9257]543      return trans.UseTransaction(() => { return dao.GetChildResources(resourceId); });
[9123]544    }
545    #endregion
546
[6983]547    #region Slave Methods
548    public int GetNewHeartbeatInterval(Guid slaveId) {
549      authen.AuthenticateForAnyRole(HiveRoles.Slave);
[9257]550
551      Slave s = trans.UseTransaction(() => { return dao.GetSlave(slaveId); });
[6983]552      if (s != null) {
553        return s.HbInterval;
554      } else {
555        return -1;
556      }
557    }
558
559    public Guid AddSlave(Slave slave) {
560      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
561      return trans.UseTransaction(() => dao.AddSlave(slave));
562    }
563
564    public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
[8051]565      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[6983]566      return trans.UseTransaction(() => dao.AddSlaveGroup(slaveGroup));
567    }
568
569    public Slave GetSlave(Guid slaveId) {
570      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
[9257]571      return trans.UseTransaction(() => { return dao.GetSlave(slaveId); });
[6983]572    }
573
574    public SlaveGroup GetSlaveGroup(Guid slaveGroupId) {
575      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
[9257]576      return trans.UseTransaction(() => { return dao.GetSlaveGroup(slaveGroupId); });
[6983]577    }
578
579    public IEnumerable<Slave> GetSlaves() {
[7910]580      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[9257]581      return trans.UseTransaction(() => {
582        return dao.GetSlaves(x => true).Where(x => x.OwnerUserId == null
583                                           || x.OwnerUserId == userManager.CurrentUserId
584                                           || userManager.VerifyUser(userManager.CurrentUserId, GetResourcePermissions(x.Id).Select(y => y.GrantedUserId).ToList())
585                                           || authen.IsInRole(HiveRoles.Administrator)).ToArray();
586      });
[6983]587    }
588
589    public IEnumerable<SlaveGroup> GetSlaveGroups() {
[7910]590      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[9257]591      return trans.UseTransaction(() => {
592        return dao.GetSlaveGroups(x => true).Where(x => x.OwnerUserId == null
593                                                || x.OwnerUserId == userManager.CurrentUserId
594                                                || userManager.VerifyUser(userManager.CurrentUserId, GetResourcePermissions(x.Id).Select(y => y.GrantedUserId).ToList())
595                                                || authen.IsInRole(HiveRoles.Administrator)).ToArray();
596      });
[6983]597    }
598
599    public void UpdateSlave(Slave slave) {
[8051]600      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[6983]601      trans.UseTransaction(() => {
602        dao.UpdateSlave(slave);
603      });
604    }
605
606    public void UpdateSlaveGroup(SlaveGroup slaveGroup) {
[8051]607      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[6983]608      trans.UseTransaction(() => {
609        dao.UpdateSlaveGroup(slaveGroup);
610      });
611    }
612
613    public void DeleteSlave(Guid slaveId) {
[8051]614      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
615      author.AuthorizeForResourceAdministration(slaveId);
[6983]616      trans.UseTransaction(() => {
617        dao.DeleteSlave(slaveId);
618      });
619    }
620
621    public void DeleteSlaveGroup(Guid slaveGroupId) {
[8051]622      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
623      author.AuthorizeForResourceAdministration(slaveGroupId);
[6983]624      trans.UseTransaction(() => {
625        dao.DeleteSlaveGroup(slaveGroupId);
626      });
627    }
628
629    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
630      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
631      trans.UseTransaction(() => {
632        var resource = dao.GetResource(resourceId);
633        resource.ParentResourceId = slaveGroupId;
634        dao.UpdateResource(resource);
635      });
636    }
637
638    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
639      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
640      trans.UseTransaction(() => {
641        var resource = dao.GetResource(resourceId);
642        resource.ParentResourceId = null;
643        dao.UpdateResource(resource);
644      });
645    }
646
647    public Guid GetResourceId(string resourceName) {
648      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
649      return trans.UseTransaction(() => {
650        var resource = dao.GetResources(x => x.Name == resourceName).FirstOrDefault();
651        if (resource != null) {
652          return resource.Id;
653        } else {
654          return Guid.Empty;
655        }
656      });
657    }
658
659    public void TriggerEventManager(bool force) {
660      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Slave);
661      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
[7187]662      bool cleanup = false;
[6983]663      trans.UseTransaction(() => {
664        DateTime lastCleanup = dao.GetLastCleanup();
[7189]665        if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
[6983]666          dao.SetLastCleanup(DateTime.Now);
[7187]667          cleanup = true;
[6983]668        }
669      }, true);
[7187]670
671      if (cleanup) {
672        eventManager.Cleanup();
673      }
[6983]674    }
675    #endregion
676
677    #region Downtime Methods
678    public Guid AddDowntime(Downtime downtime) {
[8051]679      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
680      author.AuthorizeForResourceAdministration(downtime.ResourceId);
[6983]681      return trans.UseTransaction(() => dao.AddDowntime(downtime));
682    }
683
684    public void DeleteDowntime(Guid downtimeId) {
[8051]685      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
686      // TODO: pass resource id
687      // author.AuthorizeForResource(resourceId);
[6983]688      trans.UseTransaction(() => {
689        dao.DeleteDowntime(downtimeId);
690      });
691    }
692
693    public void UpdateDowntime(Downtime downtime) {
[8051]694      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
695      author.AuthorizeForResourceAdministration(downtime.ResourceId);
[6983]696      trans.UseTransaction(() => {
697        dao.UpdateDowntime(downtime);
698      });
699    }
700
701    public IEnumerable<Downtime> GetDowntimesForResource(Guid resourceId) {
[8051]702      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
[6983]703      return trans.UseTransaction(() => dao.GetDowntimes(x => x.ResourceId == resourceId));
704    }
705    #endregion
706
707    #region User Methods
708    public string GetUsernameByUserId(Guid userId) {
709      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
710      var user = ServiceLocator.Instance.UserManager.GetUserById(userId);
711      if (user != null)
712        return user.UserName;
713      else
714        return null;
715    }
716
717    public Guid GetUserIdByUsername(string username) {
718      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
719      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
720      return user != null ? (Guid)user.ProviderUserKey : Guid.Empty;
721    }
722    #endregion
723
[9123]724    #region UserPriority Methods
725    public IEnumerable<UserPriority> GetUserPriorities() {
726      return trans.UseTransaction(() => dao.GetUserPriorities(x => true));
727    }
728    #endregion
729
[6983]730    #region Helper Methods
731    private IEnumerable<Task> GetChildTasks(Guid? parentTaskId, bool recursive, bool includeParent) {
732      var tasks = new List<Task>(dao.GetTasks(x => parentTaskId == null ? !x.ParentTaskId.HasValue : x.ParentTaskId.Value == parentTaskId));
733
734      if (recursive) {
735        var childs = new List<Task>();
736        foreach (var task in tasks) {
737          childs.AddRange(GetChildTasks(task.Id, recursive, false));
738        }
739        tasks.AddRange(childs);
740      }
741
742      if (includeParent) tasks.Add(GetTask(parentTaskId.Value));
743      return tasks;
744    }
745    #endregion
[9123]746
747    #region Statistics Methods
748    public IEnumerable<Statistics> GetStatistics() {
[9257]749      return trans.UseTransaction(() => { return dao.GetStatistics(x => true); });
[9123]750    }
751    public IEnumerable<Statistics> GetStatisticsForTimePeriod(DateTime from, DateTime to) {
[9257]752      return trans.UseTransaction(() => { return dao.GetStatistics(x => x.Timestamp >= from && x.Timestamp <= to); });
[9123]753    }
754    #endregion
[6983]755  }
756}
Note: See TracBrowser for help on using the repository browser.