private async Task OnMessageReceived(object sender, MessageEventArgs e) { using (Stream stream = e.Message.GetData().Result) { string to = string.Join(", ", e.Message.Recipients); Console.WriteLine($"Message received. Client address {e.Message.Session.ClientAddress}. From {e.Message.From}. To {to}."); Message message = new MessageConverter().ConvertAsync(stream, e.Message.From, to).Result; message.IsUnread = true; await taskQueue.QueueTask(() => { Console.WriteLine("Processing received message"); Smtp4devDbContext dbContext = dbContextFactory(); Dictionary <MailboxAddress, Exception> relayErrors = TryRelayMessage(message, null); message.RelayError = string.Join("\n", relayErrors.Select(e => e.Key.ToString() + ": " + e.Value.Message)); Session dbSession = dbContext.Sessions.Find(activeSessionsToDbId[e.Message.Session]); message.Session = dbSession; dbContext.Messages.Add(message); dbContext.SaveChanges(); TrimMessages(dbContext); dbContext.SaveChanges(); notificationsHub.OnMessagesChanged().Wait(); Console.WriteLine("Processing received message DONE"); }, false).ConfigureAwait(false); } }
private async Task OnMessageReceived(object sender, MessageEventArgs e) { using (Stream stream = e.Message.GetData().Result) { string to = string.Join(", ", e.Message.Recipients); Console.WriteLine($"Message received. Client address {e.Message.Session.ClientAddress}. From {e.Message.From}. To {to}."); Message message = new MessageConverter().ConvertAsync(stream, e.Message.From, to).Result; message.IsUnread = true; await QueueTask(() => { Console.WriteLine("Processing received message"); Smtp4devDbContext dbContext = dbContextFactory(); Session dbSession = dbContext.Sessions.Find(activeSessionsToDbId[e.Message.Session]); message.Session = dbSession; dbContext.Messages.Add(message); dbContext.SaveChanges(); Smtp4devServer.TrimMessages(dbContext, serverOptions.Value); dbContext.SaveChanges(); messagesHub.OnMessagesChanged().Wait(); Console.WriteLine("Processing received message DONE"); }, false).ConfigureAwait(false); } }
private async Task OnMessageReceived(object sender, MessageEventArgs e) { Message message = new MessageConverter().ConvertAsync(e.Message).Result; Console.WriteLine($"Message received. Client address {e.Message.Session.ClientAddress}. From {e.Message.From}. To {message.To}."); message.IsUnread = true; await taskQueue.QueueTask(() => { Console.WriteLine("Processing received message"); using var scope = serviceScopeFactory.CreateScope(); Smtp4devDbContext dbContext = scope.ServiceProvider.GetService <Smtp4devDbContext>(); Dictionary <MailboxAddress, Exception> relayErrors = TryRelayMessage(message, null); message.RelayError = string.Join("\n", relayErrors.Select(e => e.Key.ToString() + ": " + e.Value.Message)); ImapState imapState = dbContext.ImapState.Single(); imapState.LastUid = Math.Max(0, imapState.LastUid + 1); message.ImapUid = imapState.LastUid; message.Session = dbContext.Sessions.Find(activeSessionsToDbId[e.Message.Session]); dbContext.Messages.Add(message); dbContext.SaveChanges(); TrimMessages(dbContext); dbContext.SaveChanges(); notificationsHub.OnMessagesChanged().Wait(); Console.WriteLine("Processing received message DONE"); }, false).ConfigureAwait(false); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory log) { ServerOptions serverOptions = Configuration.GetSection("ServerOptions").Get <ServerOptions>(); Action <IApplicationBuilder> configure = subdir => { subdir.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = new JsonExceptionMiddleware().Invoke }); subdir.UseDefaultFiles(); if (env.IsDevelopment()) { subdir.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { HotModuleReplacement = true }); } subdir.UseStaticFiles(); subdir.UseWebSockets(); subdir.UseSignalR(routes => { routes.MapHub <MessagesHub>("/hubs/messages"); routes.MapHub <SessionsHub>("/hubs/sessions"); }); subdir.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); routes.MapSpaFallbackRoute( name: "spa-fallback", defaults: new { controller = "Home", action = "Index" }); }); Smtp4devDbContext context = subdir.ApplicationServices.GetService <Smtp4devDbContext>(); if (!context.Database.IsInMemory()) { context.Database.Migrate(); } subdir.ApplicationServices.GetService <Smtp4devServer>().Start(); }; if (!string.IsNullOrEmpty(serverOptions.RootUrl)) { app.Map(serverOptions.RootUrl, configure); } else { configure(app); } }
public void Start() { Smtp4devDbContext dbContent = dbContextFactory(); foreach (Session unfinishedSession in dbContent.Sessions.Where(s => !s.EndDate.HasValue).ToArray()) { unfinishedSession.EndDate = DateTime.Now; } dbContent.SaveChanges(); TrimMessages(dbContent, serverOptions.Value); dbContent.SaveChanges(); TrimSessions(dbContent, serverOptions.Value); dbContent.SaveChanges(); messagesHub.OnMessagesChanged().Wait(); sessionsHub.OnSessionsChanged().Wait(); processingQueue = new BlockingCollection <Action>(); priorityProcessingQueue = new BlockingCollection <Action>(); Task.Run(ProcessingTaskWork); smtpServer.Start(); Console.WriteLine($"SMTP Server is listening on port {smtpServer.PortNumber}.\nKeeping last {serverOptions.Value.NumberOfMessagesToKeep} messages and {serverOptions.Value.NumberOfSessionsToKeep} sessions."); }
public void DatesAreStoredInUtcAndKindIsSetOnRetrieval() { var timeZone = GetTestTimezone(); var testDate = new DateTime(2021, 1, 4, 10, 0, 0, DateTimeKind.Utc); using (new FakeLocalTimeZone(GetTimeZoneInfo(timeZone))) { using (var context = new Smtp4devDbContext(_sqlLiteForTesting.ContextOptions)) { context.Messages.Add(new Message { From = "test" }); context.SaveChanges(); //manually set time so we don't go through any EF converts. var sql = @$ " UPDATE Messages SET ReceivedDate = DATETIME('{testDate:yyyy-MM-dd HH:mm:ss}'); "; context.Database.ExecuteSqlRaw(sql); context.ChangeTracker.Clear(); // verify entity return value var message = context.Messages.Single(x => x.From == "test"); message.ReceivedDate.Kind.Should().Be(DateTimeKind.Utc); message.ReceivedDate.ToLocalTime().Should().Be(new DateTime(testDate.Year, testDate.Month, testDate.Day, testDate.Hour + timeZone.Offset, 0, 0, DateTimeKind.Local)); } }
private async Task OnSessionCompleted(object sender, SessionEventArgs e) { int messageCount = (await e.Session.GetMessages()).Count; log.Information("Session completed. Client address {clientAddress}. Number of messages {messageCount}.", e.Session.ClientAddress, messageCount); await taskQueue.QueueTask(() => { using var scope = serviceScopeFactory.CreateScope(); Smtp4devDbContext dbContext = scope.ServiceProvider.GetService <Smtp4devDbContext>(); Session dbSession = dbContext.Sessions.Find(activeSessionsToDbId[e.Session]); UpdateDbSession(e.Session, dbSession).Wait(); dbContext.SaveChanges(); TrimSessions(dbContext); dbContext.SaveChanges(); activeSessionsToDbId.Remove(e.Session); notificationsHub.OnSessionsChanged().Wait(); }, false).ConfigureAwait(false); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory log) { ServerOptions serverOptions = Configuration.GetSection("ServerOptions").Get <ServerOptions>(); app.UseRouting(); Action <IApplicationBuilder> configure = subdir => { subdir.UseDeveloperExceptionPage(); subdir.UseDefaultFiles(); subdir.UseStaticFiles(); subdir.UseSpaStaticFiles(); subdir.UseWebSockets(); subdir.UseEndpoints(e => { e.MapHub <MessagesHub>("/hubs/messages"); e.MapHub <SessionsHub>("/hubs/sessions"); e.MapControllers(); if (env.IsDevelopment()) { e.MapToVueCliProxy( "{*path}", new SpaOptions { SourcePath = "ClientApp" }, npmScript: "serve", regex: "Compiled successfully", forceKill: true ); } }); Smtp4devDbContext context = subdir.ApplicationServices.GetService <Smtp4devDbContext>(); if (!context.Database.IsInMemory()) { context.Database.Migrate(); } subdir.ApplicationServices.GetService <Smtp4devServer>().Start(); }; if (!string.IsNullOrEmpty(serverOptions.RootUrl)) { app.Map(serverOptions.RootUrl, configure); } else { configure(app); } }
internal Task DeleteMessage(Guid id) { return(QueueTask(async() => { Smtp4devDbContext dbContext = dbContextFactory(); dbContext.Messages.RemoveRange(dbContext.Messages.Where(m => m.Id == id)); await dbContext.SaveChangesAsync(); await messagesHub.OnMessagesChanged(); }, true)); }
internal Task DeleteAllMessages() { return(QueueTask(async() => { Smtp4devDbContext dbContext = dbContextFactory(); dbContext.Messages.RemoveRange(dbContext.Messages); await dbContext.SaveChangesAsync(); await messagesHub.OnMessagesChanged(); }, true)); }
internal Task DeleteAllSessions() { return(QueueTask(() => { Smtp4devDbContext dbContext = dbContextFactory(); dbContext.Sessions.RemoveRange(dbContext.Sessions.Where(s => s.EndDate.HasValue)); dbContext.SaveChanges(); sessionsHub.OnSessionsChanged().Wait(); }, true)); }
public Task DeleteAllMessages() { return(QueueTask(() => { Smtp4devDbContext dbContext = dbContextFactory(); dbContext.Messages.RemoveRange(dbContext.Messages); dbContext.SaveChanges(); messagesHub.OnMessagesChanged().Wait(); }, true)); }
public Task DeleteMessage(Guid id) { return(QueueTask(() => { Smtp4devDbContext dbContext = dbContextFactory(); dbContext.Messages.RemoveRange(dbContext.Messages.Where(m => m.Id == id)); dbContext.SaveChanges(); messagesHub.OnMessagesChanged().Wait(); }, true)); }
public Task DeleteAllSessions() { return(taskQueue.QueueTask(() => { using var scope = serviceScopeFactory.CreateScope(); Smtp4devDbContext dbContext = scope.ServiceProvider.GetService <Smtp4devDbContext>(); dbContext.Sessions.RemoveRange(dbContext.Sessions.Where(s => s.EndDate.HasValue)); dbContext.SaveChanges(); notificationsHub.OnSessionsChanged().Wait(); }, true)); }
public SqliteInMemory() { this.ContextOptions = new DbContextOptionsBuilder <Smtp4devDbContext>() .UseSqlite(CreateInMemoryDatabase()) .Options; _connection = RelationalOptionsExtension.Extract(ContextOptions).Connection; using var context = new Smtp4devDbContext(ContextOptions); context.Database.EnsureDeleted(); context.Database.EnsureCreated(); context.SaveChanges(); }
internal Task DeleteSession(Guid id) { return(QueueTask(async() => { Smtp4devDbContext dbContext = dbContextFactory(); dbContext.Sessions.RemoveRange(dbContext.Sessions.Where(s => s.Id == id)); dbContext.SaveChanges(); await sessionsHub.OnSessionsChanged(); }, true)); }
private async void OnMessageReceived(object sender, MessageEventArgs e) { Smtp4devDbContext dbContent = dbContextFactory(); using (Stream stream = e.Message.GetData()) { Message message = await new MessageConverter().ConvertAsync(stream, e.Message.From, string.Join(", ", e.Message.To)); dbContent.Messages.Add(message); } dbContent.SaveChanges(); messagesHub.OnMessagesChanged().Wait(); }
public MessagesControllerTests() { messagesRepository = Substitute.For <IMessagesRepository>(); server = Substitute.For <ISmtp4devServer>(); controller = new MessagesController(messagesRepository, server); var sqlLiteForTesting = new SqliteInMemory(); context = new Smtp4devDbContext(sqlLiteForTesting.ContextOptions); InitRepo(); messagesRepository.GetMessages(Arg.Any <bool>()) .Returns(context.Messages); messagesRepository.DbContext.Returns(context); }
private void OnMessageReceived(object sender, MessageEventArgs e) { Smtp4devDbContext dbContent = dbContextFactory(); using (Stream stream = e.Message.GetData()) { Message message = new MessageConverter().Convert(stream); dbContent.Messages.Add(message); } dbContent.SaveChanges(); messagesHub.OnMessagesChanged().Wait(); }
private void OnSessionStarted(object sender, SessionEventArgs e) { Console.WriteLine($"Session started. Client address {e.Session.ClientAddress}"); Smtp4devDbContext dbContent = dbContextFactory(); Session session = new Session(); UpdateDbSession(e, session); dbContent.Sessions.Add(session); dbContent.SaveChanges(); sessionToDbId[e.Session] = session.Id; }
internal Task MarkMessageRead(Guid id) { return(QueueTask(async() => { Smtp4devDbContext dbContent = dbContextFactory(); DbModel.Message message = await dbContent.Messages.FindAsync(id); if (message.IsUnread) { message.IsUnread = false; dbContent.SaveChanges(); await messagesHub.OnMessagesChanged(); } }, true)); }
public Task MarkMessageRead(Guid id) { return(QueueTask(() => { Smtp4devDbContext dbContent = dbContextFactory(); DbModel.Message message = dbContent.Messages.FindAsync(id).Result; if (message.IsUnread) { message.IsUnread = false; dbContent.SaveChanges(); messagesHub.OnMessagesChanged().Wait(); } }, true)); }
private async Task OnSessionStarted(object sender, SessionEventArgs e) { Console.WriteLine($"Session started. Client address {e.Session.ClientAddress}."); await QueueTask(async() => { Smtp4devDbContext dbContent = dbContextFactory(); Session dbSession = new Session(); await UpdateDbSession(e.Session, dbSession); dbContent.Sessions.Add(dbSession); dbContent.SaveChanges(); sessionToDbId[e.Session] = dbSession.Id; }, false); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory log) { app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = new JsonExceptionMiddleware().Invoke }); app.UseDefaultFiles(); bool webpackConfigPresent = File.Exists(Path.Combine(env.ContentRootPath, "webpack.config.js")); if (env.IsDevelopment() && webpackConfigPresent) { app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { HotModuleReplacement = true }); } app.UseStaticFiles(); app.UseWebSockets(); app.UseSignalR(routes => { routes.MapHub <MessagesHub>("/hubs/messages"); routes.MapHub <SessionsHub>("/hubs/sessions"); }); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); routes.MapSpaFallbackRoute( name: "spa-fallback", defaults: new { controller = "Home", action = "Index" }); }); Smtp4devDbContext context = app.ApplicationServices.GetService <Smtp4devDbContext>(); if (!context.Database.IsInMemory()) { context.Database.Migrate(); } app.ApplicationServices.GetService <Smtp4devServer>().Start(); }
public Task DeleteSession(Guid id) { return(taskQueue.QueueTask(() => { using var scope = serviceScopeFactory.CreateScope(); Smtp4devDbContext dbContext = scope.ServiceProvider.GetService <Smtp4devDbContext>(); Session session = dbContext.Sessions.SingleOrDefault(s => s.Id == id); if (session != null) { dbContext.Sessions.Remove(session); dbContext.SaveChanges(); notificationsHub.OnSessionsChanged().Wait(); } }, true)); }
internal Task DeleteSession(Guid id) { return(QueueTask(() => { Smtp4devDbContext dbContext = dbContextFactory(); Session session = dbContext.Sessions.FirstOrDefault(s => s.Id == id); if (session != null) { dbContext.Sessions.Remove(session); dbContext.SaveChanges(); sessionsHub.OnSessionsChanged().Wait(); } }, true)); }
private void OnSessionCompleted(object sender, SessionEventArgs e) { Console.WriteLine($"Session completed. Client address {e.Session.ClientAddress}. Number of messages {e.Session.GetMessages().Length}"); Smtp4devDbContext dbContent = dbContextFactory(); Session session = dbContent.Sessions.Find(sessionToDbId[e.Session]); UpdateDbSession(e, session); dbContent.SaveChanges(); TrimSessions(dbContent); dbContent.SaveChanges(); sessionsHub.OnSessionsChanged().Wait(); }
private async Task OnSessionStarted(object sender, SessionEventArgs e) { log.Information("Session started. Client address {clientAddress}.", e.Session.ClientAddress); await taskQueue.QueueTask(() => { using var scope = serviceScopeFactory.CreateScope(); Smtp4devDbContext dbContext = scope.ServiceProvider.GetService <Smtp4devDbContext>(); Session dbSession = new Session(); UpdateDbSession(e.Session, dbSession).Wait(); dbContext.Sessions.Add(dbSession); dbContext.SaveChanges(); activeSessionsToDbId[e.Session] = dbSession.Id; }, false).ConfigureAwait(false); }
private void OnSessionCompleted(object sender, SessionEventArgs e) { Smtp4devDbContext dbContent = dbContextFactory(); Session session = new Session(); session.EndDate = e.Session.EndDate.GetValueOrDefault(DateTime.Now); session.ClientAddress = e.Session.ClientAddress.ToString(); session.ClientName = e.Session.ClientName; session.NumberOfMessages = e.Session.GetMessages().Length; session.Log = e.Session.GetLog().ReadToEnd(); dbContent.Sessions.Add(session); dbContent.SaveChanges(); sessionsHub.OnSessionsChanged().Wait(); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = new JsonExceptionMiddleware().Invoke }); app.UseDefaultFiles(); app.UseStaticFiles(); app.UseMvc(); app.UseWebSockets(); app.UseSignalR(routes => { routes.MapHub <MessagesHub>("hubs/messages"); routes.MapHub <SessionsHub>("hubs/sessions"); }); app.ApplicationServices.GetService <Smtp4devServer>().Start(); if (env.IsDevelopment()) { Smtp4devDbContext db = app.ApplicationServices.GetService <Smtp4devDbContext>(); MessageConverter messageConverter = new MessageConverter(); using (Stream stream = File.OpenRead("example.eml")) { Message message = messageConverter.Convert(stream); db.Messages.Add(message); } using (Stream stream = File.OpenRead("example2.eml")) { Message message = messageConverter.Convert(stream); db.Messages.Add(message); } db.SaveChanges(); } }