private async Task TestLoadSignalSimple(Type signalType, string expectedTitle = "test test test") { ISmartSignalLoader loader = new SmartSignalLoader(this.tracerMock.Object); SmartSignalManifest manifest = new SmartSignalManifest("3", "simple", "description", Version.Parse("1.0"), signalType.Assembly.GetName().Name, signalType.FullName, new List <ResourceType>() { ResourceType.Subscription }, new List <int> { 60 }); SmartSignalPackage package = new SmartSignalPackage(manifest, this.assemblies["3"]); ISmartSignal signal = loader.LoadSignal(package); Assert.IsNotNull(signal, "Signal is NULL"); var resource = new ResourceIdentifier(ResourceType.VirtualMachine, "someSubscription", "someGroup", "someVM"); var analysisRequest = new AnalysisRequest( new List <ResourceIdentifier> { resource }, DateTime.UtcNow.AddDays(-1), TimeSpan.FromDays(1), new Mock <IAnalysisServicesFactory>().Object); SmartSignalResult signalResult = await signal.AnalyzeResourcesAsync(analysisRequest, this.tracerMock.Object, default(CancellationToken)); Assert.AreEqual(1, signalResult.ResultItems.Count, "Incorrect number of result items returned"); Assert.AreEqual(expectedTitle, signalResult.ResultItems.Single().Title, "Result item title is wrong"); Assert.AreEqual(resource, signalResult.ResultItems.Single().ResourceIdentifier, "Result item resource identifier is wrong"); }
/// <summary> /// Raises the <see cref="E:System.Windows.Application.Startup" /> event. /// </summary> /// <param name="e">A <see cref="T:System.Windows.StartupEventArgs" /> that contains the event data.</param> protected override void OnStartup(StartupEventArgs e) { ITracer stringTracer = new StringTracer(string.Empty); ITracer consoleTracer = new ConsoleTracer(string.Empty); var signalLoader = new SmartSignalLoader(consoleTracer); // *Temporary*: if package file path wasn't accepted, raise file selection window to allow package file selection. // This option should be removed before launching version for customers (bug for tracking: 1177247) string signalPackagePath = e.Args.Length != 1 ? this.GetSignalPackagePath() : Diagnostics.EnsureStringNotNullOrWhiteSpace(() => e.Args[0]); SmartSignalPackage signalPackage; using (var fileStream = new FileStream(signalPackagePath, FileMode.Open)) { signalPackage = SmartSignalPackage.CreateFromStream(fileStream, consoleTracer); } SmartSignalManifest signalManifest = signalPackage.Manifest; ISmartSignal signal = signalLoader.LoadSignal(signalPackage); // Authenticate the user to Active Directory var authenticationServices = new AuthenticationServices(); authenticationServices.AuthenticateUser(); ICredentialsFactory credentialsFactory = new ActiveDirectoryCredentialsFactory(authenticationServices); IAzureResourceManagerClient azureResourceManagerClient = new AzureResourceManagerClient(credentialsFactory, consoleTracer); // Create analysis service factory var queryRunInroProvider = new QueryRunInfoProvider(azureResourceManagerClient); var httpClientWrapper = new HttpClientWrapper(); IAnalysisServicesFactory analysisServicesFactory = new AnalysisServicesFactory(consoleTracer, httpClientWrapper, credentialsFactory, azureResourceManagerClient, queryRunInroProvider); var signalRunner = new SmartSignalRunner(signal, analysisServicesFactory, queryRunInroProvider, signalManifest, stringTracer); // Create a Unity container with all the required models and view models registrations Container = new UnityContainer(); Container .RegisterInstance(stringTracer) .RegisterInstance(new SignalsResultsRepository()) .RegisterInstance(authenticationServices) .RegisterInstance(azureResourceManagerClient) .RegisterInstance(signal) .RegisterInstance(signalManifest) .RegisterInstance(analysisServicesFactory) .RegisterInstance(signalRunner); }
/// <summary> /// Initializes a new instance of the <see cref="SmartSignalRunner"/> class. /// </summary> /// <param name="smartSignal">The smart signal.</param> /// <param name="analysisServicesFactory">The analysis services factory.</param> /// <param name="queryRunInfoProvider">The query run information provider.</param> /// <param name="smartSignalManifest">The smart signal manifest.</param> /// <param name="tracer">The tracer.</param> public SmartSignalRunner( ISmartSignal smartSignal, IAnalysisServicesFactory analysisServicesFactory, IQueryRunInfoProvider queryRunInfoProvider, SmartSignalManifest smartSignalManifest, ITracer tracer) { this.smartSignal = smartSignal; this.analysisServicesFactory = analysisServicesFactory; this.queryRunInfoProvider = queryRunInfoProvider; this.smartSignalManifes = smartSignalManifest; this.Tracer = tracer; this.IsSignalRunning = false; this.Results = new ObservableCollection <SignalResultItem>(); }
private async Task TestLoadSignalFromDll(string signalId, string expectedTitle) { ISmartSignalLoader loader = new SmartSignalLoader(this.tracerMock.Object); SmartSignalPackage package = new SmartSignalPackage(this.manifests[signalId], this.assemblies[signalId]); ISmartSignal signal = loader.LoadSignal(package); Assert.IsNotNull(signal, "Signal is NULL"); var resource = new ResourceIdentifier(ResourceType.VirtualMachine, "someSubscription", "someGroup", "someVM"); var analysisRequest = new AnalysisRequest( new List <ResourceIdentifier> { resource }, DateTime.UtcNow.AddDays(-1), TimeSpan.FromDays(1), new Mock <IAnalysisServicesFactory>().Object); SmartSignalResult signalResult = await signal.AnalyzeResourcesAsync(analysisRequest, this.tracerMock.Object, default(CancellationToken)); Assert.AreEqual(1, signalResult.ResultItems.Count, "Incorrect number of result items returned"); Assert.AreEqual(expectedTitle, signalResult.ResultItems.Single().Title, "Result item title is wrong"); Assert.AreEqual(resource, signalResult.ResultItems.Single().ResourceIdentifier, "Result item resource identifier is wrong"); }
/// <summary> /// Loads the signal, runs it, and returns the generated result presentations /// </summary> /// <param name="request">The signal request</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A <see cref="Task{TResult}"/>, returning the list of Smart Signal result item presentations generated by the signal</returns> public async Task <List <SmartSignalResultItemPresentation> > RunAsync(SmartSignalRequest request, CancellationToken cancellationToken) { // Read the signal's package this.tracer.TraceInformation($"Loading signal package for signal ID {request.SignalId}"); SmartSignalPackage signalPackage = await this.smartSignalRepository.ReadSignalPackageAsync(request.SignalId, cancellationToken); SmartSignalManifest signalManifest = signalPackage.Manifest; this.tracer.TraceInformation($"Read signal package, ID {signalManifest.Id}, Version {signalManifest.Version}"); // Load the signal ISmartSignal signal = this.smartSignalLoader.LoadSignal(signalPackage); this.tracer.TraceInformation($"Signal instance loaded successfully, ID {signalManifest.Id}"); // Get the resources on which to run the signal List <ResourceIdentifier> resources = await this.GetResourcesForSignal(request.ResourceIds, signalManifest, cancellationToken); // Run the signal this.tracer.TraceInformation($"Started running signal ID {signalManifest.Id}, Name {signalManifest.Name}"); SmartSignalResult signalResult; try { var analysisRequest = new AnalysisRequest(resources, request.LastExecutionTime, request.Cadence, this.analysisServicesFactory); signalResult = await signal.AnalyzeResourcesAsync(analysisRequest, this.tracer, cancellationToken); this.tracer.TraceInformation($"Completed running signal ID {signalManifest.Id}, Name {signalManifest.Name}, returning {signalResult.ResultItems.Count} result items"); } catch (Exception e) { this.tracer.TraceInformation($"Failed running signal ID {signalManifest.Id}, Name {signalManifest.Name}: {e.Message}"); throw new SmartSignalCustomException(e.GetType().ToString(), e.Message, e.StackTrace); } // Verify that each result item belongs to one of the types declared in the signal manifest foreach (SmartSignalResultItem resultItem in signalResult.ResultItems) { if (!signalManifest.SupportedResourceTypes.Contains(resultItem.ResourceIdentifier.ResourceType)) { throw new UnidentifiedResultItemResourceTypeException(resultItem.ResourceIdentifier); } } // Trace the number of result items of each type foreach (var resultItemType in signalResult.ResultItems.GroupBy(x => x.GetType().Name)) { this.tracer.TraceInformation($"Got {resultItemType.Count()} Smart Signal result items of type '{resultItemType.Key}'"); this.tracer.ReportMetric("SignalResultItemType", resultItemType.Count(), new Dictionary <string, string>() { { "ResultItemType", resultItemType.Key } }); } // Create results List <SmartSignalResultItemPresentation> results = new List <SmartSignalResultItemPresentation>(); foreach (var resultItem in signalResult.ResultItems) { SmartSignalResultItemQueryRunInfo queryRunInfo = await this.queryRunInfoProvider.GetQueryRunInfoAsync(new List <ResourceIdentifier>() { resultItem.ResourceIdentifier }, cancellationToken); results.Add(SmartSignalResultItemPresentation.CreateFromResultItem(request, signalManifest.Name, resultItem, queryRunInfo)); } this.tracer.TraceInformation($"Returning {results.Count} results"); return(results); }