Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 12468

Last change on this file since 12468 was 12468, checked in by dglaser, 9 years ago

#2388:
HeuristicLab.Services.Hive.DataAccess-3.3:

  • Added PersistenceManager with corresponding daos
  • Updated SQL Scripts
  • Fixed folder structure (interfaces, manager)
  • Removed duplicated IHiveDao and HiveDao (the HiveDao/OptimizedHiveDao that is actually used is located in HeuristicLab.Services.Hive)

HeuristicLab.Service.Hive-3.3:

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