public async Task <AlertResolutionCheckResponse> CheckForResolutionAsync( AlertResolutionCheckRequest alertResolutionCheckRequest, ITracer tracer, CancellationToken cancellationToken) { this.IsRunning = true; Assert.AreEqual(new DateTime(1999, 12, 30, 7, 0, 0), alertResolutionCheckRequest.OriginalAnalysisRequestParameters.RequestTime); this.AssertAnalysisRequestParameters(alertResolutionCheckRequest.OriginalAnalysisRequestParameters, assertRequestTime: false); Assert.AreEqual(alertResolutionCheckRequest.OriginalAnalysisRequestParameters.TargetResources.Single(), alertResolutionCheckRequest.RequestParameters.ResourceIdentifier); Assert.AreEqual(new DateTime(1985, 7, 3), alertResolutionCheckRequest.RequestParameters.AlertFireTime); Assert.AreEqual(1, alertResolutionCheckRequest.RequestParameters.AlertPredicates.Count); Assert.AreEqual("Predicate", alertResolutionCheckRequest.RequestParameters.AlertPredicates.Single().Key); Assert.AreEqual("Predicate value", alertResolutionCheckRequest.RequestParameters.AlertPredicates.Single().Value); await alertResolutionCheckRequest.StateRepository.StoreStateAsync("test auto resolve key", "test state", cancellationToken); if (this.ShouldStuck) { try { await Task.Delay(int.MaxValue, cancellationToken); } catch (TaskCanceledException) { this.WasCanceled = true; throw; } } if (this.ShouldThrow) { throw new DivideByZeroException(); } if (this.ShouldThrowCustom) { throw new CustomException(); } return(this.ShouldResolve ? new AlertResolutionCheckResponse(true, null) : new AlertResolutionCheckResponse(false, new AlertResolutionParameters { CheckForResolutionAfter = TimeSpan.FromMinutes(15) })); }
/// <summary> /// Runs the Smart Detector's resolution check flow. /// </summary> /// <param name="request">The alert resolution check request.</param> /// <param name="smartDetector">The Smart Detector to run</param> /// <param name="smartDetectorManifest">The Smart Detector's manifest</param> /// <param name="detectorTracer">The tracer to provider for the Smart Detector</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A <see cref="Task{TResult}"/>, returning the resolution check response generated by the Smart Detector.</returns> private async Task <ContractsAlertResolutionCheckResponse> CheckAlertResolutionAsync( ContractsAlertResolutionCheckRequest request, ISmartDetector smartDetector, SmartDetectorManifest smartDetectorManifest, ITracer detectorTracer, CancellationToken cancellationToken) { // Check that the detector supports resolution if (!(smartDetector is IResolvableAlertSmartDetector resolvableAlertSmartDetector)) { throw new ResolutionCheckNotSupportedException($"Smart Detector {smartDetectorManifest.Name} does not support alert resolution of alerts"); } // Create state repository IStateRepository stateRepository = this.stateRepositoryFactory.Create(request.OriginalAnalysisRequest.SmartDetectorId, request.OriginalAnalysisRequest.AlertRuleResourceId); // Load the resolution state from the repository ResolutionState resolutionState = await stateRepository.GetStateAsync <ResolutionState>(GetResolutionStateKey(request.AlertCorrelationHash), cancellationToken); if (resolutionState == null) { throw new ResolutionStateNotFoundException($"Resolution state for Alert with correlation {request.AlertCorrelationHash} was not found"); } // Create the input for the Smart Detector AnalysisRequestParameters analysisRequestParameters = await this.CreateAnalysisRequestParametersAsync( resolutionState.AnalysisRequestTime, request.OriginalAnalysisRequest, smartDetectorManifest, false, cancellationToken); var alertResolutionCheckRequest = new AlertResolutionCheckRequest( analysisRequestParameters, new AlertResolutionCheckRequestParameters(ResourceIdentifier.CreateFromResourceId(request.TargetResource), request.AlertFireTime, resolutionState.AlertPredicates), this.analysisServicesFactory, stateRepository); // Run the Smart Detector this.tracer.TraceInformation($"Started running Smart Detector ID {smartDetectorManifest.Id}, Name {smartDetectorManifest.Name} for resolution check"); try { AlertResolutionCheckResponse alertResolutionCheckResponse = await resolvableAlertSmartDetector.CheckForResolutionAsync(alertResolutionCheckRequest, detectorTracer, cancellationToken); this.tracer.TraceInformation($"Completed running Smart Detector ID {smartDetectorManifest.Id}, Name {smartDetectorManifest.Name} for resolution check"); // If the alert is resolved - delete the state if (alertResolutionCheckResponse.ShouldBeResolved) { await stateRepository.DeleteStateAsync(GetResolutionStateKey(request.AlertCorrelationHash), cancellationToken); } // Convert the result return(new ContractsAlertResolutionCheckResponse { ShouldBeResolved = alertResolutionCheckResponse.ShouldBeResolved, ResolutionParameters = alertResolutionCheckResponse.AlertResolutionParameters?.CreateContractsResolutionParameters() }); } catch (Exception e) { this.tracer.TraceError($"Failed running Smart Detector ID {smartDetectorManifest.Id}, Name {smartDetectorManifest.Name} for resolution check: {e}"); throw new FailedToRunSmartDetectorException($"Calling Smart Detector '{smartDetectorManifest.Name}' for resolution check failed with exception of type {e.GetType()} and message: {e.Message}", e); } }