public async Task <Result> Handle(Command message, CancellationToken cancellationToken) { using (var unit = await _context.Database.BeginTransactionAsync(cancellationToken)) { var jobId = await _context.Jobs .Where(x => x.Jid == message.Jid) .Select(x => (Guid?)x.Id) .SingleOrDefaultAsync(cancellationToken); var jobExists = jobId != null; if (!jobExists) { Logger.Trace($"Job with a jid {message.Jid} has never been seen, it will be recorded."); var job = new Job { Jid = message.Jid, Arguments = message.Arguments, Function = message.Function }; _context.Jobs.Add(job); await _context.SaveChangesAsync(cancellationToken); jobId = job.Id; } unit.Commit(); return(new Result { JobId = jobId.Value }); } }
public async Task ProcessEvent(Command message) { Logger.Trace($"Processing job created event for jid {message.Jid}."); var job = await _mediator.Send(new JobSeen.Command { Jid = message.Jid, Function = message.Data.Function, Arguments = message.Data.Arguments }); using (var unit = await _context.Database.BeginTransactionAsync()) { var creationEvent = new JobCreationEvent { JobId = job.JobId, Minions = message.Data.Minions, MissingMinions = message.Data.Missing, Targets = message.Data.Target, TargetType = message.Data.TargetType, User = message.Data.User, Timestamp = message.Data.Timestamp }; _context.JobCreationEvents.Add(creationEvent); await _context.SaveChangesAsync(); unit.Commit(); } Logger.Info($"Job {message.Jid} was committed."); }
public async Task <Result> Handle(Command message, CancellationToken cancellationToken) { Logger.Warn($"Got unknown tag {message.Tag} with {message.Data}."); _context.UnknownEvents.Add(new UnknownEvent { Data = message.Data, Tag = message.Tag }); await _context.SaveChangesAsync(cancellationToken); return(new Result()); }
public async Task <Result> Handle(Command message, CancellationToken cancellationToken) { Logger.Info($"Attempting to update server settings with {message.Settings.Count} values."); var existingSettings = message.Settings.Values .Where(x => x.Version.HasValue) .Select(x => new ServerSetting { Key = x.Key.ToLower(), Value = x.Value, Version = x.Version ?? 0, LastUpdated = DateTimeOffset.Now }) .ToList(); var newSettings = message.Settings.Values .Where(x => !x.Version.HasValue) .Select(x => new ServerSetting { Key = x.Key.ToLower(), Value = x.Value, LastUpdated = DateTimeOffset.Now }) .ToList(); using (var unit = await _context.Database.BeginTransactionAsync(cancellationToken)) { _context.ServerSettings.AttachRange(existingSettings); foreach (var existingSetting in existingSettings) { _context.Entry(existingSetting).Property(x => x.Value).IsModified = true; _context.Entry(existingSetting).Property(x => x.LastUpdated).IsModified = true; _context.Entry(existingSetting).Property(x => x.Version).IsModified = false; } _context.ServerSettings.AddRange(newSettings); await _context.SaveChangesAsync(cancellationToken); await _notify.Notify(ChannelConstants.ConfigurationChangedChannel, cancellationToken); unit.Commit(); } Logger.Info($"Successfully updated server settings, {existingSettings.Count} values updated, {newSettings.Count} values added."); return(new Result()); }
public async Task <Result> Handle(Command message, CancellationToken cancellationToken) { using (var unit = await _context.Database.BeginTransactionAsync(cancellationToken)) { var task = new AdHocTask { Tag = message.Tag, Metadata = new Dictionary <string, string> { { "jid", message.Jid }, { "minions", string.Join(",", message.Minions) } }, StartedOn = DateTimeOffset.Now, Status = BackgroundTaskStatus.Queued }; _context.AdHocTasks.Add(task); await _context.SaveChangesAsync(cancellationToken); var taskId = task.Id; Logger.Info($"Queuing monitoring of job {message.Jid}'s execution, tracking with task {taskId}."); _jobClient.Enqueue <Handler>(x => x.Process(message, taskId)); unit.Commit(); await _mediator.PublishEvent($"v1:tasks:{taskId}:new", ("taskId", taskId.ToString()) ); return(new Result { TaskId = taskId }); } }
public async Task ProcessEvent(Command message) { Logger.Info($"Processing authentication event for minion {message.Slug}."); var minionSeenResult = await _mediator.Send(new MinionSeen.Command { Slug = message.Slug, Timestamp = message.Timestamp }); var publicKeyHash = GetPublicKeyFingerprint(message.PublicKey); Logger.Debug($"Found public key fingerprint to be {publicKeyHash}."); using (var unit = await _context.Database.BeginTransactionAsync()) { var minion = await _context.Minions.FindAsync(minionSeenResult.MinionId); minion.LastAuthentication = message.Timestamp; var authEvent = new MinionAuthenticationEvent { MinionId = minion.Id, Action = message.Action, PublicKey = message.PublicKey, PublicKeyHash = publicKeyHash, Success = message.Success, Timestamp = message.Timestamp }; _context.MinionAuthenticationEvents.Add(authEvent); await _context.SaveChangesAsync(); unit.Commit(); } await _mediator.PublishEvent( $"v1:minions:{message.Slug}:authenticated", ("minionId", message.Slug) ); Logger.Info("Processing authentication event for minion completed."); }
public async Task <Result> Handle(Command message, CancellationToken cancellationToken) { Logger.Trace($"Minion {message.Slug} seen at {message.Timestamp}."); using (var unit = await _context.Database.BeginTransactionAsync(cancellationToken)) { var minion = await _context.Minions .SingleOrDefaultAsync(x => x.MinionSlug == message.Slug, cancellationToken); var minionDiscovered = minion == null; if (minionDiscovered) { Logger.Info($"Minion {message.Slug} is unknown, it will be recorded."); minion = new Minion { MinionSlug = message.Slug }; _context.Minions.Add(minion); } minion.LastSeen = message.Timestamp; await _context.SaveChangesAsync(cancellationToken); unit.Commit(); if (minionDiscovered) { await _mediator.Publish(new MinionDiscovered.Notification { MinionSlug = message.Slug }, cancellationToken); } return(new Result { MinionId = minion.Id }); } }
public async Task Process() { Logger.Info("Processing cleanup of grain generations."); using (var unit = await _context.Database.BeginTransactionAsync()) { var grainIds = await(from grain in _context.MinionGrains from minion in _context.Minions.Where(x => x.GrainGeneration == grain.Generation).DefaultIfEmpty() where minion == null select grain.Id).ToListAsync(); var grains = grainIds.Select(x => new MinionGrain { Id = x }); _context.MinionGrains.RemoveRange(grains); await _context.SaveChangesAsync(); unit.Commit(); Logger.Info($"Removed {grainIds.Count} grains from old generations."); } }
public async Task Process(JobReturnSaved.Notification notification) { Logger.Info($"Processing grains return for {notification.MinionReturnEventId}."); using (var unit = await _context.Database.BeginTransactionAsync()) { var bulk = await(from returnEvent in _context.MinionReturnEvents.Where(x => x.Id == notification.MinionReturnEventId) let m = returnEvent.Minion select new { ReturnEvent = returnEvent, MinionId = m.Id, m.MinionSlug, MinionVersion = m.Version, MinionLastGrainRefresh = m.LastGrainRefresh }).SingleOrDefaultAsync(); var grainsAreStale = bulk.MinionLastGrainRefresh >= bulk.ReturnEvent.Timestamp; if (grainsAreStale) { Logger.Info("Grain data is more stale than existing grain data, will ignore return event."); return; } var minion = new Minion { Id = bulk.MinionId, Version = bulk.MinionVersion }; _context.Attach(minion); var generation = Guid.NewGuid(); var grainsJson = bulk.ReturnEvent.ReturnData; var grains = _jsonFlattener.Flatten(grainsJson); var minionGrains = grains.Select(x => new MinionGrain { MinionId = bulk.MinionId, Generation = generation, Path = x.Key, Values = x.Value.ToList(), Timestamp = bulk.ReturnEvent.Timestamp }).ToList(); var minionGrainValues = minionGrains.Select( g => g.Values.Select(x => new MinionGrainValue { MinionGrain = g, Value = x }) ).SelectMany(x => x); _context.MinionGrains.AddRange(minionGrains); _context.MinionGrainValues.AddRange(minionGrainValues); minion.GrainGeneration = generation; minion.LastGrainRefresh = bulk.ReturnEvent.Timestamp; await _context.SaveChangesAsync(); unit.Commit(); Logger.Debug($"Commited {grains.Count} grains under generation {generation}."); await _mediator.PublishEvent( $"v1:minions:{bulk.MinionSlug}:grains:updated", ("minionId", bulk.MinionSlug) ); } }