Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/HiveService.cs @ 6367

Last change on this file since 6367 was 6367, checked in by cneumuel, 13 years ago

#1233

  • code cleanup
  • deleted obsolete folder
File size: 18.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.ServiceModel;
5using HeuristicLab.Services.Hive.Common;
6using HeuristicLab.Services.Hive.Common.DataTransfer;
7using HeuristicLab.Services.Hive.Common.ServiceContracts;
8
9namespace HeuristicLab.Services.Hive {
10
11  /// <summary>
12  /// Implementation of the Hive service (interface <see cref="IHiveService"/>).
13  /// We need 'IgnoreExtensionDataObject' Attribute for the slave to work.
14  /// </summary>
15  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
16  public class HiveService : IHiveService {
17    private DataAccess.IHiveDao dao {
18      get { return ServiceLocator.Instance.HiveDao; }
19    }
20    private HeuristicLab.Services.Hive.DataAccess.TransactionManager trans {
21      get { return ServiceLocator.Instance.TransactionManager; }
22    }
23    private IAuthenticationManager authen {
24      get { return ServiceLocator.Instance.AuthenticationManager; }
25    }
26    private IAuthorizationManager author {
27      get { return ServiceLocator.Instance.AuthorizationManager; }
28    }
29    private ILifecycleManager lifecycleManager {
30      get { return ServiceLocator.Instance.LifecycleManager; }
31    }
32    private HeartbeatManager heartbeatManager {
33      get { return ServiceLocator.Instance.HeartbeatManager; }
34    }
35
36    #region Job Methods
37    public Guid AddJob(Job job, JobData jobData, IEnumerable<Guid> resourceIds) {
38      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
39      return trans.UseTransaction(() => {
40        job.Id = dao.AddJob(job);
41        jobData.JobId = job.Id;
42        jobData.LastUpdate = DateTime.Now;
43        foreach (Guid slaveGroupId in resourceIds) {
44          dao.AssignJobToResource(job.Id, slaveGroupId);
45        }
46        dao.AddJobData(jobData);
47        dao.UpdateJobState(job.Id, JobState.Waiting, null, author.UserId, null);
48        return jobData.JobId;
49      });
50    }
51
52    public Guid AddChildJob(Guid parentJobId, Job job, JobData jobData) {
53      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
54      return trans.UseTransaction(() => {
55        job.ParentJobId = parentJobId;
56        return AddJob(job, jobData, dao.GetAssignedResources(parentJobId).Select(x => x.Id));
57      });
58    }
59
60    public Job GetJob(Guid jobId) {
61      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
62      return dao.GetJob(jobId);
63    }
64
65    public IEnumerable<Job> GetJobs() {
66      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
67      return dao.GetJobs(x => true);
68    }
69
70    public IEnumerable<LightweightJob> GetLightweightJobs(IEnumerable<Guid> jobIds) {
71      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
72      return dao.GetJobs(x => jobIds.Contains(x.JobId)).Select(x => new LightweightJob(x)).ToArray();
73    }
74
75    public IEnumerable<LightweightJob> GetLightweightChildJobs(Guid? parentJobId, bool recursive, bool includeParent) {
76      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
77      return GetChildJobs(parentJobId, recursive, includeParent).Select(x => new LightweightJob(x)).ToArray();
78    }
79
80    public IEnumerable<LightweightJob> GetLightweightExperimentJobs(Guid experimentId) {
81      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
82      return dao.GetJobs(x => x.HiveExperimentId == experimentId).Select(x => new LightweightJob(x)).ToArray();
83    }
84
85    public JobData GetJobData(Guid jobId) {
86      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
87      return dao.GetJobData(jobId);
88    }
89
90    public void UpdateJob(Job job) {
91      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
92      trans.UseTransaction(() => {
93        dao.UpdateJob(job);
94      });
95    }
96
97    public void UpdateJobData(Job job, JobData jobData) {
98      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
99      trans.UseTransaction(() => {
100        jobData.LastUpdate = DateTime.Now;
101        dao.UpdateJob(job);
102        dao.UpdateJobData(jobData);
103      });
104    }
105
106    public void DeleteJob(Guid jobId) {
107      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
108      trans.UseTransaction(() => {
109        dao.DeleteJob(jobId);
110      });
111    }
112
113    public void DeleteChildJobs(Guid parentJobId) {
114      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
115      trans.UseTransaction(() => {
116        var jobs = GetChildJobs(parentJobId, true, false);
117        foreach (var job in jobs) {
118          dao.DeleteJob(job.Id);
119          dao.DeleteJobData(job.Id);
120        };
121      });
122    }
123
124    public Job UpdateJobState(Guid jobId, JobState jobState, Guid? slaveId, Guid? userId, string exception) {
125      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
126      return trans.UseTransaction(() => {
127        Job job = dao.UpdateJobState(jobId, jobState, slaveId, userId, exception);
128
129        if (job.Command.HasValue && job.Command.Value == Command.Pause && job.State == JobState.Paused) {
130          job.Command = null;
131        } else if (job.Command.HasValue && job.Command.Value == Command.Abort && job.State == JobState.Aborted) {
132          job.Command = null;
133        } else if (job.Command.HasValue && job.Command.Value == Command.Stop && job.State == JobState.Aborted) {
134          job.Command = null;
135        } else if (jobState == JobState.Paused && !job.Command.HasValue) {
136          // slave paused and uploaded the job (no user-command) -> set waiting.
137          job = dao.UpdateJobState(jobId, JobState.Waiting, slaveId, userId, exception);
138        }
139
140        dao.UpdateJob(job);
141        return job;
142      });
143    }
144    #endregion
145
146    #region Job Control Methods
147    public void StopJob(Guid jobId) {
148      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
149      trans.UseTransaction(() => {
150        var job = dao.GetJob(jobId);
151        if (job.State == JobState.Calculating || job.State == JobState.Transferring) {
152          job.Command = Command.Stop;
153          dao.UpdateJob(job);
154        } else {
155          if (job.State != JobState.Aborted && job.State != JobState.Finished && job.State != JobState.Failed) {
156            job = UpdateJobState(jobId, JobState.Aborted, null, null, string.Empty);
157          }
158        }
159      });
160    }
161
162    public void PauseJob(Guid jobId) {
163      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
164      trans.UseTransaction(() => {
165        var job = dao.GetJob(jobId);
166        if (job.State == JobState.Calculating || job.State == JobState.Transferring) {
167          job.Command = Command.Pause;
168          dao.UpdateJob(job);
169        } else {
170          job = UpdateJobState(jobId, JobState.Paused, null, null, string.Empty);
171        }
172      });
173    }
174
175    public void RestartJob(Guid jobId) {
176      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
177      trans.UseTransaction(() => {
178        Job job = dao.UpdateJobState(jobId, JobState.Waiting, null, author.UserId, string.Empty);
179        job.Command = null;
180        dao.UpdateJob(job);
181      });
182    }
183    #endregion
184
185    #region HiveExperiment Methods
186    public HiveExperiment GetHiveExperiment(Guid id) {
187      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
188      return dao.GetHiveExperiments(x =>
189        x.HiveExperimentId == id
190        && (x.OwnerUserId == author.UserId || x.HiveExperimentPermissions.Count(hep => hep.Permission != Permission.NotAllowed && hep.GrantedUserId == author.UserId) > 0)
191      ).FirstOrDefault();
192    }
193
194    public IEnumerable<HiveExperiment> GetHiveExperiments() {
195      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
196      return dao.GetHiveExperiments(x => x.OwnerUserId == author.UserId || x.HiveExperimentPermissions.Count(hep => hep.Permission != Permission.NotAllowed && hep.GrantedUserId == author.UserId) > 0);
197    }
198
199    public IEnumerable<HiveExperiment> GetAllHiveExperiments() {
200      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
201      return dao.GetHiveExperiments(x => true);
202    }
203
204    public Guid AddHiveExperiment(HiveExperiment hiveExperimentDto) {
205      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
206      return trans.UseTransaction(() => {
207        hiveExperimentDto.OwnerUserId = author.UserId;
208        hiveExperimentDto.DateCreated = DateTime.Now;
209        return dao.AddHiveExperiment(hiveExperimentDto);
210      });
211    }
212
213    public void UpdateHiveExperiment(HiveExperiment hiveExperimentDto) {
214      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
215      trans.UseTransaction(() => {
216        dao.UpdateHiveExperiment(hiveExperimentDto);
217      });
218    }
219
220    public void DeleteHiveExperiment(Guid hiveExperimentId) {
221      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
222      trans.UseTransaction(() => {
223        HiveExperiment he = dao.GetHiveExperiment(hiveExperimentId);
224        dao.DeleteHiveExperiment(hiveExperimentId); // child jobs will be deleted by db-trigger
225      });
226    }
227    #endregion
228
229    #region Login Methods
230    public void Hello(Slave slaveInfo) {
231      authen.AuthenticateForAnyRole(HiveRoles.Slave);
232      trans.UseTransaction(() => {
233        var slave = dao.GetSlave(slaveInfo.Id);
234
235        if (slave == null) {
236          dao.AddSlave(slaveInfo);
237        } else {
238          var dbSlave = dao.GetSlave(slaveInfo.Id);
239
240          dbSlave.Name = slaveInfo.Name;
241          dbSlave.Description = slaveInfo.Description;
242
243          dbSlave.Cores = slaveInfo.Cores;
244          dbSlave.CpuArchitecture = slaveInfo.CpuArchitecture;
245          dbSlave.CpuSpeed = slaveInfo.CpuSpeed;
246          dbSlave.FreeCores = slaveInfo.FreeCores;
247          dbSlave.FreeMemory = slaveInfo.FreeMemory;
248          dbSlave.Memory = slaveInfo.Memory;
249          dbSlave.OperatingSystem = slaveInfo.OperatingSystem;
250
251          dbSlave.LastHeartbeat = DateTime.Now;
252          dbSlave.SlaveState = SlaveState.Idle;
253
254          // don't update those properties: dbSlave.IsAllowedToCalculate, dbSlave.ParentResourceId
255
256          dao.UpdateSlave(dbSlave);
257        }
258      });
259    }
260
261    public void GoodBye(Guid slaveId) {
262      authen.AuthenticateForAnyRole(HiveRoles.Slave);
263      trans.UseTransaction(() => {
264        var slave = dao.GetSlave(slaveId);
265        if (slave != null) {
266          slave.SlaveState = SlaveState.Offline;
267          dao.UpdateSlave(slave);
268        }
269      });
270    }
271    #endregion
272
273    #region Heartbeat Methods
274    public List<MessageContainer> Heartbeat(Heartbeat heartbeat) {
275      authen.AuthenticateForAnyRole(HiveRoles.Slave);
276      TriggerLifecycle(false);
277      return trans.UseTransaction(() => heartbeatManager.ProcessHeartbeat(heartbeat));
278    }
279    #endregion
280
281    #region Plugin Methods
282    public Guid AddPlugin(Plugin plugin, List<PluginData> pluginDatas) {
283      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
284      return trans.UseTransaction(() => {
285        plugin.UserId = author.UserId;
286        plugin.DateCreated = DateTime.Now;
287        if (!plugin.IsLocal) {
288          var existing = dao.GetPlugins(x => x.Name == plugin.Name && x.Version == plugin.Version.ToString() && !x.IsLocal);
289          if (existing.Count() > 0) {
290            // a plugin with the same name and version already exists.
291            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(existing.Single().Id));
292          }
293        }
294        Guid pluginId = dao.AddPlugin(plugin);
295        foreach (PluginData pluginData in pluginDatas) {
296          pluginData.PluginId = pluginId;
297          dao.AddPluginData(pluginData);
298        }
299        return pluginId;
300      });
301    }
302
303    public Plugin GetPlugin(Guid pluginId) {
304      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
305      return dao.GetPlugin(pluginId);
306    }
307
308    public IEnumerable<Plugin> GetPlugins() {
309      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
310      return dao.GetPlugins(x => x.IsLocal == false);
311    }
312
313    public IEnumerable<PluginData> GetPluginDatas(List<Guid> pluginIds) {
314      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
315      List<PluginData> pluginDatas = new List<PluginData>();
316
317      return trans.UseTransaction(() => {
318        foreach (Guid guid in pluginIds) {
319          List<PluginData> pluginData = dao.GetPluginDatas(x => x.PluginId == guid).ToList();
320          if (pluginData != null) {
321            pluginDatas.AddRange(pluginData);
322          } else {
323            //ignore ?
324          }
325        }
326        return pluginDatas;
327      });
328    }
329
330    #endregion
331
332    #region Slave Methods
333    public Guid AddSlave(Slave slave) {
334      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
335      return trans.UseTransaction(() => dao.AddSlave(slave));
336    }
337
338    public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
339      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
340      return trans.UseTransaction(() => dao.AddSlaveGroup(slaveGroup));
341    }
342
343    public Slave GetSlave(Guid slaveId) {
344      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
345      return dao.GetSlave(slaveId);
346    }
347
348    public SlaveGroup GetSlaveGroup(Guid slaveGroupId) {
349      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
350      return dao.GetSlaveGroup(slaveGroupId);
351    }
352
353    public IEnumerable<Slave> GetSlaves() {
354      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
355      return dao.GetSlaves(x => true);
356    }
357
358    public IEnumerable<SlaveGroup> GetSlaveGroups() {
359      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
360      return dao.GetSlaveGroups(x => true);
361    }
362
363    public void UpdateSlave(Slave slave) {
364      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
365      trans.UseTransaction(() => {
366        dao.UpdateSlave(slave);
367      });
368    }
369
370    public void UpdateSlaveGroup(SlaveGroup slaveGroup) {
371      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
372      trans.UseTransaction(() => {
373        dao.UpdateSlaveGroup(slaveGroup);
374      });
375    }
376
377    public void DeleteSlave(Guid slaveId) {
378      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
379      trans.UseTransaction(() => {
380        dao.DeleteSlave(slaveId);
381      });
382    }
383
384    public void DeleteSlaveGroup(Guid slaveGroupId) {
385      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
386      trans.UseTransaction(() => {
387        dao.DeleteSlaveGroup(slaveGroupId);
388      });
389    }
390
391    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
392      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
393      trans.UseTransaction(() => {
394        var resource = dao.GetResource(resourceId);
395        resource.ParentResourceId = slaveGroupId;
396        dao.UpdateResource(resource);
397      });
398    }
399
400    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
401      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
402      trans.UseTransaction(() => {
403        var resource = dao.GetResource(resourceId);
404        resource.ParentResourceId = null;
405        dao.UpdateResource(resource);
406      });
407    }
408
409    public Guid GetResourceId(string resourceName) {
410      authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
411      return trans.UseTransaction(() => {
412        var resource = dao.GetResources(x => x.Name == resourceName).FirstOrDefault();
413        if (resource != null) {
414          return resource.Id;
415        } else {
416          return Guid.Empty;
417        }
418      });
419    }
420
421    public void TriggerLifecycle(bool force) {
422      // use a serializable transaction here to ensure not two threads execute this simultaniously (locking would not work since IIS may use multiple AppDomains)
423      trans.UseTransaction(() => {
424        DateTime lastCleanup = dao.GetLastCleanup();
425        if (force || DateTime.Now - lastCleanup > TimeSpan.FromSeconds(59)) {
426          dao.SetLastCleanup(DateTime.Now);
427          lifecycleManager.Cleanup();
428        }
429      }, true);
430    }
431    #endregion
432
433    #region Helper Methods
434    private IEnumerable<Job> GetChildJobs(Guid? parentJobId, bool recursive, bool includeParent) {
435      var jobs = new List<Job>(dao.GetJobs(x => parentJobId == null ? !x.ParentJobId.HasValue : x.ParentJobId.Value == parentJobId));
436
437      if (recursive) {
438        var childs = new List<Job>();
439        foreach (var job in jobs) {
440          childs.AddRange(GetChildJobs(job.Id, recursive, false));
441        }
442        jobs.AddRange(childs);
443      }
444
445      if (includeParent) jobs.Add(GetJob(parentJobId.Value));
446
447      return jobs;
448    }
449
450    #endregion
451
452    #region Appointment Methods
453    public Guid AddAppointment(Appointment appointment) {
454      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
455      return trans.UseTransaction(() => dao.AddAppointment(appointment));
456    }
457
458    public void DeleteAppointment(Guid appointmentId) {
459      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
460      trans.UseTransaction(() => {
461        dao.DeleteAppointment(appointmentId);
462      });
463    }
464
465    public void UpdateAppointment(Appointment appointment) {
466      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
467      trans.UseTransaction(() => {
468        dao.UpdateAppointment(appointment);
469      });
470    }
471
472    public IEnumerable<Appointment> GetScheduleForResource(Guid resourceId) {
473      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
474      return trans.UseTransaction(() => dao.GetAppointments(x => x.ResourceId == resourceId));
475    }
476
477    public IEnumerable<Job> GetJobsByResourceId(Guid resourceId) {
478      authen.AuthenticateForAnyRole(HiveRoles.Administrator);
479      return trans.UseTransaction(() => dao.GetJobsByResourceId(resourceId));
480    }
481    #endregion
482  }
483}
Note: See TracBrowser for help on using the repository browser.