Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 9391 was 9391, checked in by pfleck, 10 years ago

#2030
Separated old DTO-Dao from new Dao. DTO-Dao should be replaced completely.
Heartbeat and UpdateTaskState uses new Dao.
DataContext is now closed on ServiceOperation end.

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