/// <summary> /// Runs the Smart Detector's resolution check flow. /// </summary> /// <param name="request">The alert resolution check request.</param> /// <param name="shouldDetectorTrace">Determines if the detector's traces are emitted.</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> public async Task <AlertResolutionCheckResponse> CheckResolutionAsync(AlertResolutionCheckRequest request, bool shouldDetectorTrace, CancellationToken cancellationToken) { try { // Run the child process return(await this.childProcessManager.RunChildProcessAsync <AlertResolutionCheckResponse>( this.GetSmartDetectorExecutablePath(), new SmartDetectorRunnerChildProcessInput { AlertResolutionCheckRequest = request }, cancellationToken)); } catch (ChildProcessFailedException e) { if (Enum.IsDefined(typeof(HttpStatusCode), e.ExitCode)) { throw new AnalysisFailedException((HttpStatusCode)e.ExitCode, e.Message, e); } throw new AnalysisFailedException($"Running Smart Detector resolution check in child process failed with exit code {e.ExitCode} and message: {e.Message}", e); } }
public static async Task <HttpResponseMessage> RunAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "checkResolution")] HttpRequestMessage request, TraceWriter log, ExecutionContext context, CancellationToken cancellationToken) { using (IUnityContainer childContainer = Container.CreateChildContainer().WithTracer(log, true)) { // Create a tracer for this run (that will also log to the specified TraceWriter) ITracer tracer = childContainer.Resolve <ITracer>(); tracer.TraceInformation($"CheckResolution function request received with invocation Id {context.InvocationId}"); tracer.AddCustomProperty("FunctionName", context.FunctionName); tracer.AddCustomProperty("InvocationId", context.InvocationId.ToString("N", CultureInfo.InvariantCulture)); try { // Trace app counters (before analysis) tracer.TraceAppCounters(); // Read the request AlertResolutionCheckRequest alertResolutionCheckRequest = await request.Content.ReadAsAsync <AlertResolutionCheckRequest>(cancellationToken); tracer.AddCustomProperty("SmartDetectorId", alertResolutionCheckRequest.OriginalAnalysisRequest.SmartDetectorId); tracer.TraceInformation($"CheckResolution request received: {JsonConvert.SerializeObject(alertResolutionCheckRequest)}"); // Process the request ISmartDetectorRunner runner = childContainer.Resolve <ISmartDetectorRunner>(); bool shouldDetectorTrace = bool.Parse(ConfigurationReader.ReadConfig("ShouldDetectorTrace", required: true)); AlertResolutionCheckResponse alertResolutionCheckResponse = await runner.CheckResolutionAsync(alertResolutionCheckRequest, shouldDetectorTrace, cancellationToken); tracer.TraceInformation($"CheckResolution completed, alert {(alertResolutionCheckResponse.ShouldBeResolved ? "should" : "should not")} be resolved"); // Create the response with StringContent to prevent Json from serializing to a string var response = request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(JsonConvert.SerializeObject(alertResolutionCheckResponse), Encoding.UTF8, "application/json"); return(response); } catch (AnalysisFailedException afe) { // Handle the exception TopLevelExceptionHandler.TraceUnhandledException(afe, tracer, log); // Return error status return(request.CreateResponse(afe.StatusCode, afe.ReasonPhrase)); } catch (Exception e) { // Handle the exception TopLevelExceptionHandler.TraceUnhandledException(e, tracer, log); // Return error status return(request.CreateResponse(HttpStatusCode.InternalServerError, e.Message)); } finally { // Trace app counters (after analysis) tracer.TraceAppCounters(); } } }