コード例 #1
0
        private WebHookDataContext GetWebHookDataContext(Version version)
        {
            string json = File.ReadAllText(Path.GetFullPath(Path.Combine("..", "..", "..", "ErrorData", "1477.expected.json")));

            var settings = GetService <JsonSerializerSettings>();

            settings.Formatting = Formatting.Indented;

            var ev = JsonConvert.DeserializeObject <PersistentEvent>(json, settings);

            ev.OrganizationId = TestConstants.OrganizationId;
            ev.ProjectId      = TestConstants.ProjectId;
            ev.StackId        = TestConstants.StackId;
            ev.Id             = TestConstants.EventId;

            var context = new WebHookDataContext(version, ev, OrganizationData.GenerateSampleOrganization(GetService <BillingManager>(), GetService <BillingPlans>()), ProjectData.GenerateSampleProject())
            {
                Stack = StackData.GenerateStack(id: TestConstants.StackId, organizationId: TestConstants.OrganizationId, projectId: TestConstants.ProjectId, title: _formatter.GetStackTitle(ev), signatureHash: "722e7afd4dca4a3c91f4d94fec89dfdc")
            };

            context.Stack.Tags = new TagSet {
                "Test"
            };
            context.Stack.FirstOccurrence = context.Stack.LastOccurrence = ev.Date.UtcDateTime;

            return(context);
        }
コード例 #2
0
ファイル: LoadDefaults.cs プロジェクト: aTiKhan/Exceptionless
    public override async Task <object> CreateFromStackAsync(WebHookDataContext ctx)
    {
        if (ctx.Stack == null)
        {
            throw new ArgumentException("Stack cannot be null.");
        }

        if (ctx.Project == null)
        {
            ctx.Project = await _projectRepository.GetByIdAsync(ctx.Stack.ProjectId, o => o.Cache()).AnyContext();
        }

        if (ctx.Project == null)
        {
            throw new ArgumentException("Project not found.");
        }

        if (ctx.Organization == null)
        {
            ctx.Organization = await _organizationRepository.GetByIdAsync(ctx.Stack.OrganizationId, o => o.Cache()).AnyContext();
        }

        if (ctx.Organization == null)
        {
            throw new ArgumentException("Organization not found.");
        }

        return(null);
    }
コード例 #3
0
        private WebHookDataContext GetWebHookDataContext(Version version)
        {
            var json = File.ReadAllText(Path.GetFullPath(@"..\..\ErrorData\1477.expected.json"));

            var settings = new JsonSerializerSettings {
                MissingMemberHandling = MissingMemberHandling.Ignore,
                ContractResolver      = new ExtensionContractResolver()
            };

            var ev = JsonConvert.DeserializeObject <PersistentEvent>(json, settings);

            ev.OrganizationId = TestConstants.OrganizationId;
            ev.ProjectId      = TestConstants.ProjectId;
            ev.StackId        = TestConstants.StackId;

            var context = new WebHookDataContext(version, ev, OrganizationData.GenerateSampleOrganization(), ProjectData.GenerateSampleProject());

            context.Stack      = StackData.GenerateStack(id: TestConstants.StackId, organizationId: TestConstants.OrganizationId, projectId: TestConstants.ProjectId, title: _formattingPluginManager.GetStackTitle(ev), signatureHash: "722e7afd4dca4a3c91f4d94fec89dfdc");
            context.Stack.Tags = new TagSet {
                "Test"
            };
            context.Stack.FirstOccurrence = context.Stack.LastOccurrence = ev.Date.DateTime;

            return(context);
        }
コード例 #4
0
    public override Task <object> CreateFromStackAsync(WebHookDataContext ctx)
    {
        if (!String.Equals(ctx.Version, Models.WebHook.KnownVersions.Version1))
        {
            return(Task.FromResult <object>(null));
        }

        return(Task.FromResult <object>(new VersionOneWebHookStack(_options.BaseURL)
        {
            Id = ctx.Stack.Id,
            Status = ctx.Stack.Status,
            Title = ctx.Stack.Title,
            Description = ctx.Stack.Description,
            Tags = ctx.Stack.Tags,
            RequestPath = ctx.Stack.SignatureInfo.ContainsKey("Path") ? ctx.Stack.SignatureInfo["Path"] : null,
            Type = ctx.Stack.SignatureInfo.ContainsKey("ExceptionType") ? ctx.Stack.SignatureInfo["ExceptionType"] : null,
            TargetMethod = ctx.Stack.SignatureInfo.ContainsKey("Method") ? ctx.Stack.SignatureInfo["Method"] : null,
            ProjectId = ctx.Stack.ProjectId,
            ProjectName = ctx.Project.Name,
            OrganizationId = ctx.Stack.OrganizationId,
            OrganizationName = ctx.Organization.Name,
            TotalOccurrences = ctx.Stack.TotalOccurrences,
            FirstOccurrence = ctx.Stack.FirstOccurrence,
            LastOccurrence = ctx.Stack.LastOccurrence,
            DateFixed = ctx.Stack.DateFixed,
            IsRegression = ctx.Stack.Status == StackStatus.Regressed,
            IsCritical = ctx.Stack.OccurrencesAreCritical || ctx.Stack.Tags != null && ctx.Stack.Tags.Contains("Critical"),
            FixedInVersion = ctx.Stack.FixedInVersion
        }));
    }
コード例 #5
0
    public override Task <object> CreateFromEventAsync(WebHookDataContext ctx)
    {
        if (!String.Equals(ctx.Version, Models.WebHook.KnownVersions.Version2))
        {
            return(Task.FromResult <object>(null));
        }

        return(Task.FromResult <object>(new WebHookEvent(_options.BaseURL)
        {
            Id = ctx.Event.Id,
            OccurrenceDate = ctx.Event.Date,
            Tags = ctx.Event.Tags,
            Message = ctx.Event.Message,
            Type = ctx.Event.Type,
            Source = ctx.Event.Source,
            ProjectId = ctx.Event.ProjectId,
            ProjectName = ctx.Project.Name,
            OrganizationId = ctx.Event.OrganizationId,
            OrganizationName = ctx.Organization.Name,
            StackId = ctx.Event.StackId,
            StackTitle = ctx.Stack.Title,
            StackDescription = ctx.Stack.Description,
            StackTags = ctx.Stack.Tags,
            TotalOccurrences = ctx.Stack.TotalOccurrences,
            FirstOccurrence = ctx.Stack.FirstOccurrence,
            LastOccurrence = ctx.Stack.LastOccurrence,
            DateFixed = ctx.Stack.DateFixed,
            IsRegression = ctx.IsRegression,
            IsNew = ctx.IsNew
        }));
    }
コード例 #6
0
    /// <summary>
    /// Runs all of the event plugins create method.
    /// </summary>
    public async Task <object> CreateFromStackAsync(WebHookDataContext context)
    {
        string metricPrefix = String.Concat(_metricPrefix, nameof(CreateFromStackAsync).ToLower(), ".");

        foreach (var plugin in Plugins.Values)
        {
            string metricName = String.Concat(metricPrefix, plugin.Name.ToLower());
            try {
                object data = null;
                await _metricsClient.TimeAsync(async() => data = await plugin.CreateFromStackAsync(context).AnyContext(), metricName).AnyContext();

                if (data == null)
                {
                    continue;
                }

                return(data);
            }
            catch (Exception ex) {
                _logger.LogError(ex, "Error calling create from stack {stack} in plugin {PluginName}: {Message}", context.Stack.Id, plugin.Name, ex.Message);
            }
        }

        return(null);
    }
コード例 #7
0
        public override async Task ProcessAsync(EventContext ctx)
        {
            // if they don't have premium features, then we don't need to queue notifications
            if (!ctx.Organization.HasPremiumFeatures)
            {
                return;
            }

            // notifications are disabled or stack is hidden.
            if (ctx.Stack.DisableNotifications || ctx.Stack.IsHidden)
            {
                return;
            }

            if (ShouldQueueNotification(ctx))
            {
                await _notificationQueue.EnqueueAsync(new EventNotificationWorkItem {
                    EventId          = ctx.Event.Id,
                    IsNew            = ctx.IsNew,
                    IsRegression     = ctx.IsRegression,
                    TotalOccurrences = ctx.Stack.TotalOccurrences
                }).AnyContext();
            }

            var webHooks = await _webHookRepository.GetByOrganizationIdOrProjectIdAsync(ctx.Event.OrganizationId, ctx.Event.ProjectId).AnyContext();

            foreach (var hook in webHooks.Documents)
            {
                if (!ShouldCallWebHook(hook, ctx))
                {
                    continue;
                }

                var context      = new WebHookDataContext(hook.Version, ctx.Event, ctx.Organization, ctx.Project, ctx.Stack, ctx.IsNew, ctx.IsRegression);
                var notification = new WebHookNotification {
                    OrganizationId = ctx.Event.OrganizationId,
                    ProjectId      = ctx.Event.ProjectId,
                    WebHookId      = hook.Id,
                    Url            = hook.Url,
                    Type           = WebHookType.General,
                    Data           = await _webHookDataPluginManager.CreateFromEventAsync(context).AnyContext()
                };

                await _webHookNotificationQueue.EnqueueAsync(notification).AnyContext();

                using (_logger.BeginScope(new Dictionary <string, object> {
                    { "Web Hook Notification", notification }
                }))
                    _logger.LogTrace("Web hook queued: project={project} url={Url}", ctx.Event.ProjectId, hook.Url);
            }
        }
コード例 #8
0
    public override Task <object> CreateFromEventAsync(WebHookDataContext ctx)
    {
        if (!String.Equals(ctx.Version, Models.WebHook.KnownVersions.Version1))
        {
            return(Task.FromResult <object>(null));
        }

        var error = ctx.Event.GetError();

        if (error == null)
        {
            return(Task.FromResult <object>(null));
        }

        var requestInfo     = ctx.Event.GetRequestInfo();
        var environmentInfo = ctx.Event.GetEnvironmentInfo();

        return(Task.FromResult <object>(new VersionOneWebHookEvent(_options.BaseURL)
        {
            Id = ctx.Event.Id,
            OccurrenceDate = ctx.Event.Date,
            Tags = ctx.Event.Tags,
            MachineName = environmentInfo?.MachineName,
            RequestPath = requestInfo?.GetFullPath(),
            IpAddress = requestInfo != null ? requestInfo.ClientIpAddress : environmentInfo?.IpAddress,
            Message = error.Message,
            Type = error.Type,
            Code = error.Code,
            TargetMethod = error.TargetMethod?.GetFullName(),
            ProjectId = ctx.Event.ProjectId,
            ProjectName = ctx.Project.Name,
            OrganizationId = ctx.Event.OrganizationId,
            OrganizationName = ctx.Organization.Name,
            ErrorStackId = ctx.Event.StackId,
            ErrorStackStatus = ctx.Stack.Status,
            ErrorStackTitle = ctx.Stack.Title,
            ErrorStackDescription = ctx.Stack.Description,
            ErrorStackTags = ctx.Stack.Tags,
            TotalOccurrences = ctx.Stack.TotalOccurrences,
            FirstOccurrence = ctx.Stack.FirstOccurrence,
            LastOccurrence = ctx.Stack.LastOccurrence,
            DateFixed = ctx.Stack.DateFixed,
            IsRegression = ctx.IsRegression,
            IsNew = ctx.IsNew
        }));
    }
コード例 #9
0
    public async Task <IActionResult> PromoteAsync(string id)
    {
        if (String.IsNullOrEmpty(id))
        {
            return(NotFound());
        }

        var stack = await _stackRepository.GetByIdAsync(id);

        if (stack == null || !CanAccessOrganization(stack.OrganizationId))
        {
            return(NotFound());
        }

        if (!await _billingManager.HasPremiumFeaturesAsync(stack.OrganizationId))
        {
            return(PlanLimitReached("Promote to External is a premium feature used to promote an error stack to an external system. Please upgrade your plan to enable this feature."));
        }

        var promotedProjectHooks = (await _webHookRepository.GetByProjectIdAsync(stack.ProjectId)).Documents.Where(p => p.EventTypes.Contains(WebHookRepository.EventTypes.StackPromoted)).ToList();

        if (!promotedProjectHooks.Any())
        {
            return(NotImplemented("No promoted web hooks are configured for this project. Please add a promoted web hook to use this feature."));
        }

        foreach (var hook in promotedProjectHooks)
        {
            var context = new WebHookDataContext(hook.Version, stack, isNew: stack.TotalOccurrences == 1, isRegression: stack.Status == StackStatus.Regressed);
            await _webHookNotificationQueue.EnqueueAsync(new WebHookNotification {
                OrganizationId = stack.OrganizationId,
                ProjectId      = stack.ProjectId,
                WebHookId      = hook.Id,
                Url            = hook.Url,
                Type           = WebHookType.General,
                Data           = await _webHookDataPluginManager.CreateFromStackAsync(context)
            });
        }

        return(Ok());
    }
コード例 #10
0
        public override async Task ProcessAsync(EventContext ctx)
        {
            // if they don't have premium features, then we don't need to queue notifications
            if (!ctx.Organization.HasPremiumFeatures)
            {
                return;
            }

            if (ShouldQueueNotification(ctx))
            {
                await _notificationQueue.EnqueueAsync(new EventNotificationWorkItem {
                    EventId          = ctx.Event.Id,
                    IsNew            = ctx.IsNew,
                    IsCritical       = ctx.Event.IsCritical(),
                    IsRegression     = ctx.IsRegression,
                    TotalOccurrences = ctx.Stack.TotalOccurrences,
                    ProjectName      = ctx.Project.Name
                }).AnyContext();
            }

            foreach (WebHook hook in (await _webHookRepository.GetByOrganizationIdOrProjectIdAsync(ctx.Event.OrganizationId, ctx.Event.ProjectId).AnyContext()).Documents)
            {
                if (!ShouldCallWebHook(hook, ctx))
                {
                    continue;
                }

                var context      = new WebHookDataContext(hook.Version, ctx.Event, ctx.Organization, ctx.Project, ctx.Stack, ctx.IsNew, ctx.IsRegression);
                var notification = new WebHookNotification {
                    OrganizationId = ctx.Event.OrganizationId,
                    ProjectId      = ctx.Event.ProjectId,
                    WebHookId      = hook.Id,
                    Url            = hook.Url,
                    Data           = await _webHookDataPluginManager.CreateFromEventAsync(context).AnyContext()
                };

                await _webHookNotificationQueue.EnqueueAsync(notification).AnyContext();

                _logger.Trace().Project(ctx.Event.ProjectId).Message("Web hook queued: project={0} url={1}", ctx.Event.ProjectId, hook.Url).Property("Web Hook Notification", notification).Write();
            }
        }
コード例 #11
0
        public IHttpActionResult Promote(string id)
        {
            if (String.IsNullOrEmpty(id))
            {
                return(NotFound());
            }

            Stack stack = _stackRepository.GetById(id);

            if (stack == null || !CanAccessOrganization(stack.OrganizationId))
            {
                return(NotFound());
            }

            if (!_billingManager.HasPremiumFeatures(stack.OrganizationId))
            {
                return(PlanLimitReached("Promote to External is a premium feature used to promote an error stack to an external system. Please upgrade your plan to enable this feature."));
            }

            List <WebHook> promotedProjectHooks = _webHookRepository.GetByProjectId(stack.ProjectId).Where(p => p.EventTypes.Contains(WebHookRepository.EventTypes.StackPromoted)).ToList();

            if (!promotedProjectHooks.Any())
            {
                return(NotImplemented("No promoted web hooks are configured for this project. Please add a promoted web hook to use this feature."));
            }

            foreach (WebHook hook in promotedProjectHooks)
            {
                var context = new WebHookDataContext(hook.Version, stack, isNew: stack.TotalOccurrences == 1, isRegression: stack.IsRegressed);
                _webHookNotificationQueue.Enqueue(new WebHookNotification {
                    OrganizationId = hook.OrganizationId,
                    ProjectId      = hook.ProjectId,
                    Url            = hook.Url,
                    Data           = _webHookDataPluginManager.CreateFromStack(context)
                });
                // TODO: Add stats metrics for webhooks.
            }

            return(Ok());
        }
コード例 #12
0
        public override void Process(EventContext ctx)
        {
            // if they don't have premium features, then we don't need to queue notifications
            if (!ctx.Organization.HasPremiumFeatures)
            {
                return;
            }

            _notificationQueue.Enqueue(new EventNotification {
                Event        = ctx.Event,
                IsNew        = ctx.IsNew,
                IsCritical   = ctx.Event.IsCritical(),
                IsRegression = ctx.IsRegression,
                //TotalOccurrences = ctx.Stack.TotalOccurrences,
                ProjectName = ctx.Project.Name
            });

            foreach (WebHook hook in _webHookRepository.GetByOrganizationIdOrProjectId(ctx.Event.OrganizationId, ctx.Event.ProjectId))
            {
                bool shouldCall = hook.EventTypes.Contains(WebHookRepository.EventTypes.NewError) && ctx.IsNew ||
                                  hook.EventTypes.Contains(WebHookRepository.EventTypes.ErrorRegression) && ctx.IsRegression ||
                                  hook.EventTypes.Contains(WebHookRepository.EventTypes.CriticalError) && ctx.Event.Tags != null && ctx.Event.Tags.Contains("Critical");

                if (!shouldCall)
                {
                    continue;
                }

                Log.Trace().Project(ctx.Event.ProjectId).Message("Web hook queued: project={0} url={1}", ctx.Event.ProjectId, hook.Url).Write();

                // TODO: Should we be using the hook's project id and organization id?
                var context = new WebHookDataContext(hook.Version, ctx.Event, ctx.Organization, ctx.Project, ctx.Stack, ctx.IsNew, ctx.IsRegression);
                _webHookNotificationQueue.Enqueue(new WebHookNotification {
                    OrganizationId = ctx.Event.OrganizationId,
                    ProjectId      = ctx.Event.ProjectId,
                    Url            = hook.Url,
                    Data           = _webHookDataPluginManager.CreateFromEvent(context)
                });
            }
        }
コード例 #13
0
        public override void Process(EventContext ctx)
        {
            // if they don't have premium features, then we don't need to queue notifications
            if (!ctx.Organization.HasPremiumFeatures)
            {
                return;
            }

            if (ShouldQueueNotification(ctx))
            {
                _notificationQueue.Enqueue(new EventNotification {
                    Event            = ctx.Event,
                    IsNew            = ctx.IsNew,
                    IsCritical       = ctx.Event.IsCritical(),
                    IsRegression     = ctx.IsRegression,
                    TotalOccurrences = ctx.Stack.TotalOccurrences,
                    ProjectName      = ctx.Project.Name
                });
            }

            foreach (WebHook hook in _webHookRepository.GetByOrganizationIdOrProjectId(ctx.Event.OrganizationId, ctx.Event.ProjectId))
            {
                if (!ShouldCallWebHook(hook, ctx))
                {
                    continue;
                }

                var context = new WebHookDataContext(hook.Version, ctx.Event, ctx.Organization, ctx.Project, ctx.Stack, ctx.IsNew, ctx.IsRegression);
                _webHookNotificationQueue.Enqueue(new WebHookNotification {
                    OrganizationId = ctx.Event.OrganizationId,
                    ProjectId      = ctx.Event.ProjectId,
                    Url            = hook.Url,
                    Data           = _webHookDataPluginManager.CreateFromEvent(context)
                });

                Log.Trace().Project(ctx.Event.ProjectId).Message("Web hook queued: project={0} url={1}", ctx.Event.ProjectId, hook.Url).Write();
            }
        }
コード例 #14
0
 public abstract Task <object> CreateFromEventAsync(WebHookDataContext ctx);