public async Task ResetStackDataAsync(string stackId) { if (String.IsNullOrEmpty(stackId)) { return; } Stack stack = _stackRepository.GetById(stackId); if (stack == null) { return; } try { stack.TotalOccurrences = 0; stack.LastOccurrence = DateTime.MinValue.ToUniversalTime(); stack.FirstOccurrence = DateTime.MinValue.ToUniversalTime(); _stackRepository.Save(stack); await _eventRepository.RemoveAllByStackIdsAsync(new[] { stackId }); } catch (Exception e) { Log.Error().Project(stack.ProjectId).Exception(e).Message("Error resetting stack data.").Write(); throw; } }
public void EnsureSingleRegression() { var pipeline = IoC.GetInstance <EventPipeline>(); var client = IoC.GetInstance <IElasticClient>(); PersistentEvent ev = EventData.GenerateEvent(projectId: TestConstants.ProjectId, organizationId: TestConstants.OrganizationId, occurrenceDate: DateTime.UtcNow); var context = new EventContext(ev); Assert.DoesNotThrow(() => pipeline.Run(context)); Assert.True(context.IsProcessed); Assert.False(context.IsRegression); client.Refresh(); ev = _eventRepository.GetById(ev.Id); Assert.NotNull(ev); var stack = _stackRepository.GetById(ev.StackId); stack.DateFixed = DateTime.UtcNow; stack.IsRegressed = false; _stackRepository.Save(stack, true); ev = EventData.GenerateEvent(stackId: ev.StackId, projectId: TestConstants.ProjectId, organizationId: TestConstants.OrganizationId, occurrenceDate: DateTime.UtcNow.AddMinutes(1)); context = new EventContext(ev); Assert.DoesNotThrow(() => pipeline.Run(context)); Assert.True(context.IsRegression); ev = EventData.GenerateEvent(stackId: ev.StackId, projectId: TestConstants.ProjectId, organizationId: TestConstants.OrganizationId, occurrenceDate: DateTime.UtcNow.AddMinutes(1)); context = new EventContext(ev); Assert.DoesNotThrow(() => pipeline.Run(context)); Assert.False(context.IsRegression); }
public ActionResult MarkFixed(string id) { // TODO: We should probably be setting error notifications when the stack is not found. if (String.IsNullOrEmpty(id)) { return(RedirectToAction("Index", "Project")); } Stack stack = _repository.GetById(id); if (stack == null || !CanAccessOrganization(stack.OrganizationId)) { return(RedirectToAction("Index", "Project")); } stack.DateFixed = DateTime.UtcNow; //stack.FixedInVersion = ""; // TODO: Implement this. stack.IsRegressed = false; // TODO: Add a log entry. _repository.Save(stack); return(RedirectToAction("Index", "Stack", new { id = stack.Id, notification = "mark-fixed" })); }
public void CanCreateUpdateRemove() { _repository.RemoveAll(); Assert.Equal(0, _repository.Count()); var stack = StackData.GenerateStack(projectId: TestConstants.ProjectId, organizationId: TestConstants.OrganizationId); Assert.Null(stack.Id); _repository.Add(stack); Assert.NotNull(stack.Id); _client.Refresh(); stack = _repository.GetById(stack.Id); Assert.NotNull(stack); stack.Description = "New Description"; _repository.Save(stack); _repository.Remove(stack.Id); }
public override void Process(EventContext ctx) { if (String.IsNullOrEmpty(ctx.Event.StackId)) { if (_stackRepository == null) { throw new InvalidOperationException("You must pass a non-null stackRepository parameter to the constructor."); } // only add default signature info if no other signature info has been added if (ctx.StackSignatureData.Count == 0) { ctx.StackSignatureData.Add("Type", ctx.Event.Type); if (!String.IsNullOrEmpty(ctx.Event.Source)) { ctx.StackSignatureData.Add("Source", ctx.Event.Source); } } string signatureHash = ctx.StackSignatureData.Values.Any(v => v != null) ? ctx.StackSignatureData.Values.ToSHA1() : null; ctx.SetProperty("__SignatureHash", signatureHash); ctx.Stack = _stackRepository.GetStackBySignatureHash(ctx.Event.ProjectId, signatureHash); if (ctx.Stack == null) { Log.Trace().Message("Creating new error stack.").Write(); ctx.IsNew = true; ctx.Event.IsFirstOccurrence = true; string title = _formattingPluginManager.GetStackTitle(ctx.Event); var stack = new Stack { OrganizationId = ctx.Event.OrganizationId, ProjectId = ctx.Event.ProjectId, SignatureInfo = new SettingsDictionary(ctx.StackSignatureData), SignatureHash = signatureHash, Title = title != null?title.Truncate(1000) : null, Tags = ctx.Event.Tags ?? new TagSet(), Type = ctx.Event.Type, TotalOccurrences = 1, FirstOccurrence = ctx.Event.Date.UtcDateTime, LastOccurrence = ctx.Event.Date.UtcDateTime }; ctx.Stack = _stackRepository.Add(stack, true); } Log.Trace().Message("Updating error's ErrorStackId to: {0}", ctx.Stack.Id).Write(); ctx.Event.StackId = ctx.Stack.Id; } else { ctx.Stack = _stackRepository.GetById(ctx.Event.StackId, true); if (ctx.Stack == null || ctx.Stack.ProjectId != ctx.Event.ProjectId) { throw new ApplicationException("Invalid StackId."); } ctx.SetProperty("__SignatureHash", ctx.Stack.SignatureHash); } if (!ctx.IsNew && ctx.Event.Tags != null && ctx.Event.Tags.Count > 0) { if (ctx.Stack.Tags == null) { ctx.Stack.Tags = new TagSet(); } List <string> newTags = ctx.Event.Tags.Where(t => !ctx.Stack.Tags.Contains(t)).ToList(); if (newTags.Count > 0) { ctx.Stack.Tags.AddRange(newTags); _stackRepository.Save(ctx.Stack, true); } } // sync the fixed and hidden flags to the error occurrence ctx.Event.IsFixed = ctx.Stack.DateFixed.HasValue; ctx.Event.IsHidden = ctx.Stack.IsHidden; }
public override void ProcessBatch(ICollection <EventContext> contexts) { var stacks = new Dictionary <string, Tuple <bool, Stack> >(); foreach (var ctx in contexts) { if (String.IsNullOrEmpty(ctx.Event.StackId)) { // only add default signature info if no other signature info has been added if (ctx.StackSignatureData.Count == 0) { ctx.StackSignatureData.Add("Type", ctx.Event.Type); if (!String.IsNullOrEmpty(ctx.Event.Source)) { ctx.StackSignatureData.Add("Source", ctx.Event.Source); } } string signatureHash = ctx.StackSignatureData.Values.ToSHA1(); ctx.SignatureHash = signatureHash; Tuple <bool, Stack> value; if (stacks.TryGetValue(signatureHash, out value)) { ctx.Stack = value.Item2; } else { ctx.Stack = _stackRepository.GetStackBySignatureHash(ctx.Event.ProjectId, signatureHash); if (ctx.Stack != null) { stacks.Add(signatureHash, Tuple.Create(false, ctx.Stack)); } } if (ctx.Stack == null) { Log.Trace().Message("Creating new event stack.").Write(); ctx.IsNew = true; string title = _formattingPluginManager.GetStackTitle(ctx.Event); var stack = new Stack { OrganizationId = ctx.Event.OrganizationId, ProjectId = ctx.Event.ProjectId, SignatureInfo = new SettingsDictionary(ctx.StackSignatureData), SignatureHash = signatureHash, Title = title != null?title.Truncate(1000) : null, Tags = ctx.Event.Tags ?? new TagSet(), Type = ctx.Event.Type, TotalOccurrences = 1, FirstOccurrence = ctx.Event.Date.UtcDateTime, LastOccurrence = ctx.Event.Date.UtcDateTime }; ctx.Stack = stack; stacks.Add(signatureHash, Tuple.Create(true, ctx.Stack)); } } else { ctx.Stack = _stackRepository.GetById(ctx.Event.StackId, true); if (ctx.Stack == null || ctx.Stack.ProjectId != ctx.Event.ProjectId) { ctx.SetError("Invalid StackId."); continue; } ctx.SignatureHash = ctx.Stack.SignatureHash; if (!stacks.ContainsKey(ctx.Stack.SignatureHash)) { stacks.Add(ctx.Stack.SignatureHash, Tuple.Create(false, ctx.Stack)); } else { stacks[ctx.Stack.SignatureHash] = Tuple.Create(false, ctx.Stack); } } if (!ctx.IsNew && ctx.Event.Tags != null && ctx.Event.Tags.Count > 0) { if (ctx.Stack.Tags == null) { ctx.Stack.Tags = new TagSet(); } List <string> newTags = ctx.Event.Tags.Where(t => !ctx.Stack.Tags.Contains(t)).ToList(); if (newTags.Count > 0) { ctx.Stack.Tags.AddRange(newTags); // make sure the stack gets saved if (!stacks.ContainsKey(ctx.Stack.SignatureHash)) { stacks.Add(ctx.Stack.SignatureHash, Tuple.Create(true, ctx.Stack)); } else { stacks[ctx.Stack.SignatureHash] = Tuple.Create(true, stacks[ctx.Stack.SignatureHash].Item2); } } } ctx.Event.IsFirstOccurrence = ctx.IsNew; // sync the fixed and hidden flags to the error occurrence ctx.Event.IsFixed = ctx.Stack.DateFixed.HasValue; ctx.Event.IsHidden = ctx.Stack.IsHidden; } var stacksToAdd = stacks.Where(kvp => kvp.Value.Item1 && String.IsNullOrEmpty(kvp.Value.Item2.Id)).Select(kvp => kvp.Value.Item2).ToList(); if (stacksToAdd.Count > 0) { _stackRepository.Add(stacksToAdd, true, sendNotification: stacksToAdd.Count == 1); if (stacksToAdd.Count > 1) { _publisher.Publish(new EntityChanged { ChangeType = ChangeType.Added, Type = typeof(Stack).Name, OrganizationId = contexts.First().Organization.Id, ProjectId = contexts.First().Project.Id }); } } var stacksToSave = stacks.Where(kvp => kvp.Value.Item1 && !String.IsNullOrEmpty(kvp.Value.Item2.Id)).Select(kvp => kvp.Value.Item2).ToList(); if (stacksToSave.Count > 0) { _stackRepository.Save(stacksToSave, true, sendNotification: false); // notification will get sent later in the update stats step } // Set stack ids after they have been saved and created contexts.ForEach(ctx => { ctx.Event.StackId = ctx.Stack != null ? ctx.Stack.Id : null; }); }
public override void Process(EventContext ctx) { if (String.IsNullOrEmpty(ctx.Event.StackId)) { if (_stackRepository == null) { throw new InvalidOperationException("You must pass a non-null stackRepository parameter to the constructor."); } // only add default signature info if no other signature info has been added if (ctx.StackSignatureData.Count == 0) { ctx.StackSignatureData.Add("Type", ctx.Event.Type); if (!String.IsNullOrEmpty(ctx.Event.Source)) { ctx.StackSignatureData.Add("Source", ctx.Event.Source); } } string signatureHash = ctx.StackSignatureData.Values.Any(v => v != null) ? ctx.StackSignatureData.Values.ToSHA1() : null; ctx.SetProperty("__SignatureHash", signatureHash); ctx.Event.SummaryHtml = _pluginManager.GetEventSummaryHtml(ctx.Event); ctx.StackInfo = _stackRepository.GetStackInfoBySignatureHash(ctx.Event.ProjectId, signatureHash); if (ctx.StackInfo == null) { Log.Trace().Message("Creating new error stack.").Write(); ctx.IsNew = true; var stack = new Stack { OrganizationId = ctx.Event.OrganizationId, ProjectId = ctx.Event.ProjectId, SignatureInfo = new SettingsDictionary(ctx.StackSignatureData), SignatureHash = signatureHash, Title = _pluginManager.GetStackTitle(ctx.Event), SummaryHtml = _pluginManager.GetStackSummaryHtml(ctx.Event), Tags = ctx.Event.Tags ?? new TagSet(), TotalOccurrences = 1, FirstOccurrence = ctx.Event.Date.UtcDateTime, LastOccurrence = ctx.Event.Date.UtcDateTime }; ctx.Stack = _stackRepository.Add(stack, true); ctx.StackInfo = new StackInfo { Id = stack.Id, DateFixed = stack.DateFixed, OccurrencesAreCritical = stack.OccurrencesAreCritical }; // new 404 stack id added, invalidate 404 id cache if (ctx.Event.IsNotFound) { _stackRepository.InvalidateNotFoundIdsCache(ctx.Event.ProjectId); } } Log.Trace().Message("Updating error's ErrorStackId to: {0}", ctx.StackInfo.Id).Write(); ctx.Event.StackId = ctx.StackInfo.Id; } else { ctx.Stack = _stackRepository.GetById(ctx.Event.StackId); // TODO: Update unit tests to work with this check. //if (stack == null || stack.ProjectId != error.ProjectId) // throw new InvalidOperationException("Invalid ErrorStackId."); if (ctx.Stack == null) { return; } if (ctx.Event.Tags != null && ctx.Event.Tags.Count > 0) { if (ctx.Stack.Tags == null) { ctx.Stack.Tags = new TagSet(); } List <string> newTags = ctx.Event.Tags.Where(t => !ctx.Stack.Tags.Contains(t)).ToList(); if (newTags.Count > 0) { ctx.Stack.Tags.AddRange(newTags); _stackRepository.Save(ctx.Stack); } } ctx.StackInfo = new StackInfo { Id = ctx.Stack.Id, DateFixed = ctx.Stack.DateFixed, OccurrencesAreCritical = ctx.Stack.OccurrencesAreCritical, IsHidden = ctx.Stack.IsHidden }; } // sync the fixed and hidden flags to the error occurrence ctx.Event.IsFixed = ctx.StackInfo.DateFixed.HasValue; ctx.Event.IsHidden = ctx.StackInfo.IsHidden; }