Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OaaS/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 9277

Last change on this file since 9277 was 8506, checked in by fschoepp, 12 years ago

#1888:

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