source: branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs @ 9395

Last change on this file since 9395 was 9395, checked in by fschoepp, 9 years ago

#1888:

  • Added visual extensions (dynamic JavaScript) which will be used to render additional result parameters specific to scenarios (e. g. create a graphical representation of a TSP).
  • Added relationship between jobs and experiments (otherwise, it's not possible to get the job's experiment).
  • Updated Admin page to allow removal/addition of visual extensions.
  • Added back-end logic to store/retrieve/delete visual extensions.
  • Added visual extension functionality to the JavaScript views/controllers (job.*.js).
  • Added tsp.js which is a visual extension for the "Genetic Algorithm - TSP" scenario. It adds a graphical representation of the TSP (just like the C# version does) to the results.
File size: 24.8 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Services.Optimization.ControllerService.Interfaces;
6using HeuristicLab.Optimization;
7using HeuristicLab.Algorithms.GeneticAlgorithm;
8using HeuristicLab.Problems.TravelingSalesman;
9using HeuristicLab;
10using System.Reflection;
11using HeuristicLab.Services.Optimization.ControllerService.Model;
12using HeuristicLab.Core;
13using System.Collections;
14using HeuristicLab.Clients.Hive;
15using System.Threading;
16using HeuristicLab.Data;
17using System.IO;
18using Microsoft.WindowsAzure;
19using Microsoft.WindowsAzure.StorageClient;
20using HeuristicLab.Services.Optimization.ControllerService.Azure;
21using System.Data;
22using HeuristicLab.Services.Optimization.ControllerService.General;
23using HeuristicLab.Services.Optimization.ControllerService.Parameters.HL;
24
25namespace HeuristicLab.Services.Optimization.ControllerService {
26  public class ScenarioEntity : TableServiceEntity {   
27    public ScenarioEntity() {
28    }
29   
30    public ScenarioEntity(string scenarioName, string scenario, string mapper) {
31      PartitionKey = "ScenarioPartition";
32      RowKey = scenarioName;
33      Scenario = scenario;
34      Mapper = mapper;
35    }   
36
37    public string Scenario { get; set; }
38
39    public string Mapper { get; set; }
40  }
41
42  public class HiveScenarioManager : IScenarioManager {
43    private static HLParameterMapper parameterMapper = new HLParameterMapper();
44    private static IScenarioMapper tspMapper;
45    private static object lockable;
46    private Dictionary<string, IScenarioMapper> mappers = new Dictionary<string, IScenarioMapper>();
47    private IDataAccessLayer dal = DataAccessLayerProvider.GetLayer();
48
49    public static readonly string SCENARIO_TABLE = "Scenario";
50
51    static HiveScenarioManager() {
52      lockable = new object();
53    }
54
55    public string DispatchScenario(Model.User user, Model.OptimizationScenario scenario, JobExecutionDetails details) {
56      // Experiment experiment = new Experiment();
57      // var problem = new TravelingSalesmanProblem();
58      // var algo = new GeneticAlgorithm();
59      // algo.Problem = problem;     
60     
61      IScenarioMapper mapper = GetMapper(scenario.Id);
62      IAlgorithm algo;
63      mapper.MapScenario(scenario, out algo);
64      /*if (details.Repititions > 1) {
65        BatchRun br = new BatchRun();
66        //br.Name = details.JobTitle;
67        br.Optimizer = algo;       
68        br.Repetitions = details.Repititions;
69        return SendExperimentToHive(user, br, details);
70      }
71      else {       
72       
73      }*/
74      return SendExperimentToHive(user, algo, details);
75    }
76
77    private sealed class StackEntry {
78      public HeuristicLab.Optimization.Experiment Parent { get; set; }
79      public IList<Model.Algorithm> Children { get; set; }
80    }
81
82    public bool DispatchExperiment(User user, Model.Experiment exp, JobExecutionDetails details) {
83      // TODO: Determine how to build a tree of IAlgorithm
84      // For now the experiment will be flatened for execution
85      HeuristicLab.Optimization.Experiment hiveExperiment = new HeuristicLab.Optimization.Experiment(exp.Name);
86      var stack = new Stack<StackEntry>();
87      var children = new List<Model.Algorithm>();
88      foreach (var child in exp.Algorithm) {
89        children.Add(child);       
90      }
91      stack.Push(new StackEntry() { Parent = hiveExperiment, Children = children });
92
93      while (stack.Count > 0) {
94        var entry = stack.Pop();
95        // handle current entry
96
97        // TODO: Store scenario name in entry.Child.Mapper when saving
98        foreach (var child in entry.Children) {
99          // This is a template experiment;
100          if (child.IsExperiment) {
101            var parent = new HeuristicLab.Optimization.Experiment();
102            entry.Parent.Optimizers.Add(parent);
103            stack.Push(new StackEntry() { Parent = parent, Children = child.ChildAlgorithms });         
104          }
105          // This entity is mapable
106          else {           
107            IScenarioMapper mapper = GetMapper(child.Id);
108            var optScen = new OptimizationScenario() { Id = child.Id };
109            optScen.Algorithm.Add(child);
110            IAlgorithm algo;
111            mapper.MapScenario(optScen, out algo);
112            algo.Name = child.Id;
113            entry.Parent.Optimizers.Add(algo);
114          } 
115        }
116      }
117      details.JobTitle = exp.Name;
118      var jobId = SendExperimentToHive(user, hiveExperiment, details);
119
120      // add relationship to azure tablestorage     
121      if (jobId != null) {
122        dal.JobDao.Add(user.Username, exp, jobId);
123      }
124      return jobId != null;
125    }
126
127    static public string AssemblyDirectory {
128      get {
129        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
130        UriBuilder uri = new UriBuilder(codeBase);
131        string path = Uri.UnescapeDataString(uri.Path);
132        return Path.GetDirectoryName(path);
133      }
134    }
135
136    public static IScenarioMapper CompileMapper(string scenarioMapper) {
137       // http://stackoverflow.com/questions/3188882/compile-and-run-dynamic-code-without-generating-exe
138      using (var csCodeProvider = new Microsoft.CSharp.CSharpCodeProvider()) {
139        var cp = new System.CodeDom.Compiler.CompilerParameters() {
140          GenerateInMemory = true
141        };
142
143        var referencedPaths = Directory.GetFiles(AssemblyDirectory, "*.dll");
144        foreach (var loadedAssembly in referencedPaths) {
145          cp.ReferencedAssemblies.Add(loadedAssembly);
146        }
147        cp.ReferencedAssemblies.Add("System.dll");
148        cp.ReferencedAssemblies.Add("System.Core.dll");
149        cp.ReferencedAssemblies.Add("System.Data.dll");
150        cp.ReferencedAssemblies.Add("System.Xml.dll");
151        cp.ReferencedAssemblies.Add("System.Xml.Linq.dll");
152
153        var res = csCodeProvider.CompileAssemblyFromSource(
154          cp,
155          scenarioMapper
156        );
157
158        foreach (var error in res.Errors) {
159          Console.WriteLine(error);
160        }
161       
162        var firstMapper = res.CompiledAssembly.GetTypes().Where(p => typeof(IScenarioMapper).IsAssignableFrom(p)).FirstOrDefault();       
163        return Activator.CreateInstance(firstMapper) as IScenarioMapper;
164      }
165    }
166
167    private IScenarioMapper GetMapper(string scenarioId) {
168      var id = scenarioId;
169      IScenarioMapper mapper = null;     
170      if (!mappers.TryGetValue(id, out mapper)) {
171        lock (lockable) {
172          if (mappers.ContainsKey(id))
173            return mappers[id];
174         
175          var mapperString = GetMapperFromBlobStore(id);
176          if (mapperString == null) return null;
177          mapper = CompileMapper(mapperString);
178
179          mappers[id] = mapper;
180          return mapper;
181        } // lock       
182       } // if
183      return mapper;
184     } 
185
186    private void MapExperiment(Model.OptimizationScenario scenario, out IAlgorithm algorithm) {     
187      IScenarioMapper mapper = GetMapper(scenario.Id);
188      mapper.MapScenario(scenario, out algorithm);     
189    }
190
191    private HiveServiceLocator ConfigureHive(Model.User user) {
192      var serviceLocator = new HiveServiceLocator();
193      serviceLocator.Username = user.Username;
194      serviceLocator.Password = user.Password;
195      serviceLocator.EndpointConfigurationName = Configuration.HiveEndpointName;
196      return serviceLocator;
197    }
198
199    private string SendExperimentToHive(Model.User user, IOptimizer exp, JobExecutionDetails details) {     
200      var job = new RefreshableJob();
201      job.IsAllowedPrivileged = true;     
202      job.Job.Name = details.JobTitle;
203      job.Job.ResourceNames = details.Group;     
204      job.RefreshAutomatically = false;
205     
206      if (details.Repititions > 1) {
207        BatchRun br = new BatchRun();
208        br.Optimizer = exp;
209        br.Repetitions = details.Repititions;
210        exp = br;
211      }
212
213      if (exp.ExecutionState != ExecutionState.Prepared) {
214        exp.Prepare();
215      }     
216      job.HiveTasks.Add(new OptimizerHiveTask(exp));
217      var service = ConfigureHive(user);
218     
219      // TODO: Fix HiveClient class to be not dependent on singleton HiveServiceLocator!!!
220      HiveServiceLocator.Instance.Username = user.Username;
221      HiveServiceLocator.Instance.Password = user.Password;
222      HiveServiceLocator.Instance.EndpointConfigurationName = Configuration.HiveEndpointName;
223      HiveClient.Store(job, new CancellationToken());
224     
225      job.StopResultPolling();
226      return job.Id != null ? job.Id.ToString() : null;
227    }
228
229
230    public IList<Model.Job> GetJobs(User user) {
231      var serviceLocator = ConfigureHive(user);
232      var jobsLoaded = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.Job>>(s => s.GetJobs());
233      IList<Model.Job> jobs = new List<Model.Job>();
234
235      foreach (var job in jobsLoaded) {
236        jobs.Add(ConvertJob(user, job));
237      }     
238      return jobs;
239    }
240
241    private Model.Job ConvertJob(User user, HeuristicLab.Clients.Hive.Job job)
242    {
243      var waitingJobs = job.JobCount - job.CalculatingCount - job.FinishedCount;
244      Model.JobState? state = null;
245      if (job.CalculatingCount > 0)
246        state = JobState.Calculating;
247      else if (job.JobCount > 0 && job.JobCount == job.FinishedCount)
248        state = JobState.Finished;
249      else
250        state = JobState.Waiting;
251
252      return new Model.Job() { Id = job.Id.ToString(), Name = job.Name, Resource = job.ResourceNames, State = state.Value, DateCreated = job.DateCreated };
253    }
254
255
256    public Model.Job GetJob(User user, string id) {
257      var serviceLocator = ConfigureHive(user);
258      var guid = Guid.Parse(id);
259      return ConvertJob(user, serviceLocator.CallHiveService<HeuristicLab.Clients.Hive.Job>(s => s.GetJob(guid)));
260    }
261
262
263    public bool DeleteJob(User user, string id) {
264      var serviceLocator = ConfigureHive(user);
265      var guid = Guid.Parse(id);     
266      serviceLocator.CallHiveService(s => s.DeleteJob(guid));
267      return true;
268    }
269
270    public IList<Model.Run> GetJobResults(User user, string id) {
271      var serviceLocator = ConfigureHive(user);
272      var guid = Guid.Parse(id);
273      var jobTasks = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightJobTasks(guid));
274
275      IList<Guid> taskIds = new List<Guid>();
276      foreach (var task in jobTasks) {
277        taskIds.Add(task.Id);
278      }
279
280      // TODO: Fix problems with the HiveServiceLocater singleton!!!
281      HiveServiceLocator.Instance.Username = user.Username;
282      HiveServiceLocator.Instance.Password = user.Password;
283      HiveServiceLocator.Instance.EndpointConfigurationName = Configuration.HiveEndpointName;
284      TaskDownloader downloader = new TaskDownloader(taskIds);
285      downloader.StartAsync();
286      while (!downloader.IsFinished) {       
287        Thread.Sleep(500);
288
289        if (downloader.IsFaulted) {
290          throw downloader.Exception;
291        }
292      }
293      //var experiment = dal.JobDao.FindByJobId(user.Username, id);
294
295      IDictionary<Guid, HiveTask> hiveTasks = downloader.Results;
296      IList<Model.Run> runs = new List<Model.Run>();
297      foreach (var keyTask in hiveTasks.Keys) {
298        var oht = hiveTasks[keyTask] as OptimizerHiveTask;
299        if (oht != null) {
300          foreach (var run in oht.ItemTask.Item.Runs) {
301            Model.Run taskRun = new Model.Run();
302            taskRun.Id = taskRun.Name = run.Name;
303            // We try to extract the original algorithm name here
304            var index = taskRun.Name.LastIndexOf(" Run ");
305            var algorithName = taskRun.Name.Substring(0, index);
306            taskRun.AlgorithmName = algorithName;
307            if (taskRun.AlgorithmName == null)
308              taskRun.AlgorithmName = run.Algorithm != null ? run.Algorithm.Name : run.Name;
309           
310            IList<Parameter> resultValues = new List<Model.Parameter>();
311            foreach (var key in run.Results.Keys) {
312              var value = run.Results[key];             
313              Parameter result = MapHiveDataType(key, value);
314              resultValues.Add(result);             
315            }
316            taskRun.Results = resultValues;
317            IList<Parameter> inputParameters = new List<Model.Parameter>();
318            foreach (var key in run.Parameters.Keys) {
319              var value = run.Parameters[key];
320              Parameter param = MapHiveDataType(key, value);
321              inputParameters.Add(param);
322            }
323            // crawl the copied experiment of the job
324            //taskRun.Experiment = dal.JobDao.FindByJobId(id);
325            taskRun.InputParameters = inputParameters;
326            runs.Add(taskRun);
327          }
328        }
329      }
330      return runs;
331    }
332
333    //TODO: We might need images / +++
334   
335    private Parameter MapHiveDataType(string name, IItem item) {
336
337      if (parameterMapper.IsHandlerAvailable(item)) {
338        return parameterMapper.Map(name, item);
339      }
340
341      var result = new Parameter();
342      result.Type = ParameterType.String;
343      //TODO: How shall we handle dll specific datatypes?     
344      //if (item is PathTSPTour) {
345      //  var tour = item as PathTSPTour;           
346      //}
347      //else
348      if (item is IStringConvertibleValue) {
349        var value = (item as IStringConvertibleValue).GetValue();
350        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = value };
351      }
352      else if (item is IStringConvertibleValueTuple) {
353        var value1 = (item as IStringConvertibleValueTuple).Item1.GetValue();
354        var value2 = (item as IStringConvertibleValueTuple).Item2.GetValue();
355        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = "{" + value1 + ", " + value2 + "}" };
356      }           
357      else if (item is DoubleArray) {
358        var array = item as DoubleArray;
359        double[] arrayValue = new double[array.Length];
360        for (int i = 0; i < arrayValue.Length; ++i) {
361          arrayValue[i] = array[i];
362        }
363        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.DecimalVector() { Name = name, Value = arrayValue };
364      }
365      else if (item is DoubleMatrix) {
366        var matrix = item as DoubleMatrix;
367        /*double[][] matrixValue = new double[matrix.Rows][];
368        for (int i = 0; i < matrixValue.Length; ++i) {
369          matrixValue[i] = new double[matrix.Columns];
370          for (int j = 0; j < matrixValue[i].Length; ++j) {
371            matrixValue[i][j] = matrix[i, j];
372          }
373        } */
374        double[][] matrixValue = new double[matrix.Columns][];
375        for (int i = 0; i < matrix.Columns; ++i) {
376          matrixValue[i] = new double[matrix.Rows];
377          for (int j = 0; j < matrix.Rows; ++j) {
378            matrixValue[i][j] = matrix[j, i];
379          }
380        }
381        matrixValue = transpose(matrixValue);
382        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.DecimalMatrix() { Name = name, Value = matrixValue, RowNames = (matrix.ColumnNames.Count() > 0 ? matrix.ColumnNames.ToArray() : null) };
383      }
384      else if (item is IStringConvertibleArray) {
385        StringBuilder sb = new StringBuilder();
386        var array = item as IStringConvertibleArray;
387        if (array.Length == 0) {
388          sb.Append("[ ]");
389        }
390        else {
391          sb.Append("[");
392          for (int i = 0; i < array.Length - 1; i++) {
393            sb.Append(array.GetValue(i)).Append(", ");
394          }
395          sb.Append(array.GetValue(array.Length - 1));
396          sb.Append(" ]");
397        }
398        var value = sb.ToString();
399        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = value };
400      }
401      else if (item is HeuristicLab.Analysis.DataTable) {
402        var table = item as HeuristicLab.Analysis.DataTable;
403        string[] names = new string[table.Rows.Count];
404        double[][] results = new double[table.Rows.Count][];
405        for (int i = 0; i < table.Rows.Count; i++ ) {
406          var columns = table.Rows.ToList()[i];
407          names[i] = columns.Name;
408          results[i] = new double[columns.Values.Count];         
409          for (int j=0; j < columns.Values.Count; j++) {
410            results[i][j] = columns.Values[j];
411          }
412        }
413        results = transpose(results);
414        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.DecimalMatrix() { Name = name, Value = results, RowNames = names };
415      }
416      else if (item is IStringConvertibleMatrix) {
417        StringBuilder sb = new StringBuilder();
418        var matrix = item as IStringConvertibleMatrix;
419
420        if (matrix.Rows == 0 || matrix.Columns == 0) {
421          sb.Append("[ ]");
422        }
423        else {
424
425          sb.Append("[ ");
426          for (int r = 0; r < matrix.Rows; r++) {
427            sb.Append("( ");
428            for (int c = 0; c < matrix.Columns - 1; c++) {
429              matrix.GetValue(r, c);
430              sb.Append(matrix.GetValue(r, c)).Append(", ");
431            }
432            sb.Append(matrix.GetValue(r, matrix.Columns - 1)).Append(r < matrix.Rows - 1 ? " ), " : " )");
433          }
434          sb.Append(" ]");
435        }
436        var value = sb.ToString();
437        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = value };
438      }
439      else {
440        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = item.ItemName != null ? item.ItemName + " (Cannot be displayed properly as string)" : "Cannot be displayed properly as string" };
441      }
442      // TODO: Add workaround for TSP
443      return result;
444    }
445
446    public bool AddScenario(User user, string scenarioName, string scenarioXml, string scenarioMapper) {
447      // create scenario mapper
448      var mapper = CompileMapper(scenarioMapper);
449      if (mapper == null)
450        return false;
451     
452      // insert into table & blob store
453      var scenDao = dal.ScenarioDao;
454      var blobDao = dal.BlobDao;
455     
456      Guid scenarioXmlGuid = Guid.NewGuid();
457      Guid scenarioMapperGuid = Guid.NewGuid();
458      string scenarioXmlId = scenarioName + "_" + scenarioXmlGuid.ToString();
459      string scenarioMapperId = scenarioName + "_" + scenarioMapperGuid.ToString();
460      if (!blobDao.Add(new StringEntry() { Key = scenarioXmlId, Text = scenarioXml }))
461        return false;
462      if (!blobDao.Add(new StringEntry() { Key = scenarioMapperId, Text = scenarioMapper }))
463        return false;
464      if (!scenDao.Add(new ScenarioEntity(scenarioName, scenarioXmlId, scenarioMapperId)))
465        return false;
466
467      // everything stored in the DB -> add mapper to dictionary
468      if (!mappers.ContainsKey(scenarioName)) {
469        lock (lockable) {
470          if (!mappers.ContainsKey(scenarioName))
471            mappers[scenarioName] = mapper;
472        }
473      }
474      return true;
475    }
476
477    private double[][] transpose(double[][] arr) {
478      var width = arr.Length;
479      var height = arr[0].Length;
480
481      var res = new double[height][];
482      for (var i = 0; i < height; i++)
483        res[i] = new double[width];
484
485      for (var i = 0; i < width; i++) {
486        for (var j = 0; j < height; j++) {
487          res[j][i] = arr[i][j];
488        }
489      }
490      return res;
491    }
492
493    private string GetMapperFromBlobStore(string scenarioName) {
494      var scenarioDao = dal.ScenarioDao;
495      var blobDao = dal.BlobDao;
496      var entity = scenarioDao.FindByName(scenarioName);
497      if (entity == null)
498        return null;
499
500      var mapper = blobDao.FindByKey(entity.Mapper);
501      if (mapper == null)
502        return null;
503      return mapper.Text;
504    }
505
506    public bool DeleteScenario(User user, string scenarioName) {
507      // delete from table & blob store
508      var scenarioDao = dal.ScenarioDao;
509      var blobDao = dal.BlobDao;
510
511      var entity = scenarioDao.FindByName(scenarioName);
512      if (entity == null)
513        return false;
514
515      blobDao.DeleteByKey(entity.Mapper);
516      blobDao.DeleteByKey(entity.Scenario);
517      scenarioDao.DeleteByName(scenarioName);           
518      return true;
519    }
520
521    public string SaveExperiment(User user, Model.Experiment experiment) {
522      if (experiment.Id != null) {
523        dal.ExperimentDao.Update(user.Username, experiment);
524      }
525      else {
526        dal.ExperimentDao.Add(user.Username, experiment);
527      }
528      return experiment.Id;
529    }
530
531    public IEnumerable<string> GetExperimentNames(User user) {
532      return (from exp in dal.ExperimentDao.GetExperiments(user.Username)
533              select exp.Name);
534    }
535
536
537    public bool DeleteExperiment(User user, string experiment) {
538      return dal.ExperimentDao.Delete(user.Username, experiment);
539    }
540
541
542    public Model.Task GetTaskData(User u, string jobId, string taskId) {
543      ConfigureHive(u);
544      HiveServiceLocator.Instance.Username = u.Username;
545      HiveServiceLocator.Instance.Password = u.Password;
546      HiveServiceLocator.Instance.EndpointConfigurationName = Configuration.HiveEndpointName;
547      TaskDownloader downloader = new TaskDownloader(new List<Guid>(){Guid.Parse(taskId)});
548      downloader.StartAsync();
549      while (!downloader.IsFinished) {
550        Thread.Sleep(250);
551        if (downloader.IsFaulted) {
552          throw downloader.Exception;
553        }
554      }
555     
556      IDictionary<Guid, HiveTask> hiveTasks = downloader.Results;
557      var task = hiveTasks[Guid.Parse(taskId)];
558      if (task == null)
559        return null;
560     
561      return new Model.Task() {
562        State = new Model.TaskState() {
563          DateCreated = task.Task.DateCreated.ToString(),
564          DateFinished = task.Task.DateFinished.ToString(),
565          ExecutionTime = task.Task.ExecutionTime.ToString(),
566          State = task.Task.State.ToString()
567        },
568        General = new Model.General() {
569          Id = task.Task.Id.ToString(),
570          LastChanged = task.Task.Modified.ToString(),
571          Name = task.ItemTask.Name
572        }
573      };
574    }
575
576    public Model.Job GetTasks(User u, string jobId) {
577      var serviceLocator = ConfigureHive(u);
578      var jobTasks = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightJobTasks(Guid.Parse(jobId)));
579     
580      var job = new Model.Job();
581      job.Id = jobId;
582      var tasks = new Dictionary<Guid, Model.Task>();
583      // push all elements to dictionary
584      foreach (var task in jobTasks) {
585        // TODO: Crawl children + parent and create hierarchy!
586        var children = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightChildTasks(Guid.Parse(jobId), true, true));
587        foreach (var child in children) {
588          tasks[child.Id] = new Model.Task() {
589            State = new Model.TaskState() {
590              DateCreated = child.DateCreated.ToString(),
591              DateFinished = child.DateFinished.ToString(),
592              ExecutionTime = child.ExecutionTime.ToString(),
593              State = child.State.ToString()
594            },
595            General = new Model.General() {
596              Id = child.Id.ToString(),
597              LastChanged = child.Modified.ToString(),
598              Name = child.ItemName
599            }
600          };
601        }
602      }
603
604      // traverse all tasks again and create tree of tasks
605      foreach (var task in jobTasks) {
606        if (task.ParentTaskId.HasValue)
607          tasks[task.Id].Children.Add(tasks[task.ParentTaskId.Value]);
608        else // its a root task
609          job.Tasks.Add(tasks[task.Id]);
610      }
611
612      return job;
613    }
614
615
616    public Model.Experiment GetExperimentByName(User user, string scenario) {
617      return dal.ExperimentDao.GetExperimentByName(user.Username, scenario);
618    }
619
620    public IEnumerable<Model.Experiment> GetExperiments(User user, bool namesOnly=false) {
621      return dal.ExperimentDao.GetExperiments(user.Username, namesOnly);
622    }
623
624    public Model.Experiment GetExperimentById(User user, string nodeId) {
625      return dal.ExperimentDao.GetExperimentById(user, nodeId);
626    }
627
628
629    public string GetVisualExtension(string algorithmId) {
630      return dal.VisualExtensionDao.FindById(algorithmId);
631    }
632
633
634    public bool AddVisualExtension(string algorithmId, string script) {
635      return dal.VisualExtensionDao.Add(algorithmId, script);
636    }
637
638    public bool DeleteVisualExtension(string algorithmId) {
639      return dal.VisualExtensionDao.DeleteById(algorithmId);
640    }
641
642
643    public bool ExistsVisualExtension(string algorithmId) {
644      return dal.VisualExtensionDao.Exists(algorithmId);
645    }
646  }
647}
Note: See TracBrowser for help on using the repository browser.