source: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs @ 9324

Last change on this file since 9324 was 9324, checked in by fschoepp, 6 years ago

#1888:

  • DAL: Added a Delete method which deletes by experiment id.
  • HL DataTables will now be transposed and mapped as double[ROWS][COLUMNS] (transposed)
  • JS: Moved all classes into "modules" to prevent namespace pollution (using OAAS_MODEL for model classes, OAAS_VIEW for views and OAAS_CONTROLLER for controllers)
  • JS: Moved DatatypeMapper classes into Backbone views
  • JS: Models now correctly send DELETE requests
  • Added a new job overview page (which also renders run details) using AJAX
  • Using moment.min.js to format DateTime as string
  • Controllers now inherit from BaseController which provides a RedirectToLoginIfNecessary-method
  • Added loading animations to several AJAX bound places (loading experiments / scenarios)
  • Added a section to _Layout.cshtml which allows page-specific JavaScript includes (<script> only for a certain page)
  • Fixed Build/Edit of experiment menu redirecting to the wrong page
  • The Experiment Variation Dialog disables input fields, if the property has not been activated before
File size: 14.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Services.Optimization.ControllerService.Interfaces;
6using Microsoft.WindowsAzure;
7using Microsoft.WindowsAzure.StorageClient;
8using Microsoft.WindowsAzure.ServiceRuntime;
9using System.Diagnostics;
10using HeuristicLab.Services.Optimization.ControllerService.Model;
11using HeuristicLab.Services.Optimization.ControllerService.Parsers;
12
13namespace HeuristicLab.Services.Optimization.ControllerService.Azure {
14  public static class AzureConstants {
15    public static readonly string SCENARIO_TABLE = "Scenario";
16    public static readonly string SCENARIO_BLOB_CONTAINER = "scenario";
17    public static readonly string EXPERIMENT_TABLE = "Experiment";
18    public static readonly string EXPERIMENT_BLOB_CONTAINER = "experiment";
19    public static readonly string CLOUD_SETTINGS_KEY = "Cloudia.WindowsAzure.Storage";
20
21   
22  }
23
24  public class ScenarioDao : IScenarioDao {   
25    public CloudTableClient TableClient { get; set; }
26
27    public bool Add(ScenarioEntity entity) {
28      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
29      TableClient.CreateTableIfNotExist(AzureConstants.SCENARIO_TABLE);
30      ScenarioEntity dbEntity = (from e in serviceContext.CreateQuery<ScenarioEntity>(AzureConstants.SCENARIO_TABLE)
31                               where e.RowKey == entity.RowKey
32                               select e).FirstOrDefault();
33      if (dbEntity != null)
34        return false;
35
36      serviceContext.AddObject(AzureConstants.SCENARIO_TABLE, entity);
37      serviceContext.SaveChanges();
38      return true;
39    }
40
41    public bool DeleteByName(string scenarioName) {
42      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
43      TableClient.CreateTableIfNotExist(AzureConstants.SCENARIO_TABLE);
44      ScenarioEntity entity = (from e in serviceContext.CreateQuery<ScenarioEntity>(AzureConstants.SCENARIO_TABLE)
45                               where e.RowKey == scenarioName
46                               select e).FirstOrDefault();
47      if (entity == null)
48        return false;
49
50      serviceContext.DeleteObject(entity);
51      serviceContext.SaveChangesWithRetries();
52      return true;
53    }
54
55    public ScenarioEntity FindByName(string scenarioName) {
56      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
57      TableClient.CreateTableIfNotExist(AzureConstants.SCENARIO_TABLE);
58      ScenarioEntity entity = (from e in serviceContext.CreateQuery<ScenarioEntity>(AzureConstants.SCENARIO_TABLE)
59                               where e.RowKey == scenarioName
60                               select e).FirstOrDefault();
61      return entity;
62    }
63
64
65    public IEnumerable<ScenarioEntity> GetAllEntities() {
66      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
67      TableClient.CreateTableIfNotExist(AzureConstants.SCENARIO_TABLE);
68      return (from e in serviceContext.CreateQuery<ScenarioEntity>(AzureConstants.SCENARIO_TABLE)
69             select e).AsEnumerable();
70    }
71  }
72
73  public class BlobDao : IBlobDao {
74    public CloudBlobClient BlobClient { get; set; }
75
76    public bool Add(StringEntry entry) {
77      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.SCENARIO_BLOB_CONTAINER);
78      container.CreateIfNotExist();
79      var blob = container.GetBlobReference(entry.Key);
80      blob.UploadText(entry.Text);
81      return true;
82    }
83
84    public bool DeleteByKey(string entryKey) {
85      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.SCENARIO_BLOB_CONTAINER);
86      container.CreateIfNotExist();
87      var blob = container.GetBlobReference(entryKey);
88      return blob.DeleteIfExists();
89    }
90
91    public StringEntry FindByKey(string entryKey) {
92      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.SCENARIO_BLOB_CONTAINER);
93      container.CreateIfNotExist();
94      var blob = container.GetBlobReference(entryKey);
95      return new StringEntry() { Key = entryKey, Text = blob.DownloadText() };     
96    }
97  }
98
99  internal sealed class ExperimentEntity : TableServiceEntity {
100    public ExperimentEntity() {
101    }
102
103    public ExperimentEntity(string user, string experimentName, string experimentId, string experimentUrl) {
104      PartitionKey = "ScenarioPartition";
105      RowKey = user + "_" + experimentName;     
106      User = user;
107      ExperimentId = experimentId;
108      ExperimentJsonUrl = experimentUrl;
109    }
110
111    public string ExperimentId { get; set; }
112
113    public string User { get; set; }
114
115    public string ExperimentJsonUrl { get; set; }
116
117  }
118
119  public class ExperimentDao : IExperimentDao {
120    public CloudBlobClient BlobClient { get; set; }
121    public CloudTableClient TableClient { get; set; }
122
123    public bool Add(string username, Model.Experiment experiment) {
124      if (FindByName(username, experiment.Name) != null)
125        return false;
126
127      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
128      container.CreateIfNotExist();
129      // For now we store it as JSON element in the blob store
130      var experimentJson = AlgorithmConverter.ConvertExperimentToJson(experiment);
131      Guid experimentJsonGuid = Guid.NewGuid();
132      var experimentJsonId = experiment.Name + "_" + experimentJsonGuid.ToString();
133      experimentJson["nodeId"] = experimentJsonId.ToString();
134      var blob = container.GetBlobReference(experimentJsonId);     
135      blob.UploadText(experimentJson.ToString());
136      experiment.Id = experimentJsonId;
137
138      TableServiceContext serviceContext = TableClient.GetDataServiceContext();     
139      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
140      var entity = new ExperimentEntity(username, experiment.Name, experiment.Id, blob.Uri.ToString());
141      serviceContext.AddObject(AzureConstants.EXPERIMENT_TABLE, entity);
142      serviceContext.SaveChangesWithRetries();
143      return true;
144    }
145
146    public bool Update(string username, Experiment experiment) {
147      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
148      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
149      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
150                    where e.ExperimentId == experiment.Id
151                    select e).FirstOrDefault();
152      if (entity == null) {
153        return false;
154      }
155
156      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
157      container.CreateIfNotExist();
158      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
159      var experimentJson = AlgorithmConverter.ConvertExperimentToJson(experiment).ToString();
160      blob.UploadText(experimentJson);
161      return true;
162    }
163
164    public bool Delete(string username, string experimentId) {
165      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
166      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
167      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
168                    where e.ExperimentId == experimentId
169                    select e).FirstOrDefault();
170
171      if (entity == null)
172        return false;
173
174      if (entity.ExperimentJsonUrl != null) {
175        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
176        container.CreateIfNotExist();
177        var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
178        blob.DeleteIfExists();
179      }
180
181      serviceContext.DeleteObject(entity);
182      serviceContext.SaveChangesWithRetries();
183      return true;
184    }
185
186    public bool DeleteByName(string username, string experiment) {
187      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
188      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
189      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
190                    where e.RowKey == (username + "_" + experiment)
191                    select e).FirstOrDefault();
192     
193      if (entity == null)
194        return false;
195
196      if (entity.ExperimentJsonUrl != null) {
197        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
198        container.CreateIfNotExist();
199        var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
200        blob.DeleteIfExists();
201      }
202
203      serviceContext.DeleteObject(entity);
204      serviceContext.SaveChangesWithRetries();
205      return true;
206    }
207
208    public Model.Experiment FindByName(string username, string experiment) {
209      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
210      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
211      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
212                    where e.RowKey == (username + "_" + experiment)
213                    select e).FirstOrDefault();
214     
215      if (entity == null) {
216        return null;
217      }
218
219      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
220      container.CreateIfNotExist();
221      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
222      return AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText());
223    }
224
225    //private Experiment Convert(ExperimentEntity entity, string entityJson) {
226    //  // TODO: Read the whole experiment, not just the names!
227    //  var exp = new Experiment() { Name = entity.RowKey.Split('_')[1] };
228    //  foreach (var scenarioName in entity.Algorithms.Split(','))
229    //    exp.Algorithm.Add(new Algorithm() { Name = scenarioName });
230    //  return exp;
231    //}
232
233    public IEnumerable<Model.Experiment> GetExperiments(string user, bool namesOnly=false) {
234      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
235      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
236      var entites = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
237                    where e.User == user
238                    select e).ToList();
239      var experiments = new List<Experiment>();
240      if (namesOnly) {
241        return (from e in entites select new Model.Experiment() { Id = e.ExperimentId, Name = e.RowKey.Split('_')[1] });
242      }
243      else {
244        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
245        container.CreateIfNotExist();
246        foreach (var entity in entites) {
247          var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
248          experiments.Add(AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText()));
249        }
250        return experiments;
251      }
252    }
253
254
255    public Experiment GetExperimentByName(string username, string scenario) {
256      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
257      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
258      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
259                      where e.RowKey == username + "_" + scenario
260                      select e).FirstOrDefault();
261      if (entity == null || entity.ExperimentJsonUrl == null) {
262        return null;
263      }
264
265      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
266      container.CreateIfNotExist();
267      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
268      var exp = AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText());
269      return exp;
270    }
271
272
273    public Experiment GetExperimentById(User user, string nodeId) {
274      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
275      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
276      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
277                    where e.ExperimentId == nodeId
278                    select e).FirstOrDefault();
279      if (entity == null || entity.ExperimentJsonUrl == null) {
280        return null;
281      }
282
283      if (entity.User != user.Username)
284        return null;
285
286      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
287      container.CreateIfNotExist();
288      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
289      return AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText());
290    }
291
292  }
293
294  public class AzureDataAccessLayer : IDataAccessLayer {
295    private IScenarioDao scenarioDao;
296    private IBlobDao blobDao;
297    private IExperimentDao expDao;
298
299    private CloudStorageAccount storageAccount;
300
301    private CloudStorageAccount StorageAccount {
302      get {
303        if (storageAccount == null) {
304          try {
305            storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(AzureConstants.CLOUD_SETTINGS_KEY));
306          }
307          catch (Exception ex) {
308            Trace.WriteLine(ex.Message);
309            storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=optimizationstorage1;AccountKey=n7Leom8ZFWkof/VQ2a4aRSvwOlX+Gwr3uojQF9CFJw1osmGCV0WwaNC8s7nkZ+qteLduAgW2l75WFpbXrkvG4Q==");
310          }
311        }
312        return storageAccount; 
313      }     
314    }
315
316    public IScenarioDao ScenarioDao {
317      get {
318        if (scenarioDao == null) {
319          scenarioDao = new ScenarioDao() { TableClient = StorageAccount.CreateCloudTableClient() };
320        }
321        return scenarioDao;
322      }
323    }
324
325    public IBlobDao BlobDao {
326      get {
327        if (blobDao == null) {
328          blobDao = new BlobDao() { BlobClient = StorageAccount.CreateCloudBlobClient() };
329        }
330        return blobDao;
331      }
332    }
333
334    public IExperimentDao ExperimentDao {
335      get {
336        if (expDao == null) {
337          expDao = new ExperimentDao() { TableClient = StorageAccount.CreateCloudTableClient(), BlobClient = StorageAccount.CreateCloudBlobClient() };
338        }
339        return expDao;
340      }
341    }
342  }
343}
Note: See TracBrowser for help on using the repository browser.