public async Task ResetProjectDataAsync(string projectId) { if (String.IsNullOrEmpty(projectId)) { return; } Project project = _projectRepository.GetById(projectId); if (project == null) { return; } try { await _stackRepository.RemoveAllByProjectIdAsync(projectId); await _eventRepository.RemoveAllByProjectIdAsync(projectId); _projectRepository.Save(project); } catch (Exception e) { Log.Error().Project(projectId).Exception(e).Message("Error resetting project data.").Report().Write(); throw; } }
private void TryDeleteOrganization(Organization organization) { try { Log.Info().Message("Removing existing empty projects for the organization '{0}' with Id: '{1}'.", organization.Name, organization.Id).Write(); List <Project> projects = _projectRepository.GetByOrganizationId(organization.Id).ToList(); if (projects.Any(project => project.TotalEventCount > 0)) { Log.Info().Message("Organization '{0}' with Id: '{1}' has a project with existing data. This organization will not be deleted.", organization.Name, organization.Id).Write(); return; } foreach (Project project in projects) { Log.Info().Message("Resetting all project data for project '{0}' with Id: '{1}'.", project.Name, project.Id).Write(); _stackRepository.RemoveAllByProjectIdAsync(project.Id).Wait(); _eventRepository.RemoveAllByProjectIdAsync(project.Id).Wait(); _dayStackStats.RemoveAllByProjectIdAsync(project.Id).Wait(); _monthStackStats.RemoveAllByProjectIdAsync(project.Id).Wait(); _dayProjectStats.RemoveAllByProjectIdAsync(project.Id).Wait(); _monthProjectStats.RemoveAllByProjectIdAsync(project.Id).Wait(); } Log.Info().Message("Deleting all projects for organization '{0}' with Id: '{1}'.", organization.Name, organization.Id).Write(); _projectRepository.Remove(projects); Log.Info().Message("Removing users from organization '{0}' with Id: '{1}'.", organization.Name, organization.Id).Write(); List <User> users = _userRepository.GetByOrganizationId(organization.Id).ToList(); foreach (User user in users) { if (user.OrganizationIds.All(oid => String.Equals(oid, organization.Id))) { Log.Info().Message("Removing user '{0}' as they do not belong to any other organizations.", user.Id, organization.Name, organization.Id).Write(); _userRepository.Remove(user.Id); } else { Log.Info().Message("Removing user '{0}' from organization '{1}' with Id: '{2}'", user.Id, organization.Name, organization.Id).Write(); user.OrganizationIds.Remove(organization.Id); _userRepository.Save(user); } } Log.Info().Message("Deleting organization '{0}' with Id: '{1}'.", organization.Name, organization.Id).Write(); _organizationRepository.Remove(organization); // TODO: Send notifications that the organization and projects have been updated. } catch (Exception ex) { ex.ToExceptionless().MarkAsCritical().AddTags("Remove Stale Accounts").AddObject(organization).Submit(); } }
public override async Task HandleItemAsync(WorkItemContext context) { var wi = context.GetData <RemoveProjectWorkItem>(); using (Log.BeginScope(new ExceptionlessState().Organization(wi.OrganizationId).Project(wi.ProjectId))) { Log.LogInformation("Received remove project work item for: {0} Reset Data: {1}", wi.ProjectId, wi.Reset); await context.ReportProgressAsync(0, "Starting deletion...").AnyContext(); var project = await _projectRepository.GetByIdAsync(wi.ProjectId).AnyContext(); if (project == null) { await context.ReportProgressAsync(100, wi.Reset? "Project data reset" : "Project deleted").AnyContext(); return; } if (!wi.Reset) { await context.ReportProgressAsync(20, "Removing tokens").AnyContext(); await _tokenRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await context.ReportProgressAsync(40, "Removing web hooks").AnyContext(); await _webHookRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); } await context.ReportProgressAsync(60, "Resetting project data").AnyContext(); await _eventRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await _stackRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); if (!wi.Reset) { await context.ReportProgressAsync(80, "Removing project").AnyContext(); await _projectRepository.RemoveAsync(project.Id).AnyContext(); } await context.ReportProgressAsync(100, wi.Reset? "Project data reset" : "Project deleted").AnyContext(); } }
private async Task RemoveProjectsAsync(Project project, JobContext context) { _logger.LogInformation("Removing project: {Project} ({ProjectId})", project.Name, project.Id); await _tokenRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await _webHookRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await RenewLockAsync(context).AnyContext(); long removedEvents = await _eventRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await RenewLockAsync(context).AnyContext(); long removedStacks = await _stackRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await _projectRepository.RemoveAsync(project).AnyContext(); _logger.LogInformation("Removed project: {Project} ({ProjectId}), Removed {RemovedStacks} Stacks, {RemovedEvents} Events", project.Name, project.Id, removedStacks, removedEvents); }
private async Task RemoveProjectsAsync(Project project, JobContext context) { _logger.RemoveProjectStart(project.Name, project.Id); await _tokenRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await _webHookRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await RenewLockAsync(context).AnyContext(); long removedEvents = await _eventRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await RenewLockAsync(context).AnyContext(); long removedStacks = await _stackRepository.RemoveAllByProjectIdAsync(project.OrganizationId, project.Id).AnyContext(); await _projectRepository.RemoveAsync(project).AnyContext(); _logger.RemoveProjectComplete(project.Name, project.Id, removedStacks, removedEvents); }
public async Task ResetProjectDataAsync(string projectId) { if (String.IsNullOrEmpty(projectId)) { return; } Project project = _projectRepository.GetById(projectId); if (project == null) { return; } try { await _stackRepository.RemoveAllByProjectIdAsync(projectId); await _eventRepository.RemoveAllByProjectIdAsync(projectId); await _dayStackStats.RemoveAllByProjectIdAsync(projectId); await _monthStackStats.RemoveAllByProjectIdAsync(projectId); await _dayProjectStats.RemoveAllByProjectIdAsync(projectId); await _monthProjectStats.RemoveAllByProjectIdAsync(projectId); project.EventCount = 0; project.StackCount = 0; _projectRepository.Save(project); var orgProjects = _projectRepository.GetByOrganizationId(project.OrganizationId); Organization organization = _organizationRepository.GetById(project.OrganizationId); organization.EventCount = orgProjects.Sum(p => p.EventCount); organization.StackCount = orgProjects.Sum(p => p.StackCount); _organizationRepository.Save(organization); } catch (Exception e) { Log.Error().Project(projectId).Exception(e).Message("Error resetting project data.").Report().Write(); throw; } }
public void CanRunAsyncMethodsAndWait() { string taskId = Guid.NewGuid().ToString("N"); //_cacheClient.Set(taskId, 0); string id = "51cf1b597841550f1c44b539"; var tasks = new[] { _stackRepository.RemoveAllByProjectIdAsync(id), _eventRepository.RemoveAllByProjectIdAsync(id), _dayStackStats.RemoveAllByProjectIdAsync(id), _monthStackStats.RemoveAllByProjectIdAsync(id), _dayProjectStats.RemoveAllByProjectIdAsync(id), _monthProjectStats.RemoveAllByProjectIdAsync(id) }; try { Task.WaitAll(tasks); // wait 2 minutes after completed and then remove the task id //Task.Factory.StartNewDelayed(2 * 60 * 1000, () => _cacheClient.Remove(taskId)); } catch (Exception) { //Log.Error().Project(id).Exception(e).Message("Error resetting project data.").Report().Write(); } }
public override async Task HandleItemAsync(WorkItemContext context) { var wi = context.GetData <RemoveOrganizationWorkItem>(); using (Log.BeginScope(new ExceptionlessState().Organization(wi.OrganizationId))) { Log.LogInformation("Received remove organization work item for: {organization}", wi.OrganizationId); await context.ReportProgressAsync(0, "Starting deletion...").AnyContext(); var organization = await _organizationRepository.GetByIdAsync(wi.OrganizationId).AnyContext(); if (organization == null) { await context.ReportProgressAsync(100, "Organization deleted").AnyContext(); return; } await context.ReportProgressAsync(10, "Removing subscriptions").AnyContext(); if (!String.IsNullOrEmpty(organization.StripeCustomerId)) { Log.LogInformation("Canceling stripe subscription for the organization {OrganizationName} with Id: {organization}.", organization.Name, organization.Id); var client = new StripeClient(_stripeOptions.Value.StripeApiKey); var subscriptionService = new SubscriptionService(client); var subscriptions = (await subscriptionService.ListAsync(new SubscriptionListOptions { Customer = organization.StripeCustomerId }).AnyContext()).Where(s => !s.CanceledAt.HasValue); foreach (var subscription in subscriptions) { await subscriptionService.CancelAsync(subscription.Id, new SubscriptionCancelOptions()).AnyContext(); } } await context.ReportProgressAsync(20, "Removing users").AnyContext(); var users = await _userRepository.GetByOrganizationIdAsync(organization.Id).AnyContext(); foreach (var user in users.Documents) { // delete the user if they are not associated to any other organizations and they are not the current user if (user.OrganizationIds.All(oid => String.Equals(oid, organization.Id)) && !String.Equals(user.Id, wi.CurrentUserId)) { Log.LogInformation("Removing user {user} as they do not belong to any other organizations.", user.Id); await _userRepository.RemoveAsync(user.Id).AnyContext(); } else { Log.LogInformation("Removing user {user} from organization {OrganizationName} with Id: {organization}", user.Id, organization.Name, organization.Id); user.OrganizationIds.Remove(organization.Id); await _userRepository.SaveAsync(user, o => o.Cache()).AnyContext(); } } await context.ReportProgressAsync(30, "Removing tokens").AnyContext(); await _tokenRepository.RemoveAllByOrganizationIdAsync(organization.Id).AnyContext(); await context.ReportProgressAsync(40, "Removing web hooks").AnyContext(); await _webHookRepository.RemoveAllByOrganizationIdAsync(organization.Id).AnyContext(); await context.ReportProgressAsync(50, "Removing projects").AnyContext(); var projects = await _projectRepository.GetByOrganizationIdAsync(organization.Id).AnyContext(); if (wi.IsGlobalAdmin && projects.Total > 0) { int completed = 1; foreach (var project in projects.Documents) { using (Log.BeginScope(new ExceptionlessState().Organization(wi.OrganizationId).Project(project.Id))) { Log.LogInformation("Resetting all project data for project {ProjectName} with Id: {project}.", project.Name, project.Id); await _eventRepository.RemoveAllByProjectIdAsync(organization.Id, project.Id).AnyContext(); await _stackRepository.RemoveAllByProjectIdAsync(organization.Id, project.Id).AnyContext(); await context.ReportProgressAsync(CalculateProgress(projects.Total, completed++, 51, 89), "Removing projects...").AnyContext(); } } Log.LogInformation("Deleting all projects for organization {OrganizationName} with Id: {organization}.", organization.Name, organization.Id); await _projectRepository.RemoveAsync(projects.Documents).AnyContext(); } Log.LogInformation("Deleting organization {OrganizationName} with Id: {organization}.", organization.Name, organization.Id); await context.ReportProgressAsync(90, "Removing organization").AnyContext(); await _organizationRepository.RemoveAsync(organization.Id).AnyContext(); await context.ReportProgressAsync(100, "Organization deleted").AnyContext(); } }
public override async Task HandleItemAsync(WorkItemContext context) { var workItem = context.GetData <RemoveOrganizationWorkItem>(); Log.Info("Received remove organization work item for: {0}", workItem.OrganizationId); await context.ReportProgressAsync(0, "Starting deletion...").AnyContext(); var organization = await _organizationRepository.GetByIdAsync(workItem.OrganizationId).AnyContext(); if (organization == null) { await context.ReportProgressAsync(100, "Organization deleted").AnyContext(); return; } await context.ReportProgressAsync(10, "Removing subscriptions").AnyContext(); if (!String.IsNullOrEmpty(organization.StripeCustomerId)) { Log.Info("Canceling stripe subscription for the organization '{0}' with Id: '{1}'.", organization.Name, organization.Id); var subscriptionService = new StripeSubscriptionService(Settings.Current.StripeApiKey); var subscriptions = subscriptionService.List(organization.StripeCustomerId).Where(s => !s.CanceledAt.HasValue); foreach (var subscription in subscriptions) { subscriptionService.Cancel(organization.StripeCustomerId, subscription.Id); } } await context.ReportProgressAsync(20, "Removing users").AnyContext(); var users = await _userRepository.GetByOrganizationIdAsync(organization.Id).AnyContext(); foreach (User user in users.Documents) { // delete the user if they are not associated to any other organizations and they are not the current user if (user.OrganizationIds.All(oid => String.Equals(oid, organization.Id)) && !String.Equals(user.Id, workItem.CurrentUserId)) { Log.Info("Removing user '{0}' as they do not belong to any other organizations.", user.Id, organization.Name, organization.Id); await _userRepository.RemoveAsync(user.Id).AnyContext(); } else { Log.Info("Removing user '{0}' from organization '{1}' with Id: '{2}'", user.Id, organization.Name, organization.Id); user.OrganizationIds.Remove(organization.Id); await _userRepository.SaveAsync(user, true).AnyContext(); } } await context.ReportProgressAsync(30, "Removing tokens").AnyContext(); await _tokenRepository.RemoveAllByOrganizationIdAsync(organization.Id).AnyContext(); await context.ReportProgressAsync(40, "Removing web hooks").AnyContext(); await _webHookRepository.RemoveAllByOrganizationIdAsync(organization.Id).AnyContext(); await context.ReportProgressAsync(50, "Removing projects").AnyContext(); var projects = await _projectRepository.GetByOrganizationIdAsync(organization.Id).AnyContext(); if (workItem.IsGlobalAdmin && projects.Total > 0) { var completed = 1; foreach (Project project in projects.Documents) { Log.Info("Resetting all project data for project '{0}' with Id: '{1}'.", project.Name, project.Id); await _eventRepository.RemoveAllByProjectIdAsync(organization.Id, project.Id).AnyContext(); await _stackRepository.RemoveAllByProjectIdAsync(organization.Id, project.Id).AnyContext(); await context.ReportProgressAsync(CalculateProgress(projects.Total, completed++, 51, 89), "Removing projects...").AnyContext(); } Log.Info("Deleting all projects for organization '{0}' with Id: '{1}'.", organization.Name, organization.Id); await _projectRepository.RemoveAsync(projects.Documents).AnyContext(); } Log.Info("Deleting organization '{0}' with Id: '{1}'.", organization.Name, organization.Id); await context.ReportProgressAsync(90, "Removing organization").AnyContext(); await _organizationRepository.RemoveAsync(organization.Id).AnyContext(); await context.ReportProgressAsync(100, "Organization deleted").AnyContext(); }