Ejemplo n.º 1
0
        public async Task <HttpResponseMessage> RunAsync(HttpRequestMessage req, CancellationToken cancellationToken)
        {
            _log.LogDebug($"Context: {_context.InvocationId} {_context.FunctionName} {_context.FunctionDirectory} {_context.FunctionAppDirectory}");

            var aggregatorVersion = GetCustomAttribute <System.Reflection.AssemblyInformationalVersionAttribute>()?.InformationalVersion;

            try
            {
                var rule = _context.FunctionName;
                _log.LogInformation($"Aggregator v{aggregatorVersion} executing rule '{rule}'");
            }
            catch (Exception ex)
            {
                _log.LogWarning($"Failed parsing request headers: {ex.Message}");
            }

            cancellationToken.ThrowIfCancellationRequested();

            // Get request body
            var jsonContent = await req.Content.ReadAsStringAsync();

            if (string.IsNullOrWhiteSpace(jsonContent))
            {
                _log.LogWarning($"Failed parsing request body: empty");

                var resp = new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    Content = new StringContent("Request body is empty")
                };
                return(resp);
            }

            dynamic data      = JsonConvert.DeserializeObject(jsonContent);
            string  eventType = data.eventType;

            // sanity check
            if (!DevOpsEvents.IsValidEvent(eventType) ||
                data.publisherId != DevOpsEvents.PublisherId)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Not a good Azure DevOps post..."
                }));
            }

            if (data.resource.url == "http://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/5")
            {
                var resp = req.CreateResponse(HttpStatusCode.OK, new
                {
                    message = $"Hello from Aggregator v{aggregatorVersion} executing rule '{_context.FunctionName}'"
                });
                resp.Headers.Add("X-Aggregator-Version", aggregatorVersion);
                resp.Headers.Add("X-Aggregator-Rule", _context.FunctionName);
                return(resp);
            }

            var config = new ConfigurationBuilder()
                         .SetBasePath(_context.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();
            var configuration = AggregatorConfiguration.Read(config);

            configuration = InvokeOptions.ExtendFromUrl(configuration, req.RequestUri);

            var logger  = new ForwarderLogger(_log);
            var wrapper = new RuleWrapper(configuration, logger, _context.FunctionName, _context.FunctionDirectory);

            try
            {
                string execResult = await wrapper.ExecuteAsync(data, cancellationToken);

                if (string.IsNullOrEmpty(execResult))
                {
                    var resp = new HttpResponseMessage(HttpStatusCode.OK);
                    return(resp);
                }
                else
                {
                    _log.LogInformation($"Returning '{execResult}' from '{_context.FunctionName}'");

                    var resp = new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent(execResult)
                    };
                    return(resp);
                }
            }
            catch (Exception ex)
            {
                _log.LogWarning($"Rule '{_context.FunctionName}' failed: {ex.Message}");

                var resp = new HttpResponseMessage(HttpStatusCode.NotImplemented)
                {
                    Content = new StringContent(ex.Message)
                };
                return(resp);
            }
        }
Ejemplo n.º 2
0
        public async Task <HttpResponseMessage> RunAsync(HttpRequestMessage req, CancellationToken cancellationToken)
        {
            _log.LogDebug($"Context: {_context.InvocationId} {_context.FunctionName} {_context.FunctionDirectory} {_context.FunctionAppDirectory}");

            var ruleName          = _context.FunctionName;
            var aggregatorVersion = GetCustomAttribute <System.Reflection.AssemblyInformationalVersionAttribute>()?.InformationalVersion;

            _log.LogInformation($"Aggregator v{aggregatorVersion} executing rule '{ruleName}'");
            cancellationToken.ThrowIfCancellationRequested();

            // Get request body
            var eventData = await GetWebHookEvent(req);

            if (eventData == null)
            {
                return(req.CreateErrorResponse(HttpStatusCode.BadRequest, "Request body is empty"));
            }

            // sanity check
            if (!DevOpsEvents.IsValidEvent(eventData.EventType) ||
                eventData.PublisherId != DevOpsEvents.PublisherId)
            {
                return(req.CreateErrorResponse(HttpStatusCode.BadRequest, "Not a good Azure DevOps post..."));
            }

            var eventContext = CreateContextFromEvent(eventData);

            if (eventContext.IsTestEvent())
            {
                return(req.CreateTestEventResponse(aggregatorVersion, ruleName));
            }

            var configContext = GetConfigurationContext();
            var configuration = AggregatorConfiguration.ReadConfiguration(configContext)
                                .UpdateFromUrl(ruleName, req.RequestUri);

            var logger       = new ForwarderLogger(_log);
            var ruleProvider = new AzureFunctionRuleProvider(logger, _context.FunctionDirectory);
            var ruleExecutor = new RuleExecutor(logger, configuration);

            using (_log.BeginScope($"WorkItem #{eventContext.WorkItemPayload.WorkItem.Id}"))
            {
                try
                {
                    var rule = await ruleProvider.GetRule(ruleName);

                    var execResult = await ruleExecutor.ExecuteAsync(rule, eventContext, cancellationToken);

                    if (string.IsNullOrEmpty(execResult))
                    {
                        return(req.CreateResponse(HttpStatusCode.OK));
                    }
                    else
                    {
                        _log.LogInformation($"Returning '{execResult}' from '{rule.Name}'");
                        return(req.CreateResponse(HttpStatusCode.OK, execResult));
                    }
                }
                catch (Exception ex)
                {
                    _log.LogWarning($"Rule '{ruleName}' failed: {ex.Message}");
                    return(req.CreateErrorResponse(HttpStatusCode.NotImplemented, ex));
                }
            }
        }
        public async Task <HttpResponseMessage> Run(HttpRequestMessage req)
        {
            log.LogDebug($"Context: {context.InvocationId} {context.FunctionName} {context.FunctionDirectory} {context.FunctionAppDirectory}");

            var aggregatorVersion = GetCustomAttribute <System.Reflection.AssemblyInformationalVersionAttribute>()?.InformationalVersion;

            try
            {
                string rule = context.FunctionName;
                log.LogInformation($"Aggregator v{aggregatorVersion} executing rule '{rule}'");
            }
            catch (Exception ex)
            {
                log.LogWarning($"Failed parsing request headers: {ex.Message}");
            }

            // Get request body
            string jsonContent = await req.Content.ReadAsStringAsync();

            if (string.IsNullOrWhiteSpace(jsonContent))
            {
                log.LogWarning($"Failed parsing request body: empty");

                var resp = new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    Content = new StringContent("Request body is empty")
                };
                return(resp);
            }
            dynamic data      = JsonConvert.DeserializeObject(jsonContent);
            string  eventType = data.eventType;

            // sanity check
            if (!DevOpsEvents.IsValidEvent(eventType) ||
                data.publisherId != DevOpsEvents.PublisherId)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Not a good Azure DevOps post..."
                }));
            }

            var config = new ConfigurationBuilder()
                         .SetBasePath(context.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();
            var configuration = AggregatorConfiguration.Read(config);

            var logger  = new ForwarderLogger(log);
            var wrapper = new RuleWrapper(configuration, logger, context.FunctionName, context.FunctionDirectory);

            try
            {
                string execResult = await wrapper.Execute(data);

                if (string.IsNullOrEmpty(execResult))
                {
                    var resp = new HttpResponseMessage(HttpStatusCode.OK);
                    return(resp);
                }
                else
                {
                    log.LogInformation($"Returning '{execResult}' from '{context.FunctionName}'");

                    var resp = new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent(execResult)
                    };
                    return(resp);
                }
            }
            catch (Exception ex)
            {
                log.LogWarning($"Rule '{context.FunctionName}' failed: {ex.Message}");

                var resp = new HttpResponseMessage(HttpStatusCode.NotImplemented)
                {
                    Content = new StringContent(ex.Message)
                };
                return(resp);
            }
        }
        public async Task <IActionResult> RunAsync(/*HttpRequest request, */ WebHookEvent eventData, CancellationToken cancellationToken)
        {
            _log.LogDebug($"Context: {_executionContext.InvocationId} {_executionContext.FunctionName} {_executionContext.FunctionDirectory} {_executionContext.FunctionAppDirectory}");

            var ruleName          = _executionContext.FunctionName;
            var aggregatorVersion = RequestHelper.AggregatorVersion;

            _log.LogInformation($"Aggregator v{aggregatorVersion} executing rule '{ruleName}'");
            cancellationToken.ThrowIfCancellationRequested();

            if (eventData == null)
            {
                return(BadRequest("Request body is empty"));
            }

            // sanity check
            if (!DevOpsEvents.IsValidEvent(eventData.EventType) ||
                eventData.PublisherId != DevOpsEvents.PublisherId)
            {
                _log.LogDebug("return BadRequest");
                return(BadRequest(new { Error = "Not a good Azure DevOps post..." }));
            }

            var helper       = new RequestHelper(_log);
            var eventContext = helper.CreateContextFromEvent(eventData);

            if (eventContext.IsTestEvent())
            {
                Response.AddCustomHeaders(aggregatorVersion, ruleName);
                return(RespondToTestEventMessage(aggregatorVersion, ruleName));
            }

            var configContext = GetConfigurationContext();
            var configuration = AggregatorConfiguration.ReadConfiguration(configContext)
                                .UpdateFromUrl(ruleName, GetRequestUri());

            var logger       = new ForwarderLogger(_log);
            var ruleProvider = new AzureFunctionRuleProvider(logger, _executionContext.FunctionDirectory);
            var ruleExecutor = new RuleExecutor(logger, configuration);

            using (_log.BeginScope($"WorkItem #{eventContext.WorkItemPayload.WorkItem.Id}"))
            {
                try
                {
                    var rule = await ruleProvider.GetRule(ruleName);

                    var execResult = await ruleExecutor.ExecuteAsync(rule, eventContext, cancellationToken);

                    if (string.IsNullOrEmpty(execResult))
                    {
                        return(Ok());
                    }
                    else
                    {
                        _log.LogInformation($"Returning '{execResult}' from '{rule.Name}'");
                        return(Ok(execResult));
                    }
                }
                catch (Exception ex)
                {
                    _log.LogWarning($"Rule '{ruleName}' failed: {ex.Message}");
                    return(BadRequest(ex.Message));
                }
            }
        }
 public AspNetRuleProvider(ForwarderLogger logger, IConfiguration configuration)
 {
     this._logger        = logger;
     this._configuration = configuration;
 }