Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Core/3.3/JobManager.cs @ 4333

Last change on this file since 4333 was 4333, checked in by cneumuel, 14 years ago

added authorizationManager which checks for permission to specific jobs (#1168)

File size: 12.2 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using System.Collections.Generic;
26using System.Linq;
27using System.Text;
28using HeuristicLab.Hive.Contracts.Interfaces;
29using HeuristicLab.Hive.Contracts.BusinessObjects;
30using HeuristicLab.Hive.Contracts;
31using HeuristicLab.Hive.Server.DataAccess;
32using HeuristicLab.Hive.Server.Core.InternalInterfaces;
33using HeuristicLab.DataAccess.Interfaces;
34using System.Data;
35using System.IO;
36using HeuristicLab.Tracing;
37using System.Transactions;
38using HeuristicLab.Hive.Server.LINQDataAccess;
39using IsolationLevel = System.Transactions.IsolationLevel;
40using HeuristicLab.Hive.Contracts.ResponseObjects;
41
42namespace HeuristicLab.Hive.Server.Core {
43  internal class JobManager : IJobManager, IInternalJobManager {
44    private ILifecycleManager lifecycleManager;
45
46    #region IJobManager Members
47
48    public JobManager() {
49      lifecycleManager = ServiceLocator.GetLifecycleManager();
50
51      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnStartup));
52      lifecycleManager.RegisterShutdown(new EventHandler(lifecycleManager_OnShutdown));
53    }
54
55    private void CheckForDeadJobs() {
56      Logger.Info("Searching for dead Jobs");
57
58      List<JobDto> allJobs = new List<JobDto>(DaoLocator.JobDao.FindAll());
59      foreach (JobDto curJob in allJobs) {
60        if (curJob.State != JobState.Calculating && curJob.State != JobState.Finished) {
61          DaoLocator.JobDao.SetJobOffline(curJob);
62        }
63      }
64    }
65
66    private void lifecycleManager_OnStartup(object sender, EventArgs e) {
67      Logger.Info("Startup Event Fired, Checking DB for consistency");
68      CheckForDeadJobs();
69      Logger.Info("Startup Event Done");
70    }
71
72    private void lifecycleManager_OnShutdown(object sender, EventArgs e) {
73      Logger.Info("Startup Event Fired, Checking DB for consistency");
74      CheckForDeadJobs();
75      Logger.Info("Startup Event Done");
76    }
77
78    /// <summary>
79    /// returns all jobs stored in the database
80    /// </summary>
81    /// <returns></returns>
82    public ResponseList<JobDto> GetAllJobs() {
83      ResponseList<JobDto> response = new ResponseList<JobDto>();
84      response.List = new List<JobDto>(DaoLocator.JobDao.FindAll());
85      return response;
86    }
87
88    public ResponseList<JobDto> GetAllJobsWithFilter(JobState jobState, int offset, int count) {
89      ResponseList<JobDto> response = new ResponseList<JobDto>();
90      response.List = new List<JobDto>(DaoLocator.JobDao.FindWithLimitations(jobState, offset, count));
91      return response;
92    }
93
94    /// <summary>
95    /// Gets the streamed job
96    /// </summary>
97    /// <param name="jobId"></param>
98    /// <returns></returns>
99    public Stream GetJobStreamById(Guid jobId) {
100      return DaoLocator.JobDao.GetSerializedJobStream(jobId);
101    }
102
103    /// <summary>
104    /// returns the job with the specified id
105    /// </summary>
106    /// <returns></returns>
107    public ResponseObject<JobDto> GetJobById(Guid jobId) {
108      ResponseObject<JobDto> response = new ResponseObject<JobDto>();
109
110      response.Obj = DaoLocator.JobDao.FindById(jobId);
111      if (response.Obj != null) {
112        response.StatusMessage = ResponseStatus.Ok;
113      } else {
114        response.StatusMessage = ResponseStatus.GetJobById_JobDoesNotExist;
115      }
116
117      return response;
118    }
119
120    /// <summary>
121    /// Returns JobDto object with Slave-Object attached
122    /// </summary>
123    public ResponseObject<JobDto> GetJobByIdWithDetails(Guid jobId) {
124      ResponseObject<JobDto> job = new ResponseObject<JobDto>();
125      job.Obj = DaoLocator.JobDao.FindById(jobId);
126      if (job.Obj != null) {
127        job.StatusMessage = ResponseStatus.Ok;
128
129        job.Obj.Slave = DaoLocator.SlaveDao.GetSlaveForJob(jobId);
130      } else {
131        job.StatusMessage = ResponseStatus.GetJobByIdWithDetails_JobDoesNotExist;
132      }
133      return job;
134    }
135
136    public ResponseObject<JobDto> AddJobWithGroupStrings(SerializedJob job, IEnumerable<string> resources) {
137      ISlaveGroupDao cgd = DaoLocator.SlaveGroupDao;
138      foreach (string res in resources) {
139        foreach (SlaveGroupDto cg in cgd.FindByName(res)) {
140          job.JobInfo.AssignedResourceIds.Add(cg.Id);
141        }
142      }
143      return AddNewJob(job);
144    }
145
146    /// <summary>
147    /// Adds a new job into the database
148    /// </summary>
149    /// <param name="job"></param>
150    /// <returns></returns>
151    public ResponseObject<JobDto> AddNewJob(SerializedJob job) {
152      ResponseObject<JobDto> response = new ResponseObject<JobDto>();
153
154      if (job != null && job.JobInfo != null) {
155        if (job.JobInfo.State != JobState.Offline) {
156          response.StatusMessage = ResponseStatus.AddNewJob_JobStateMustBeOffline;
157          return response;
158        }
159        if (job.JobInfo.Id != Guid.Empty) {
160          response.StatusMessage = ResponseStatus.AddNewJob_JobIdMustNotBeSet;
161          return response;
162        }
163        if (job.SerializedJobData == null) {
164          response.StatusMessage = ResponseStatus.AddNewJob_JobNull;
165          return response;
166        }
167
168        job.JobInfo.DateCreated = DateTime.Now;
169        job.JobInfo.UserId = ServiceLocator.GetAuthorizationManager().UserId;
170        DaoLocator.JobDao.InsertWithAttachedJob(job);
171        DaoLocator.PluginInfoDao.InsertPluginDependenciesForJob(job.JobInfo);
172
173        response.Obj = job.JobInfo;
174      } else {
175        response.StatusMessage = ResponseStatus.AddNewJob_JobNull;
176      }
177
178      return response;
179    }
180
181    /// <summary>
182    /// Removes a job from the database
183    ///
184    /// [chn] this is currently not used anywhere -> check redundancy with AbortJob
185    /// </summary>
186    /// <param name="jobId"></param>
187    /// <returns></returns>
188    //public Response RemoveJob(Guid jobId) {
189    //  Response response = new Response();
190
191    //  JobDto job = DaoLocator.JobDao.FindById(jobId);
192    //  if (job == null) {
193    //    response.StatusMessage = ResponseStatusMessage.RemoveJob_JobDoesNotExist;
194    //    return response;
195    //  }
196    //  DaoLocator.JobDao.Delete(job);
197
198    //  return response;
199    //}
200
201    ///
202    /// [chn] currently not used anywhere
203    ///
204    //public ResponseObject<JobDto> GetLastJobResultOf(Guid jobId) {
205    //  ResponseObject<JobDto> result = new ResponseObject<JobDto>();
206
207    //  result.Obj = DaoLocator.JobDao.FindById(jobId);
208    //  if (result.Obj == null) {
209    //    result.StatusMessage = ResponseStatusMessage.
210    //  }
211
212    //  return result;
213    //}
214
215    // [chn] [refactor] why does this method handle 3 different cases? wouldn't 3 methods be easier?
216    //Requested means: there MUST be a job result which gets sent back
217    // requested==true: resultat mit job
218    // requested==false:
219    public ResponseObject<SerializedJob> GetLastSerializedResult(Guid jobId, bool requested, bool snapshot) {
220      ResponseObject<SerializedJob> response = new ResponseObject<SerializedJob>();
221
222      JobDto job = DaoLocator.JobDao.FindById(jobId);
223
224      //if it's a snapshot but the result hasn't reached the server yet...
225      if (snapshot && (job.State == JobState.SnapshotRequested || job.State == JobState.SnapshotSent)) {
226        response.StatusMessage = ResponseStatus.GetLastSerializedResult_JobResultNotYetThere;
227
228        return response;
229      }
230
231      //if it's NOT a snapshot, NEITHER request NOR is it finished
232      if (!requested && !snapshot && job.State != JobState.Finished) {
233        response.StatusMessage = ResponseStatus.GetLastSerializedResult_JobResultNotYetThere;
234
235        return response;
236      }
237
238      //every other case - snapshot, job finished or it's requested
239      response.Obj = new SerializedJob();
240      response.Obj.JobInfo = job;
241
242      response.Obj.SerializedJobData = DaoLocator.JobDao.GetBinaryJobFile(jobId);
243
244      return response;
245    }
246
247    public Response RequestSnapshot(Guid jobId) {
248      Response response = new Response();
249
250      JobDto job = DaoLocator.JobDao.FindById(jobId);
251      if (job.State == JobState.SnapshotRequested || job.State == JobState.SnapshotSent) {
252        response.StatusMessage = ResponseStatus.RequestSnapshot_SnapshotAlreadyRequested;
253        return response;
254      }
255      if (job.State != JobState.Calculating) {
256        response.StatusMessage = ResponseStatus.RequestSnapshot_JobIsNotBeeingCalculated;
257        return response;
258      }
259      // job is in correct state
260      job.State = JobState.SnapshotRequested;
261      DaoLocator.JobDao.Update(job);
262
263      return response;
264    }
265
266    /// <summary>
267    /// [chn] rename to RequestAbortJob?
268    /// </summary>
269    public Response AbortJob(Guid jobId) {
270      Response response = new Response();
271
272      JobDto job = DaoLocator.JobDao.FindById(jobId);
273      if (job == null) {
274        //response.Success = false;
275        response.StatusMessage = ResponseStatus.AbortJob_JobDoesNotExist;
276        return response; // no commit needed
277      }
278      if (job.State == JobState.Aborted) {
279        //response.Success = true;
280        response.StatusMessage = ResponseStatus.AbortJob_AbortAlreadyRequested;
281        return response; // no commit needed
282      }
283      if (job.State != JobState.Calculating && job.State != JobState.SnapshotRequested && job.State != JobState.SnapshotSent) {
284        //response.Success = false;
285        response.StatusMessage = ResponseStatus.AbortJob_JobIsNotBeeingCalculated;
286        return response; // no commit needed
287      }
288      // job is in correct state
289      job.State = JobState.Aborted;
290      DaoLocator.JobDao.Update(job);
291
292      return response;
293    }
294
295    /// <summary>
296    /// Returns the current state for all jobs requested
297    /// </summary>
298    /// <param name="jobIds"></param>
299    /// <returns></returns>
300    public ResponseObject<JobResultList> GetJobResults(IEnumerable<Guid> jobIds) {
301      ResponseObject<JobResultList> response = new ResponseObject<JobResultList>();
302      JobResultList jobResultList = new JobResultList();
303      IEnumerable<JobDto> jobs = DaoLocator.JobDao.FindJobsById(jobIds);
304      foreach (JobDto job in jobs) {
305        jobResultList.Add(new JobResult() {
306          JobId = job.Id,
307          State = job.State,
308          DateCalculated = job.DateCalculated,
309          DateFinished = job.DateFinished,
310          Exception = job.Exception,
311          Percentage = job.Percentage
312        });
313      }
314      response.Obj = jobResultList;
315      return response;
316    }
317
318    public byte[] GetSerializedJobDataById(Guid jobId) {
319      return DaoLocator.JobDao.GetBinaryJobFile(jobId);
320    }
321
322    public void SetSerializedJobDataById(Guid jobId, byte[] data) {
323      DaoLocator.JobDao.SetBinaryJobFile(jobId, data);
324    }
325
326    #endregion
327
328    #region Project handling (currently unimplemented)
329
330    public ResponseList<ProjectDto> GetAllProjects() {
331      throw new NotImplementedException();
332    }
333
334    private Response CreateUpdateProject(ProjectDto project) {
335      throw new NotImplementedException();
336    }
337
338    public Response CreateProject(ProjectDto project) {
339      return CreateUpdateProject(project);
340    }
341
342    public Response ChangeProject(ProjectDto project) {
343      return CreateUpdateProject(project);
344    }
345
346    public Response DeleteProject(Guid projectId) {
347      throw new NotImplementedException();
348    }
349
350    public ResponseList<JobDto> GetJobsByProject(Guid projectId) {
351      throw new NotImplementedException();
352    }
353    #endregion
354  }
355}
Note: See TracBrowser for help on using the repository browser.