Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 13401 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: 18.9 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 VISUAL_BLOB_CONTAINER = "visualextensions";
20    public static readonly string JOB_TABLE = "Job";
21    public static readonly string CLOUD_SETTINGS_KEY = "Cloudia.WindowsAzure.Storage";
22
23   
24  }
25
26  public class ScenarioDao : IScenarioDao {   
27    public CloudTableClient TableClient { get; set; }
28
29    public bool Add(ScenarioEntity entity) {
30      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
31      TableClient.CreateTableIfNotExist(AzureConstants.SCENARIO_TABLE);
32      ScenarioEntity dbEntity = (from e in serviceContext.CreateQuery<ScenarioEntity>(AzureConstants.SCENARIO_TABLE)
33                               where e.RowKey == entity.RowKey
34                               select e).FirstOrDefault();
35      if (dbEntity != null)
36        return false;
37
38      serviceContext.AddObject(AzureConstants.SCENARIO_TABLE, entity);
39      serviceContext.SaveChanges();
40      return true;
41    }
42
43    public bool DeleteByName(string scenarioName) {
44      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
45      TableClient.CreateTableIfNotExist(AzureConstants.SCENARIO_TABLE);
46      ScenarioEntity entity = (from e in serviceContext.CreateQuery<ScenarioEntity>(AzureConstants.SCENARIO_TABLE)
47                               where e.RowKey == scenarioName
48                               select e).FirstOrDefault();
49      if (entity == null)
50        return false;
51
52      serviceContext.DeleteObject(entity);
53      serviceContext.SaveChangesWithRetries();
54      return true;
55    }
56
57    public ScenarioEntity FindByName(string scenarioName) {
58      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
59      TableClient.CreateTableIfNotExist(AzureConstants.SCENARIO_TABLE);
60      ScenarioEntity entity = (from e in serviceContext.CreateQuery<ScenarioEntity>(AzureConstants.SCENARIO_TABLE)
61                               where e.RowKey == scenarioName
62                               select e).FirstOrDefault();
63      return entity;
64    }
65
66
67    public IEnumerable<ScenarioEntity> GetAllEntities() {
68      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
69      TableClient.CreateTableIfNotExist(AzureConstants.SCENARIO_TABLE);
70      return (from e in serviceContext.CreateQuery<ScenarioEntity>(AzureConstants.SCENARIO_TABLE)
71             select e).AsEnumerable();
72    }
73  }
74
75  public class BlobDao : IBlobDao {
76    public CloudBlobClient BlobClient { get; set; }
77
78    public bool Add(StringEntry entry) {
79      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.SCENARIO_BLOB_CONTAINER);
80      container.CreateIfNotExist();
81      var blob = container.GetBlobReference(entry.Key);
82      blob.UploadText(entry.Text);
83      return true;
84    }
85
86    public bool DeleteByKey(string entryKey) {
87      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.SCENARIO_BLOB_CONTAINER);
88      container.CreateIfNotExist();
89      var blob = container.GetBlobReference(entryKey);
90      return blob.DeleteIfExists();
91    }
92
93    public StringEntry FindByKey(string entryKey) {
94      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.SCENARIO_BLOB_CONTAINER);
95      container.CreateIfNotExist();
96      var blob = container.GetBlobReference(entryKey);
97      return new StringEntry() { Key = entryKey, Text = blob.DownloadText() };     
98    }
99  }
100
101  internal sealed class ExperimentEntity : TableServiceEntity {
102    public ExperimentEntity() {
103    }
104
105    public ExperimentEntity(string user, string experimentName, string experimentId, string experimentUrl) {
106      PartitionKey = "ScenarioPartition";
107      RowKey = user + "_" + experimentName;     
108      User = user;
109      ExperimentId = experimentId;
110      ExperimentJsonUrl = experimentUrl;
111    }
112
113    public string ExperimentId { get; set; }
114
115    public string User { get; set; }
116
117    public string ExperimentJsonUrl { get; set; }
118
119  }
120
121  public class ExperimentDao : IExperimentDao {
122    public CloudBlobClient BlobClient { get; set; }
123    public CloudTableClient TableClient { get; set; }
124
125    public bool Add(string username, Model.Experiment experiment) {
126      if (FindByName(username, experiment.Name) != null)
127        return false;
128
129      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
130      container.CreateIfNotExist();
131      // For now we store it as JSON element in the blob store
132      var experimentJson = AlgorithmConverter.ConvertExperimentToJson(experiment);
133      Guid experimentJsonGuid = Guid.NewGuid();
134      var experimentJsonId = experiment.Name + "_" + experimentJsonGuid.ToString();
135      experimentJson["nodeId"] = experimentJsonId.ToString();
136      var blob = container.GetBlobReference(experimentJsonId);     
137      blob.UploadText(experimentJson.ToString());
138      experiment.Id = experimentJsonId;
139
140      TableServiceContext serviceContext = TableClient.GetDataServiceContext();     
141      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
142      var entity = new ExperimentEntity(username, experiment.Name, experiment.Id, blob.Uri.ToString());
143      serviceContext.AddObject(AzureConstants.EXPERIMENT_TABLE, entity);
144      serviceContext.SaveChangesWithRetries();
145      return true;
146    }
147
148    public bool Update(string username, Experiment experiment) {
149      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
150      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
151      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
152                    where e.ExperimentId == experiment.Id
153                    select e).FirstOrDefault();
154      if (entity == null) {
155        return false;
156      }
157
158      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
159      container.CreateIfNotExist();
160      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
161      var experimentJson = AlgorithmConverter.ConvertExperimentToJson(experiment).ToString();
162      blob.UploadText(experimentJson);
163      return true;
164    }
165
166    public bool Delete(string username, string experimentId) {
167      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
168      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
169      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
170                    where e.ExperimentId == experimentId
171                    select e).FirstOrDefault();
172
173      if (entity == null)
174        return false;
175
176      if (entity.ExperimentJsonUrl != null) {
177        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
178        container.CreateIfNotExist();
179        var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
180        blob.DeleteIfExists();
181      }
182
183      serviceContext.DeleteObject(entity);
184      serviceContext.SaveChangesWithRetries();
185      return true;
186    }
187
188    public bool DeleteByName(string username, string experiment) {
189      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
190      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
191      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
192                    where e.RowKey == (username + "_" + experiment)
193                    select e).FirstOrDefault();
194     
195      if (entity == null)
196        return false;
197
198      if (entity.ExperimentJsonUrl != null) {
199        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
200        container.CreateIfNotExist();
201        var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
202        blob.DeleteIfExists();
203      }
204
205      serviceContext.DeleteObject(entity);
206      serviceContext.SaveChangesWithRetries();
207      return true;
208    }
209
210    public Model.Experiment FindByName(string username, string experiment) {
211      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
212      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
213      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
214                    where e.RowKey == (username + "_" + experiment)
215                    select e).FirstOrDefault();
216     
217      if (entity == null) {
218        return null;
219      }
220
221      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
222      container.CreateIfNotExist();
223      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
224      return AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText());
225    }
226
227    public IEnumerable<Model.Experiment> GetExperiments(string user, bool namesOnly=false) {
228      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
229      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
230      var entites = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
231                    where e.User == user
232                    select e).ToList();
233      var experiments = new List<Experiment>();
234      if (namesOnly) {
235        return (from e in entites select new Model.Experiment() { Id = e.ExperimentId, Name = e.RowKey.Split('_')[1] });
236      }
237      else {
238        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
239        container.CreateIfNotExist();
240        foreach (var entity in entites) {
241          var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
242          experiments.Add(AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText()));
243        }
244        return experiments;
245      }
246    }
247
248
249    public Experiment GetExperimentByName(string username, string scenario) {
250      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
251      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
252      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
253                      where e.RowKey == username + "_" + scenario
254                      select e).FirstOrDefault();
255      if (entity == null || entity.ExperimentJsonUrl == null) {
256        return null;
257      }
258
259      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
260      container.CreateIfNotExist();
261      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
262      var exp = AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText());
263      return exp;
264    }
265
266
267    public Experiment GetExperimentById(User user, string nodeId) {
268      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
269      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
270      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
271                    where e.ExperimentId == nodeId
272                    select e).FirstOrDefault();
273      if (entity == null || entity.ExperimentJsonUrl == null) {
274        return null;
275      }
276
277      if (entity.User != user.Username)
278        return null;
279
280      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
281      container.CreateIfNotExist();
282      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
283      return AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText());
284    }
285  }
286
287  public class VisualExtensionDao : IVisualExtensionDao {
288    public CloudBlobClient BlobClient { get; set; }
289
290    public bool Add(string algorithmId, string script) {
291      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
292      container.CreateIfNotExist();
293      var blob = container.GetBlobReference(algorithmId);
294      blob.UploadText(script);
295      return true;
296    }
297
298    public bool DeleteById(string algorithmId) {
299      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
300      container.CreateIfNotExist();
301      var blob = container.GetBlobReference(algorithmId);
302      return blob.DeleteIfExists();
303    }
304
305    public string FindById(string algorithmId) {
306      try {
307        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
308        container.CreateIfNotExist();
309        var blob = container.GetBlobReference(algorithmId);
310        return blob.DownloadText();
311      }
312      catch (Exception ex) {
313        Trace.TraceError(ex.ToString());
314        return null;
315      }
316    }
317
318
319    public bool Exists(string algorithmId) {
320      try {
321        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
322        container.CreateIfNotExist();
323        var blob = container.GetBlobReference(algorithmId);
324        blob.FetchAttributes();
325        return true;
326      }
327      catch (StorageClientException ex) {
328        if (ex.ErrorCode == StorageErrorCode.ResourceNotFound) {
329          return false;
330        }
331        Trace.TraceError(ex.ToString());
332        return false;
333      }
334    }
335  }
336
337  internal sealed class JobEntity : TableServiceEntity {
338    public JobEntity() {
339    }
340
341    public JobEntity(string user, string experimentName, string experimentId, string jobId) {
342      PartitionKey = "JobPartition";
343      RowKey = user + "_" + jobId;
344      User = user;
345      ExperimentId = experimentId;
346      JobId = jobId;
347    }
348
349    public string ExperimentId { get; set; }
350
351    public string User { get; set; }
352
353    public string JobId { get; set; }
354  }
355
356  public class JobDao : IJobDao {
357    public IExperimentDao ExperimentDao { get; set; }
358    public CloudTableClient TableClient { get; set; }
359
360    public bool Add(string username, Experiment experiment, string jobId) {
361      try {
362        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
363        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
364        serviceContext.AddObject(AzureConstants.JOB_TABLE,
365          new JobEntity(username, experiment.Name, experiment.Id, jobId)
366        );
367        serviceContext.SaveChangesWithRetries();
368        return true;
369      }
370      catch (Exception ex) {
371        Trace.TraceError(ex.ToString());
372        return false;
373      }
374    }
375
376    public bool Delete(string username, string jobId) {
377      try {
378        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
379        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
380        var entity = (from e in serviceContext.CreateQuery<JobEntity>(AzureConstants.JOB_TABLE)
381                      where e.JobId == jobId && e.User == username
382                      select e).FirstOrDefault();
383        serviceContext.DeleteObject(entity);       
384        return true;
385      }
386      catch (Exception ex) {
387        Trace.TraceError(ex.ToString());
388        return false;
389      }
390    }
391
392    public Experiment FindByJobId(string username, string jobId) {
393      try {
394        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
395        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
396        var entity = (from e in serviceContext.CreateQuery<JobEntity>(AzureConstants.JOB_TABLE)
397                      where e.JobId == jobId && e.User == username
398                      select e).FirstOrDefault();
399        return ExperimentDao.GetExperimentById(new User() { Username = username }, entity.ExperimentId);
400      }
401      catch (Exception ex) {
402        Trace.TraceError(ex.ToString());
403        return null;
404      }
405    }
406  }
407
408  public class AzureDataAccessLayer : IDataAccessLayer {
409    private IScenarioDao scenarioDao;
410    private IBlobDao blobDao;
411    private IExperimentDao expDao;
412    private IVisualExtensionDao visualDao;
413    private IJobDao jobDao;
414
415    private CloudStorageAccount storageAccount;
416
417    private CloudStorageAccount StorageAccount {
418      get {
419        if (storageAccount == null) {
420          try {
421            storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(AzureConstants.CLOUD_SETTINGS_KEY));
422          }
423          catch (Exception ex) {
424            Trace.WriteLine(ex.Message);
425            storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=optimizationstorage1;AccountKey=n7Leom8ZFWkof/VQ2a4aRSvwOlX+Gwr3uojQF9CFJw1osmGCV0WwaNC8s7nkZ+qteLduAgW2l75WFpbXrkvG4Q==");
426          }
427        }
428        return storageAccount;
429      }     
430    }
431
432    public IScenarioDao ScenarioDao {
433      get {
434        if (scenarioDao == null) {
435          scenarioDao = new ScenarioDao() { TableClient = StorageAccount.CreateCloudTableClient() };
436        }
437        return scenarioDao;
438      }
439    }
440
441    public IBlobDao BlobDao {
442      get {
443        if (blobDao == null) {
444          blobDao = new BlobDao() { BlobClient = StorageAccount.CreateCloudBlobClient() };
445        }
446        return blobDao;
447      }
448    }
449
450    public IExperimentDao ExperimentDao {
451      get {
452        if (expDao == null) {
453          expDao = new ExperimentDao() { TableClient = StorageAccount.CreateCloudTableClient(), BlobClient = StorageAccount.CreateCloudBlobClient() };
454        }
455        return expDao;
456      }
457    }
458
459
460    public IVisualExtensionDao VisualExtensionDao {
461      get {
462        if (visualDao == null) {
463          visualDao = new VisualExtensionDao() { BlobClient = StorageAccount.CreateCloudBlobClient() };
464        }
465        return visualDao;
466      }
467    }
468
469
470    public IJobDao JobDao {
471      get {
472        if (jobDao == null) {
473          jobDao = new JobDao() { ExperimentDao = ExperimentDao, TableClient = StorageAccount.CreateCloudTableClient() };
474        }
475        return jobDao;
476      }
477    }
478  }
479}
Note: See TracBrowser for help on using the repository browser.