Changeset 9395


Ignore:
Timestamp:
04/24/13 13:40:43 (7 years ago)
Author:
fschoepp
Message:

#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.
Location:
branches/OaaS
Files:
1 added
17 edited

Legend:

Unmodified
Added
Removed
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs

    r9362 r9395  
    1818    public static readonly string EXPERIMENT_BLOB_CONTAINER = "experiment";
    1919    public static readonly string VISUAL_BLOB_CONTAINER = "visualextensions";
     20    public static readonly string JOB_TABLE = "Job";
    2021    public static readonly string CLOUD_SETTINGS_KEY = "Cloudia.WindowsAzure.Storage";
    2122
     
    311312
    312313    public string FindById(string algorithmId) {
    313       CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
    314       container.CreateIfNotExist();
    315       var blob = container.GetBlobReference(algorithmId);
    316       return blob.DownloadText();
     314      try {
     315        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
     316        container.CreateIfNotExist();
     317        var blob = container.GetBlobReference(algorithmId);
     318        return blob.DownloadText();
     319      }
     320      catch (Exception ex) {
     321        Trace.TraceError(ex.ToString());
     322        return null;
     323      }
     324    }
     325
     326
     327    public bool Exists(string algorithmId) {
     328      try {
     329        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
     330        container.CreateIfNotExist();
     331        var blob = container.GetBlobReference(algorithmId);
     332        blob.FetchAttributes();
     333        return true;
     334      }
     335      catch (StorageClientException ex) {
     336        if (ex.ErrorCode == StorageErrorCode.ResourceNotFound) {
     337          return false;
     338        }
     339        Trace.TraceError(ex.ToString());
     340        return false;
     341      }
     342    }
     343  }
     344
     345  internal sealed class JobEntity : TableServiceEntity {
     346    public JobEntity() {
     347    }
     348
     349    public JobEntity(string user, string experimentName, string experimentId, string jobId) {
     350      PartitionKey = "JobPartition";
     351      RowKey = user + "_" + jobId;
     352      User = user;
     353      ExperimentId = experimentId;
     354      JobId = jobId;
     355    }
     356
     357    public string ExperimentId { get; set; }
     358
     359    public string User { get; set; }
     360
     361    public string JobId { get; set; }
     362  }
     363
     364  public class JobDao : IJobDao {
     365    public IExperimentDao ExperimentDao { get; set; }
     366    public CloudTableClient TableClient { get; set; }
     367
     368    public bool Add(string username, Experiment experiment, string jobId) {
     369      try {
     370        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
     371        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
     372        serviceContext.AddObject(AzureConstants.JOB_TABLE,
     373          new JobEntity(username, experiment.Name, experiment.Id, jobId)
     374        );
     375        serviceContext.SaveChangesWithRetries();
     376        return true;
     377      }
     378      catch (Exception ex) {
     379        Trace.TraceError(ex.ToString());
     380        return false;
     381      }
     382    }
     383
     384    public bool Delete(string username, string jobId) {
     385      try {
     386        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
     387        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
     388        var entity = (from e in serviceContext.CreateQuery<JobEntity>(AzureConstants.JOB_TABLE)
     389                      where e.JobId == jobId && e.User == username
     390                      select e).FirstOrDefault();
     391        serviceContext.DeleteObject(entity);       
     392        return true;
     393      }
     394      catch (Exception ex) {
     395        Trace.TraceError(ex.ToString());
     396        return false;
     397      }
     398    }
     399
     400    public Experiment FindByJobId(string username, string jobId) {
     401      try {
     402        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
     403        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
     404        var entity = (from e in serviceContext.CreateQuery<JobEntity>(AzureConstants.JOB_TABLE)
     405                      where e.JobId == jobId && e.User == username
     406                      select e).FirstOrDefault();
     407        return ExperimentDao.GetExperimentById(new User() { Username = username }, entity.ExperimentId);
     408      }
     409      catch (Exception ex) {
     410        Trace.TraceError(ex.ToString());
     411        return null;
     412      }
    317413    }
    318414  }
     
    323419    private IExperimentDao expDao;
    324420    private IVisualExtensionDao visualDao;
     421    private IJobDao jobDao;
    325422
    326423    private CloudStorageAccount storageAccount;
     
    377474      }
    378475    }
     476
     477
     478    public IJobDao JobDao {
     479      get {
     480        if (jobDao == null) {
     481          jobDao = new JobDao() { ExperimentDao = ExperimentDao, TableClient = StorageAccount.CreateCloudTableClient() };
     482        }
     483        return jobDao;
     484      }
     485    }
    379486  }
    380487}
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs

    r9365 r9395  
    110110            IAlgorithm algo;
    111111            mapper.MapScenario(optScen, out algo);
     112            algo.Name = child.Id;
    112113            entry.Parent.Optimizers.Add(algo);
    113114          } 
     
    115116      }
    116117      details.JobTitle = exp.Name;
    117       return SendExperimentToHive(user, hiveExperiment, details) != null;
     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;
    118125    }
    119126
     
    214221      HiveServiceLocator.Instance.Password = user.Password;
    215222      HiveServiceLocator.Instance.EndpointConfigurationName = Configuration.HiveEndpointName;
    216       HiveClient.StartJob((ex) => {
    217         Console.WriteLine(ex.StackTrace);
    218       }, job, new CancellationToken());
     223      HiveClient.Store(job, new CancellationToken());
    219224     
    220225      job.StopResultPolling();
     
    286291        }
    287292      }
     293      //var experiment = dal.JobDao.FindByJobId(user.Username, id);
     294
    288295      IDictionary<Guid, HiveTask> hiveTasks = downloader.Results;
    289296      IList<Model.Run> runs = new List<Model.Run>();
     
    294301            Model.Run taskRun = new Model.Run();
    295302            taskRun.Id = taskRun.Name = run.Name;
    296             taskRun.AlgorithmName = run.Algorithm != null ? run.Algorithm.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           
    297310            IList<Parameter> resultValues = new List<Model.Parameter>();
    298311            foreach (var key in run.Results.Keys) {
     
    617630      return dal.VisualExtensionDao.FindById(algorithmId);
    618631    }
     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    }
    619646  }
    620647}
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/DAL.cs

    r9362 r9395  
    3030  }
    3131
     32  public interface IJobDao {
     33    bool Add(string username, Experiment experiment, string jobId);
     34    bool Delete(string username, string jobId);
     35    Experiment FindByJobId(string username, string jobId);
     36  }
     37
    3238  public interface IBlobDao {
    3339    bool Add(StringEntry entry);
     
    4147    bool DeleteById(string algorithmId);
    4248    string FindById(string algorithmId);
     49    bool Exists(string algorithmId);
    4350  }
    4451
     
    4855    IExperimentDao ExperimentDao { get; }
    4956    IVisualExtensionDao VisualExtensionDao { get; }
     57    IJobDao JobDao { get; }
    5058  }
    5159
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IControllerService.cs

    r9362 r9395  
    6868
    6969    [OperationContract]
    70     string GetVisualExtension(string algorithmId);
     70    VisualExtension GetVisualExtension(string algorithmId);
    7171
    7272    [OperationContract]
     
    7575    [OperationContract]
    7676    bool DeleteVisualExtension(string algorithmId);
     77
     78    [OperationContract]
     79    bool ExistsVisualExtension(string algorithmId);
    7780  }
    7881}
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IScenarioManager.cs

    r9362 r9395  
    3030
    3131    string GetVisualExtension(string algorithmId);
     32
     33    bool AddVisualExtension(string algorithmId, string script);
     34
     35    bool DeleteVisualExtension(string algorithmId);
     36
     37    bool ExistsVisualExtension(string algorithmId);
    3238  }
    3339}
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/Model/ControllerModel.cs

    r9362 r9395  
    467467      set { tasks = value; }
    468468    }
    469 
     469  }
     470
     471  [DataContract]
     472  public class VisualExtension {
     473    [DataMember]
     474    public string ScenarioId { get; set; }
     475
     476    [DataMember]
     477    public string ScenarioJs { get; set; }
    470478  }
    471479
     
    484492    public IList<Parameter> InputParameters { get; set; }
    485493
     494    [DataMember]
    486495    public string AlgorithmName { get; set; }
    487496  }
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupDAL.cs

    r9362 r9395  
    258258      get { throw new NotImplementedException(); }
    259259    }
     260
     261
     262    public IJobDao JobDao {
     263      get { throw new NotImplementedException(); }
     264    }
    260265  }
    261266}
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupScenarioManager.cs

    r9362 r9395  
    291291      throw new NotImplementedException();
    292292    }
     293
     294
     295    public bool AddVisualExtension(string algorithmId, string script) {
     296      throw new NotImplementedException();
     297    }
     298
     299    public bool DeleteVisualExtension(string algorithmId) {
     300      throw new NotImplementedException();
     301    }
     302
     303
     304    public bool ExistsVisualExtension(string algorithmId) {
     305      throw new NotImplementedException();
     306    }
    293307  }
    294308}
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs

    r9362 r9395  
    190190      jrun["results"] = ConvertParametersToJson(run.Results);
    191191      jrun["params"] = ConvertParametersToJson(run.InputParameters);
    192       jrun["algorithmName"] = run.AlgorithmName;
     192      jrun["algorithmName"] = run.AlgorithmName;     
    193193      return jrun;
    194194    }
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/PlaceholderControllerService.cs

    r9363 r9395  
    100100      var added = hiveManager.AddScenario(user, scenario.Id, scenarioXml, scenarioMapper);
    101101      if (added)
    102         scenarios.Add(scenario);
     102        scenarios.Add(scenario);     
    103103      return added;
    104104    }
     
    192192
    193193
    194     public string GetVisualExtension(string algorithmId) {
    195       return hiveManager.GetVisualExtension(algorithmId);
     194    public VisualExtension GetVisualExtension(string algorithmId) {
     195      return new VisualExtension() { ScenarioId = algorithmId, ScenarioJs = hiveManager.GetVisualExtension(algorithmId) };
    196196    }
    197197
    198198
    199199    public bool AddVisualExtension(string algorithmId, string script) {
    200       //return hiveManager.AddVisualExtension(algorithmId, script);
    201       return true;
     200      return hiveManager.AddVisualExtension(algorithmId, script);
    202201    }
    203202
    204203    public bool DeleteVisualExtension(string algorithmId) {
    205       //return hiveManager.DeleteVisualExtension(algorithmId);
    206       return true;
     204      return hiveManager.DeleteVisualExtension(algorithmId);
     205    }
     206
     207
     208    public bool ExistsVisualExtension(string algorithmId) {
     209      return hiveManager.ExistsVisualExtension(algorithmId);
    207210    }
    208211  }
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.controller.js

    r9324 r9395  
    11var OAAS_CONTROLLER = (function (my, Backbone, OAAS_VIEW, OAAS_MODEL, _, $) {
     2    my.JobVisualExtensionListener = function (model, element) {
     3        var extension = new OAAS_MODEL.VisualExtension({ id: model.get('algorithmName') });
     4        extension.fetch({ cache: true, success: function () {
     5            //eval extension.js -> execute addVisualExtension(model, element):
     6            var js = extension.get('ScenarioJs');
     7            if (js != null) {
     8                (function (model, element) {
     9                    addExtension = undefined;
     10                    eval(js);
     11                    if (addExtension)
     12                        addExtension(model, element);
     13                } (model, element));
     14            }
     15        }
     16        });
     17    },
    218    my.JobPageController = function () {
    319        this.create = function () {
     
    2339                    var div = $('<div/>').appendTo($('#jobDetails'));
    2440                    var rv = new OAAS_VIEW.ResultView({ model: runList, el: div });
     41                    listener.listenTo(rv, 'renderVisualExtension', my.JobVisualExtensionListener);
    2542                    rv.render();
    2643                    var av = new OAAS_VIEW.AccordionView({ el: div });
     
    3047            });
    3148
     49
     50
    3251            jobList.poll();
    3352        }
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.model.js

    r9362 r9395  
    7777    });
    7878
     79    my.VisualExtension = Backbone.Model.extend({
     80        defaults: {
     81            id: null,
     82            js: null
     83        },
     84        url: function () {
     85            return '/Job/VisualExtension?scenarioId=' + this.get('id');
     86        }
     87    });
     88
    7989    return my;
    8090} (OAAS_MODEL || {}, Backbone));
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.view.js

    r9350 r9395  
    9090                $('<h3></h3>').text(this.model.models[i].get('name')).appendTo(this.$el);
    9191                var rev = new my.ResultEntryView({ model: this.model.models[i], el: this.$el });
    92                 rev.render();
    93             }
     92                this.listenTo(rev, 'renderVisualExtension', this.renderVisualExtension);
     93                rev.render();                         
     94            }           
     95        },
     96        renderVisualExtension: function(model, element) {
     97            // propagate to client listener
     98            this.trigger('renderVisualExtension', model, element);
    9499        }
    95100    });
     
    161166            var results = this.model.get('results');
    162167            for (var i = 0; i < results.length; i++) {
    163                 this.renderModelEntry(results[i], i, body, 'results');
    164             }
     168                this.renderModelEntry(results[i], i, body, 'results');               
     169            }
     170            // get the visual extension, execute it!
     171            this.trigger('renderVisualExtension', this.model, body);
    165172
    166173            var inputs = this.model.get('params');
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/AdminController.cs

    r9215 r9395  
    3434        public ActionResult Index()
    3535        {
    36           var names = ControllerService.withControllerService<IEnumerable<string>>((service) => {           
     36          var names = ControllerService.withControllerService<IEnumerable<ScenarioModel>>((service) => {           
    3737            User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
    38             return service.GetOptimizationScenarioNames();
     38            var scenModel = new List<ScenarioModel>();
     39            var scenarios = service.GetOptimizationScenarioNames();
     40            foreach (var scenario in scenarios) {
     41              scenModel.Add(new ScenarioModel() { Exists = service.ExistsVisualExtension(scenario), Scenario = scenario });             
     42            }
     43            return scenModel;
    3944          });
    4045          return View(names);
     
    6570        }
    6671
     72        [HttpPost]
     73        public ActionResult AddVisualExtension(UploadVisualExtension extension) {         
     74          StreamReader reader = new StreamReader(extension.ScenarioJs.InputStream);
     75          string scenarioJs = reader.ReadToEnd();
     76
     77          var ok = ControllerService.withControllerService<bool>((service) => {
     78            OptimizationModel model = new OptimizationModel();
     79            User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
     80            return service.AddVisualExtension(extension.ScenarioId, scenarioJs);
     81          });
     82          return RedirectToAction("Index");
     83        }
     84
     85        [HttpPost]
     86        public ActionResult DeleteVisualExtension(UploadVisualExtension extension) {
     87          var ok = ControllerService.withControllerService<bool>((service) => {
     88            OptimizationModel model = new OptimizationModel();
     89            User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
     90            return service.DeleteVisualExtension(extension.ScenarioId);
     91          });
     92          return RedirectToAction("Index");
     93        }
     94
    6795        public ActionResult DeleteScenario(string id) {
    6896          ControllerService.withControllerService<bool>((service) => {           
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/JobController.cs

    r9362 r9395  
    5959
    6060      [HttpGet]
    61       public ActionResult VisualExtension(string algorithmId) {
    62         var script = ControllerService.withControllerService<string>((service) => {
     61      public JsonResult VisualExtension(string scenarioId) {
     62        var extension = ControllerService.withControllerService<VisualExtension>((service) => {
    6363          User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
    64           return service.GetVisualExtension(algorithmId);
     64          return service.GetVisualExtension(scenarioId);
    6565        });
    66         return Content(script, "text/javascript", System.Text.Encoding.UTF8);
     66        return Json(extension, JsonRequestBehavior.AllowGet);
    6767      }
    6868    }
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Models/AdminModels.cs

    r9362 r9395  
    2929      set { scenarioJs = value; }
    3030    }
     31  }
     32
     33  public class ScenarioModel {
     34    public string Scenario { get; set; }
     35    public bool Exists { get; set; }
     36  }
     37
     38  public class UploadVisualExtension {
     39
     40    private string scenarioId;
     41
     42    public string ScenarioId {
     43      get { return scenarioId; }
     44      set { scenarioId = value; }
     45    }
     46
     47
     48    private HttpPostedFileBase scenarioJs;
     49
     50    public HttpPostedFileBase ScenarioJs {
     51      get { return scenarioJs; }
     52      set { scenarioJs = value; }
     53    }
    3154
    3255  }
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Admin/Index.cshtml

    r9362 r9395  
    1 @model IEnumerable<string>
     1@model IEnumerable<HeuristicLab.Services.Optimization.Web.Models.ScenarioModel>
    22
    33@{
     
    1111    <label for="scenarioMapper">Scenario Mapper</label>
    1212    <input type="file" name="scenarioMapper" id="scenarioMapper" />
    13     <label for="scenarioMapper">Scenario XML</label>
     13    <label for="scenarioXml">Scenario XML</label>
    1414    <input type="file" name="scenarioXml" id="scenarioXml" />
    15     <label for="scenarioMapper">Visual extension (JavaScript) for Scenario</label>
    16     <input type="file" name="scenarioJs" id="scenarioJs" />
    1715    <input type="submit" value="Upload scenario" />   
    1816  </fieldset>
     
    3129      @foreach (var scen in Model) {
    3230        <tr>
    33           <td>@scen</td>
     31          <td>@scen.Scenario</td>
    3432          <td>
    35              <input type="hidden" value="@scen" name="id" />
     33             <input type="hidden" value="@scen.Scenario" name="id" />
    3634             <input type="submit" value="Delete" />       
    37           </td>         
     35          </td>
    3836       </tr>
    3937      }
     
    4240}
    4341
     42<h2>Visual extensions:</h2>
     43@using (Html.BeginForm("DeleteVisualExtension", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" })) {
     44  <fieldset>   
     45    <label for="scenarioId">Scenario</label>
     46    <select name="scenarioId">
     47        @foreach (var scen in Model) {
     48            if (scen.Exists) {
     49                <option>@scen.Scenario</option>
     50            }
     51        }
     52    </select>
     53    <input type="submit" value="Delete visual extension" />   
     54  </fieldset>
     55}
    4456
     57@using (Html.BeginForm("AddVisualExtension", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" })) {
     58  <fieldset>   
     59    <label for="scenarioId">Scenario</label>
     60    <select name="scenarioId">
     61        @foreach (var scen in Model) {
     62            <option>@scen.Scenario</option>
     63        }
     64    </select>
     65    <label for="scenarioJs">Visual extension (JavaScript) for Scenario</label>
     66    <input type="file" name="scenarioJs" id="scenarioJs" />
     67    <input type="submit" value="Upload visual extension" />   
     68  </fieldset>
     69}
Note: See TracChangeset for help on using the changeset viewer.