using System; using ln.http; using System.Collections.Generic; using System.Collections; using System.Linq; using ln.logging; using ln.types; using System.Net; using ln.application.service; using ln.http.resources; using ln.types.btree; namespace ln.application { public class Application : IApplicationInterface { public ArgumentContainer Arguments { get; protected set; } public HTTPServer HttpServer { get; private set; } public ServiceContainer ServiceContainer { get; } public ResourceApplication HTTPApplication { get; private set; } public MemoryLogger MemoryLogger { get; } public int ApplicationContextTimeout { get; set; } = 1200; MappingBTree applicationContexts = new MappingBTree((x)=>x.ContextID); public Application() { MemoryLogger = new MemoryLogger(8192); Logger.Default.Backends.Add(MemoryLogger); Arguments = new ArgumentContainer() .Add((char)0, "log-level", "INFO") .Add('l', "http-listen","0.0.0.0") .Add('p', "http-port", "8080"); ServiceContainer = new ServiceContainer(this); } public virtual void PrepareStart() { } public void Start(String[] arguments) { Arguments.Parse(arguments); Logger.ConsoleLogger.MaxLogLevel = (LogLevel)Enum.Parse(typeof(LogLevel), Arguments["log-level"].Value); /* Startup Sequence */ Logging.Log(LogLevel.INFO, "Calling PrepareStart()"); PrepareStart(); /* HTTP Server */ Logging.Log(LogLevel.INFO, "Start: HTTPServer on {0}:{1}", Arguments['l'].Value, Arguments['p'].IntegerValue); HttpServer = new HTTPServer(); HttpServer.AddEndpoint(new System.Net.IPEndPoint( IPAddress.Parse(Arguments['l'].Value), Arguments['p'].IntegerValue )); HttpServer.Start(); HTTPApplication = new ResourceApplication(); HttpServer.DefaultApplication = HTTPApplication; /* Application Services */ foreach (ServiceDefinition serviceDefinition in ServiceContainer) { if (serviceDefinition.AutoStart && !serviceDefinition.IsAlive) ServiceContainer.Start(serviceDefinition); } } public void Stop() { Logging.Log(LogLevel.INFO, "Application shutdown requested"); /* Application Services */ foreach (ServiceDefinition serviceDefinition in ServiceContainer) { if (serviceDefinition.IsAlive) { ServiceContainer.Stop(serviceDefinition); if (serviceDefinition.IsAlive) throw new Exception("application service could not be stopped"); } } /* HTTP Server */ Logging.Log(LogLevel.INFO, "Stopping HTTP server"); HttpServer.Stop(); } public virtual ApplicationContext CreateApplicationContext() => new ApplicationContext(this); public ApplicationContext GetApplicationContext() => GetApplicationContext(Guid.Empty); public ApplicationContext GetApplicationContext(Guid contextID) { ApplicationContext applicationContext; if (Guid.Empty.Equals(contextID)) { while (true) { applicationContext = CreateApplicationContext(); if (!applicationContexts.ContainsKey(applicationContext.ContextID)) { applicationContexts.Add(applicationContext); break; } } } else { if (!applicationContexts.ContainsKey(contextID)) throw new KeyNotFoundException(); applicationContext = applicationContexts[contextID]; } return applicationContext; } public virtual AuthenticatedUser AuthenticateUser(string username,object prove) { return null; } public void CleanupApplicationContexts() { foreach (ApplicationContext applicationContext in applicationContexts.ToArray()) { if (applicationContext.Untouched > TimeSpan.FromSeconds(ApplicationContextTimeout)) applicationContexts.RemoveKey(applicationContext.ContextID); } } /* * Plugin Classes */ Dictionary> pluginInstances = new Dictionary>(); public void RegisterPluginInstance(PC pluginInstance) => RegisterPluginInstance(typeof(PC),pluginInstance); public void RegisterPluginInstance(Type type,object pluginInstance) { if (!pluginInstances.ContainsKey(type)) pluginInstances.Add(type, new List()); if (!pluginInstances[type].Contains(pluginInstance)) pluginInstances[type].Add(pluginInstance); } public IEnumerable GetPluginInstances() { Type pluginType = typeof(PC); if (!pluginInstances.ContainsKey(pluginType)) return new PC[0]; return pluginInstances[pluginType].Select((ut) => (PC)ut); } public IEnumerable GetPluginInstances(Type pluginType) { if (!pluginInstances.ContainsKey(pluginType)) return new object[0]; return pluginInstances[pluginType]; } } }