Publish flow (#503)
* 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:
Родитель
66b70082ae
Коммит
05fc3103be
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче