* Publish flow to upload blob and data to table

* E2E test for compilation and load

* Update StorageWatcher.cs

* Update GithubClient.cs

* Store gist references for detector, publish flow for national clouds
This commit is contained in:
rekhaswaminathan 2020-05-11 14:34:15 -07:00 коммит произвёл GitHub
Родитель 66b70082ae
Коммит 05fc3103be
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 417 добавлений и 10 удалений

Просмотреть файл

@ -12,6 +12,9 @@
<None Include="$(MSBuildThisFileDirectory)BackupCheckDetector.csx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)blobDetector.csx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)GetRuntimeSiteSlotMapData.csx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

Просмотреть файл

@ -0,0 +1,7 @@
[AppFilter(AppType = AppType.WebApp, PlatformType = PlatformType.Windows, StackType = StackType.All)]
[Definition(Id = "blobDetector", Name = "Blob Detector", Author = "reswamin", Category=Categories.AvailabilityAndPerformance, Description = "This detector is stored in azure storage")]
public async static Task<Response> Run(DataProviders dp, OperationContext<App> cxt, Response res)
{
res.AddMarkdownView("This detector is stored in azure storage");
return res;
}

Просмотреть файл

@ -148,5 +148,36 @@ namespace Diagnostics.ModelsAndUtils.Models.Storage
/// Detector type - Detector, Analysis, CategoryOverview
/// </summary>
public string DetectorType { get; set; }
/// <summary>
/// List of dependencies for a detector
/// </summary>
[IgnoreProperty]
public Dictionary<string, string> Dependencies
{
get
{
if(string.IsNullOrWhiteSpace(GistReferencesRaw))
{
return null;
}
return JsonConvert.DeserializeObject<Dictionary<string,string>>(GistReferencesRaw);
}
set
{
if(value == null)
{
GistReferencesRaw = string.Empty;
} else
{
GistReferencesRaw = JsonConvert.SerializeObject(value);
}
}
}
/// <summary>
/// Gist References stored as raw string in table.
/// </summary>
public string GistReferencesRaw { get; set; } = string.Empty;
}
}

Просмотреть файл

@ -21,6 +21,7 @@ using Diagnostics.RuntimeHost.Services;
using Diagnostics.RuntimeHost.Services.CacheService;
using Diagnostics.RuntimeHost.Services.CacheService.Interfaces;
using Diagnostics.RuntimeHost.Services.SourceWatcher;
using Diagnostics.RuntimeHost.Services.SourceWatcher.Watchers;
using Diagnostics.RuntimeHost.Services.StorageService;
using Diagnostics.RuntimeHost.Utilities;
using Diagnostics.Scripts;
@ -52,6 +53,7 @@ namespace Diagnostics.RuntimeHost.Controllers
private InternalAPIHelper _internalApiHelper;
private IDiagEntityTableCacheService tableCacheService;
private ISourceWatcher storageWatcher;
public DiagnosticControllerBase(IServiceProvider services, IRuntimeContext<TResource> runtimeContext)
{
@ -67,6 +69,7 @@ namespace Diagnostics.RuntimeHost.Controllers
this._kustoMappingCacheService = (IKustoMappingsCacheService)services.GetService(typeof(IKustoMappingsCacheService));
this._loggerProvider = (IRuntimeLoggerProvider)services.GetService(typeof(IRuntimeLoggerProvider));
tableCacheService = (IDiagEntityTableCacheService)services.GetService(typeof(IDiagEntityTableCacheService));
storageWatcher = ((StorageWatcher)services.GetService(typeof(ISourceWatcher)));
this._internalApiHelper = new InternalAPIHelper();
_runtimeContext = runtimeContext;
}
@ -362,6 +365,7 @@ namespace Diagnostics.RuntimeHost.Controllers
}
await _sourceWatcherService.Watcher.CreateOrUpdatePackage(pkg);
await storageWatcher.CreateOrUpdatePackage(pkg);
return Ok();
}

Просмотреть файл

@ -33,6 +33,8 @@ namespace Diagnostics.RuntimeHost.Services
Task CreateOrUpdateFile(string destinationFilePath, string content, string commitMessage, bool convertContentToBase64 = true);
Task CreateOrUpdateFiles(IEnumerable<CommitContent> commits, string commitMessage);
Task<GitHubCommit> GetCommitByPath(string filePath);
}
public class GithubClient : IGithubClient
@ -178,6 +180,13 @@ namespace Diagnostics.RuntimeHost.Services
await _octokitClient.Git.Reference.Update(_userName, _repoName, headRef, new ReferenceUpdate(commit.Sha));
}
public async Task<GitHubCommit> GetCommitByPath(string filePath)
{
var request = new CommitRequest { Path = filePath, Sha = _branch };
var commitLists = await _octokitClient.Repository.Commit.GetAll(_userName, _repoName, request);
return commitLists.FirstOrDefault();
}
public void Dispose()
{
if (_httpClient != null)

Просмотреть файл

@ -0,0 +1,21 @@
using Diagnostics.RuntimeHost.Models;
using Diagnostics.RuntimeHost.Services.StorageService;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using System.Threading.Tasks;
namespace Diagnostics.RuntimeHost.Services.SourceWatcher.Watchers
{
public sealed class NationalCloudStorageWatcher : StorageWatcher
{
public NationalCloudStorageWatcher(IHostingEnvironment env, IConfiguration configuration, IStorageService service): base(env, configuration, service)
{
}
public override Task CreateOrUpdatePackage(Package pkg)
{
return Task.CompletedTask;
}
}
}

Просмотреть файл

@ -0,0 +1,82 @@
using Diagnostics.DataProviders;
using Diagnostics.RuntimeHost.Models;
using Diagnostics.RuntimeHost.Services.StorageService;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using System;
using System.Threading;
using System.Threading.Tasks;
using Diagnostics.ModelsAndUtils.Models.Storage;
using Newtonsoft.Json;
using Diagnostics.RuntimeHost.Utilities;
using System.IO;
using Diagnostics.Logger;
namespace Diagnostics.RuntimeHost.Services.SourceWatcher.Watchers
{
public class StorageWatcher : ISourceWatcher
{
private IStorageService storageService;
private IHostingEnvironment hostingEnvironment;
private IConfiguration configuration;
private IGithubClient gitHubClient;
public StorageWatcher(IHostingEnvironment env, IConfiguration config, IStorageService service)
{
storageService = service;
hostingEnvironment = env;
configuration = config;
gitHubClient = new GithubClient(env, config);
}
public async Task<HealthCheckResult> CheckHealthAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public virtual async Task CreateOrUpdatePackage(Package pkg)
{
if (pkg == null)
{
throw new ArgumentNullException(nameof(pkg));
}
try
{
var blobName = $"{pkg.Id.ToLower()}/{pkg.Id.ToLower()}.dll";
var etag = await storageService.LoadBlobToContainer(blobName, pkg.DllBytes);
if (string.IsNullOrWhiteSpace(etag))
{
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageWatcher), $"Uploading {pkg.Id} to blob failed, not proceeding further");
return;
}
var gitCommit = await gitHubClient.GetCommitByPath(blobName);
var diagEntity = JsonConvert.DeserializeObject<DiagEntity>(pkg.PackageConfig);
if (gitCommit != null)
{
diagEntity.GitHubSha = gitCommit.Commit.Tree.Sha;
diagEntity.GithubLastModified = gitCommit.Commit.Author.Date.DateTime.ToUniversalTime();
}
using (var ms = new MemoryStream(Convert.FromBase64String(pkg.DllBytes)))
{
var assemblyBytes = DiagEntityHelper.GetByteFromStream(ms);
diagEntity = DiagEntityHelper.PrepareEntityForLoad(assemblyBytes, pkg.CodeString, diagEntity);
}
await storageService.LoadDataToTable(diagEntity);
} catch (Exception ex)
{
DiagnosticsETWProvider.Instance.LogAzureStorageException(nameof(StorageWatcher), ex.Message, ex.GetType().ToString(), ex.ToString());
}
}
public void Start()
{
throw new NotImplementedException();
}
public Task WaitForFirstCompletion()
{
throw new NotImplementedException();
}
}
}

Просмотреть файл

@ -10,6 +10,9 @@ using Diagnostics.Logger;
using Diagnostics.RuntimeHost.Utilities;
using Microsoft.AspNetCore.Hosting;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace Diagnostics.RuntimeHost.Services.StorageService
{
@ -18,6 +21,8 @@ namespace Diagnostics.RuntimeHost.Services.StorageService
bool GetStorageFlag();
Task<List<DiagEntity>> GetEntitiesByPartitionkey(string partitionKey = null);
Task<DiagEntity> LoadDataToTable(DiagEntity detectorEntity);
Task<string> LoadBlobToContainer(string blobname, string contents);
Task<byte[]> GetBlobByName(string name);
}
public class StorageService : IStorageService
{
@ -25,8 +30,9 @@ namespace Diagnostics.RuntimeHost.Services.StorageService
public static readonly string RowKey = "RowKey";
private static CloudTableClient tableClient;
private static CloudBlobContainer containerClient;
private string tableName;
private string container;
private bool loadOnlyPublicDetectors;
private bool isStorageEnabled;
private CloudTable cloudTable;
@ -34,15 +40,18 @@ namespace Diagnostics.RuntimeHost.Services.StorageService
public StorageService(IConfiguration configuration, IHostingEnvironment hostingEnvironment)
{
tableName = configuration["SourceWatcher:TableName"];
container = configuration["SourceWatcher:BlobContainerName"];
if(hostingEnvironment != null && hostingEnvironment.EnvironmentName.Equals("UnitTest", StringComparison.CurrentCultureIgnoreCase))
{
tableClient = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudTableClient();
containerClient = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudBlobClient().GetContainerReference(container);
} else
{
var accountname = configuration["SourceWatcher:DiagStorageAccount"];
var key = configuration["SourceWatcher:DiagStorageKey"];
var storageAccount = new CloudStorageAccount(new StorageCredentials(accountname, key), accountname, "core.windows.net", true);
tableClient = storageAccount.CreateCloudTableClient();
containerClient = storageAccount.CreateCloudBlobClient().GetContainerReference(container);
}
if (!bool.TryParse((configuration[$"SourceWatcher:{RegistryConstants.LoadOnlyPublicDetectorsKey}"]), out loadOnlyPublicDetectors))
@ -63,32 +72,34 @@ namespace Diagnostics.RuntimeHost.Services.StorageService
{
CloudTable table = tableClient.GetTableReference(tableName);
await table.CreateIfNotExistsAsync();
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageService), $"Retrieving detectors from table");
var timeTakenStopWatch = new Stopwatch();
partitionKey = partitionKey == null ? "Detector" : partitionKey;
var filterPartitionKey = TableQuery.GenerateFilterCondition(PartitionKey, QueryComparisons.Equal, partitionKey);
var tableQuery = new TableQuery<DiagEntity>();
tableQuery.Where(filterPartitionKey);
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageService), $"GetEntities by parition key {partitionKey}");
TableContinuationToken tableContinuationToken = null;
var detectorsResult = new List<DiagEntity>();
timeTakenStopWatch.Start();
do
{
// Execute the operation.
var detectorList = await table.ExecuteQuerySegmentedAsync(tableQuery, tableContinuationToken);
tableContinuationToken = detectorList.ContinuationToken;
if(detectorList.Results != null)
if (detectorList.Results != null)
{
detectorsResult.AddRange(detectorList.Results);
}
} while (tableContinuationToken != null);
timeTakenStopWatch.Stop();
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageService), $"GetEntities by Parition key {partitionKey} took {timeTakenStopWatch.ElapsedMilliseconds}");
return detectorsResult;
}
catch (Exception ex)
{
DiagnosticsETWProvider.Instance.LogAzureStorageException(nameof(StorageService), ex.Message, ex.GetType().ToString(), ex.ToString());
return null;
}
}
}
public bool GetStorageFlag()
@ -109,13 +120,16 @@ namespace Diagnostics.RuntimeHost.Services.StorageService
}
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageService), $"Insert or Replace {detectorEntity.RowKey} into {tableName}");
var timeTakenStopWatch = new Stopwatch();
timeTakenStopWatch.Start();
// Create the InsertOrReplace table operation
TableOperation insertOrReplaceOperation = TableOperation.InsertOrReplace(detectorEntity);
// Execute the operation.
TableResult result = await table.ExecuteAsync(insertOrReplaceOperation);
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageService), $"InsertOrReplace result : {result.HttpStatusCode}");
timeTakenStopWatch.Stop();
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageService), $"InsertOrReplace result : {result.HttpStatusCode}, time taken {timeTakenStopWatch.ElapsedMilliseconds}");
DiagEntity insertedCustomer = result.Result as DiagEntity;
return detectorEntity;
}
@ -126,6 +140,49 @@ namespace Diagnostics.RuntimeHost.Services.StorageService
}
}
public async Task<string> LoadBlobToContainer(string blobname, string contents)
{
try
{
var timeTakenStopWatch = new Stopwatch();
await containerClient.CreateIfNotExistsAsync();
timeTakenStopWatch.Start();
var cloudBlob = containerClient.GetBlockBlobReference(blobname);
using (var uploadStream = new MemoryStream(Convert.FromBase64String(contents)))
{
await cloudBlob.UploadFromStreamAsync(uploadStream);
}
await cloudBlob.FetchAttributesAsync();
timeTakenStopWatch.Stop();
var uploadResult = cloudBlob.Properties;
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageService), $"Loaded {blobname}, etag {uploadResult.ETag}, time taken {timeTakenStopWatch.ElapsedMilliseconds}");
return uploadResult.ETag;
} catch (Exception ex)
{
DiagnosticsETWProvider.Instance.LogAzureStorageException(nameof(StorageService), ex.Message, ex.GetType().ToString(), ex.ToString());
return null;
}
}
public async Task<byte[]> GetBlobByName(string name)
{
try
{
var timeTakenStopWatch = new Stopwatch();
await containerClient.CreateIfNotExistsAsync();
timeTakenStopWatch.Start();
var cloudBlob = containerClient.GetBlockBlobReference(name);
using (MemoryStream ms = new MemoryStream())
{
await cloudBlob.DownloadToStreamAsync(ms);
DiagnosticsETWProvider.Instance.LogAzureStorageMessage(nameof(StorageService), $"Downloaded {name} to memory stream, time taken {timeTakenStopWatch.ElapsedMilliseconds}");
return ms.ToArray();
}
} catch (Exception ex)
{
DiagnosticsETWProvider.Instance.LogAzureStorageException(nameof(StorageService), ex.Message, ex.GetType().ToString(), ex.ToString());
return null;
}
}
}
}

Просмотреть файл

@ -39,6 +39,7 @@ using System.Net;
using Diagnostics.RuntimeHost.Utilities;
using Microsoft.AspNetCore.Rewrite;
using Newtonsoft.Json;
using Diagnostics.RuntimeHost.Services.SourceWatcher.Watchers;
namespace Diagnostics.RuntimeHost
{
@ -213,6 +214,13 @@ namespace Diagnostics.RuntimeHost
}
services.AddSingleton<IStorageService, StorageService>();
services.AddSingleton<IDiagEntityTableCacheService, DiagEntityTableCacheService>();
if(IsPublicAzure())
{
services.AddSingleton<ISourceWatcher, StorageWatcher>();
} else
{
services.AddSingleton<ISourceWatcher, NationalCloudStorageWatcher>();
}
services.AddLogging(loggingConfig =>
{
loggingConfig.ClearProviders();

Просмотреть файл

@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using Diagnostics.Scripts;
using Diagnostics.Scripts.Models;
using Diagnostics.ModelsAndUtils.ScriptUtilities;
using Diagnostics.ModelsAndUtils.Attributes;
using Diagnostics.ModelsAndUtils.Models.Storage;
namespace Diagnostics.RuntimeHost.Utilities
{
public static class DiagEntityHelper
{
public static DiagEntity PrepareEntityForLoad(byte[] assemblyData, string detectorScript, DiagEntity detectorPackage)
{
Assembly temp = Assembly.Load(assemblyData);
if (!Enum.TryParse(detectorPackage.EntityType, true, out EntityType entityType))
{
entityType = EntityType.Signal;
}
EntityMetadata metaData = new EntityMetadata(detectorScript, entityType);
using (var invoker = new EntityInvoker(metaData, ScriptHelper.GetFrameworkReferences(), ScriptHelper.GetFrameworkImports()))
{
invoker.InitializeEntryPoint(temp);
var resourceFilter = invoker.ResourceFilter;
detectorPackage.IsInternal = resourceFilter != null ? resourceFilter.InternalOnly : false;
detectorPackage.SupportTopicList = invoker.EntryPointDefinitionAttribute != null ? invoker.EntryPointDefinitionAttribute.SupportTopicList : new List<SupportTopic>();
detectorPackage.AnalysisTypes = invoker.EntryPointDefinitionAttribute != null ? invoker.EntryPointDefinitionAttribute.AnalysisTypes : new List<string>();
detectorPackage.DetectorType = invoker.EntryPointDefinitionAttribute != null ? invoker.EntryPointDefinitionAttribute.Type.ToString() : "Detector";
if (invoker.ResourceFilter != null)
{
if (invoker.ResourceFilter is AppFilter)
{
// Store WebApp related info
var resourceInfo = invoker.ResourceFilter as AppFilter;
AppType appType = resourceInfo.AppType;
var appTypesList = Enum.GetValues(typeof(AppType)).Cast<AppType>().Where(p => appType.HasFlag(p)).Select(x => Enum.GetName(typeof(AppType), x));
detectorPackage.AppType = string.Join(",", appTypesList);
PlatformType platformType = resourceInfo.PlatformType;
var platformTypesList = Enum.GetValues(typeof(PlatformType)).Cast<PlatformType>().Where(p => platformType.HasFlag(p)).Select(x => Enum.GetName(typeof(PlatformType), x));
detectorPackage.PlatForm = string.Join(",", platformTypesList);
StackType stackType = resourceInfo.StackType;
var stackTypesList = Enum.GetValues(typeof(StackType)).Cast<StackType>().Where(s => stackType.HasFlag(s)).Select(x => Enum.GetName(typeof(StackType), x));
detectorPackage.StackType = string.Join(",", stackTypesList);
detectorPackage.ResourceProvider = "Microsoft.Web";
detectorPackage.ResourceType = "sites";
}
else if (invoker.ResourceFilter is ApiManagementServiceFilter)
{
detectorPackage.ResourceProvider = "Microsoft.ApiManagement";
detectorPackage.ResourceType = "service";
}
else if (invoker.ResourceFilter is AppServiceCertificateFilter)
{
detectorPackage.ResourceProvider = "Microsoft.CertificateRegistration";
detectorPackage.ResourceType = "certificateOrders";
}
else if (invoker.ResourceFilter is AppServiceDomainFilter)
{
detectorPackage.ResourceProvider = "Microsoft.DomainRegistration";
detectorPackage.ResourceType = "domains";
}
else if (invoker.ResourceFilter is AzureKubernetesServiceFilter)
{
detectorPackage.ResourceProvider = "Microsoft.ContainerService";
detectorPackage.ResourceType = "managedClusters";
}
else if (invoker.ResourceFilter is LogicAppFilter)
{
detectorPackage.ResourceProvider = "Microsoft.Logic";
detectorPackage.ResourceType = "workflows";
}
else if (invoker.ResourceFilter is HostingEnvironmentFilter)
{
// Store ASE related info
var resourceInfo = invoker.ResourceFilter as HostingEnvironmentFilter;
PlatformType platformType = resourceInfo.PlatformType;
var platformTypesList = Enum.GetValues(typeof(PlatformType)).Cast<PlatformType>().Where(p => platformType.HasFlag(p)).Select(x => Enum.GetName(typeof(PlatformType), x));
detectorPackage.PlatForm = string.Join(",", platformTypesList);
HostingEnvironmentType hostingEnvironmentType = resourceInfo.HostingEnvironmentType;
var hostingEnvironmentTypesList = Enum.GetValues(typeof(HostingEnvironmentType)).Cast<HostingEnvironmentType>().Where(h => hostingEnvironmentType.HasFlag(h)).Select(x => Enum.GetName(typeof(HostingEnvironmentType), x));
detectorPackage.HostingEnvironmentType = string.Join(",", hostingEnvironmentTypesList);
detectorPackage.ResourceProvider = "Microsoft.Web";
detectorPackage.ResourceType = "hostingEnvironments";
}
else if (invoker.ResourceFilter is ArmResourceFilter)
{
// Store Provider and ResourceType
var resourceInfo = invoker.ResourceFilter as ArmResourceFilter;
detectorPackage.ResourceType = resourceInfo.ResourceTypeName;
detectorPackage.ResourceProvider = resourceInfo.Provider;
detectorPackage.ResourceType = resourceInfo.ResourceTypeName;
}
}
}
detectorPackage.PartitionKey = detectorPackage.EntityType;
detectorPackage.RowKey = detectorPackage.DetectorId;
return detectorPackage;
}
public static byte[] GetByteFromStream(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
}
}

Просмотреть файл

@ -11,6 +11,18 @@ using Diagnostics.ModelsAndUtils.Models;
using System.Threading;
using RimDev.Automation.StorageEmulator;
using System.Linq;
using Diagnostics.ModelsAndUtils.Attributes;
using Diagnostics.Tests.Helpers;
using Diagnostics.Scripts.Models;
using Diagnostics.Scripts.CompilationService;
using Diagnostics.Scripts.CompilationService.Interfaces;
using Microsoft.CodeAnalysis.Scripting;
using Octokit;
using Diagnostics.RuntimeHost.Utilities;
using System.Reflection;
using Diagnostics.Scripts;
using System.IO;
using Diagnostics.ModelsAndUtils.ScriptUtilities;
namespace Diagnostics.Tests.AzureStorageTests
{
@ -36,7 +48,11 @@ namespace Diagnostics.Tests.AzureStorageTests
if(string.IsNullOrWhiteSpace(configuration["SourceWatcher:TableName"]))
{
configuration["SourceWatcher:TableName"] = "diagentities";
}
}
if (string.IsNullOrWhiteSpace(configuration["SourceWatcher:BlobContainerName"]))
{
configuration["SourceWatcher:BlobContainerName"] = "detectors";
}
storageService = new StorageService(configuration, environment);
tableCacheService = new DiagEntityTableCacheService(storageService);
}
@ -177,5 +193,51 @@ namespace Diagnostics.Tests.AzureStorageTests
}
}
}
[Fact]
/// <summary>
/// Test blob upload operation
/// </summary>
public async void TestBlobOperations()
{
// First check if emulator is running before proceeding.
bool isEmulatorRunning = CheckProcessRunning(4);
if (isEmulatorRunning)
{
// Test .dll blob upload
Definition definitonAttribute = new Definition()
{
Id = "blobDetector"
};
EntityMetadata metadata = ScriptTestDataHelper.GetRandomMetadata();
metadata.ScriptText = await File.ReadAllTextAsync("blobDetector.csx");
var scriptOptions = ScriptTestDataHelper.GetScriptOption(ScriptHelper.GetFrameworkReferences(), ScriptHelper.GetFrameworkImports());
var serviceInstance = CompilationServiceFactory.CreateService(metadata, scriptOptions);
ICompilation compilation = await serviceInstance.GetCompilationAsync();
var assemblyBytes = await compilation.GetAssemblyBytesAsync();
var blobName = $"{definitonAttribute.Id}/{definitonAttribute.Id}.dll";
var etagdetector = await storageService.LoadBlobToContainer(blobName, assemblyBytes.Item1);
Assert.NotNull(etagdetector);
var assemblyData = await storageService.GetBlobByName(blobName);
Assert.NotNull(assemblyData);
// Now test initializing Entry Point of Invoker using assembly
Assembly temp = Assembly.Load(assemblyData);
using (EntityInvoker invoker = new EntityInvoker(metadata))
{
Exception ex = Record.Exception(() =>
{
invoker.InitializeEntryPoint(temp);
});
Assert.Null(ex);
Assert.True(invoker.IsCompilationSuccessful);
Assert.Equal(definitonAttribute.Id, invoker.EntryPointDefinitionAttribute.Id);
}
}
}
}
}