Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 11868 was 9508, checked in by fschoepp, 11 years ago

#1888:
HL:

  • Web projects requires different users to interact with hive. The singleton HiveServiceLocator.Instance doesn't allow different users at the same time, resulting in serialization during access of HiveClient methods.

The following changes have been introduced in favor of a parallel use of the HL libs:

  • HiveClient, TaskDownloader and ConcurrentTaskDownloader may now use a different IHiveServiceLocator than HiveServiceLocator.Instance (all methods have appropriate overloads now).
  • The default instance is still HiveServiceLocator.Instance.

Automated Scaling of Instances:

  • Added Scaler project to solution which represents a WorkerRole that scales the slave instances based on the global cpu utilization of all slaves.
  • Scaler is based on WASABi, rules can be adjusted in rulesstore.xml. Basic rule is: if < 45% global cpu utilization => remove an instance; if > 65% cpu => add an instance. Minimum boundary is 1 and maximum boundary is 8 slave instances.
  • Adjusted Slave project to automatically register itself to a SlaveGroup during WebRole startup (can be adjusted in service configuration).

Web-Frontend:

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