Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1888_OaaS/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 16371

Last change on this file since 16371 was 9363, checked in by spimming, 12 years ago

#1888:

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