Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 9232

Last change on this file since 9232 was 9232, checked in by ascheibe, 12 years ago

#1890 use transactions for retrieving jobs to avoid returning wrong statistics

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