/// <summary> /// Initializes a new instance of <see cref="KafkaBusHost{TContext}"/> /// </summary> /// <param name="subscriber">The KafkaBus Subscriber</param> /// <param name="application">The HttpApplication</param> internal KafkaBusHost(IKafkaBusSubscriber subscriber, IHttpApplication <TContext> application, IApplicationLifetime applicationLifetime, ILoggerFactory logFactory) { this.subscriber = subscriber; this.application = application; this.applicationLifetime = applicationLifetime; this.logger = logFactory.CreateLogger <KafkaBusHost <TContext> >(); }
/// <summary> /// Starts running a new KafkaBus host. /// </summary> /// <param name="app">The Application builder</param> /// <param name="subscriber">The KafkaBus subscriber</param> /// <param name="skipKafkaBusServerCheck">Set to true to run the host even if the application server is the KafkaBus.AspNet server</param> public static void RunKafkaBusHost(this IApplicationBuilder app, IKafkaBusSubscriber subscriber, bool skipKafkaBusServerCheck) { if (app == null) { throw new ArgumentNullException("app"); } if (subscriber == null) { throw new ArgumentNullException("subscriber"); } if (!skipKafkaBusServerCheck && Server.InstanceCount > 0) { //The application is running KafkaBusServer, so exit return; } var appFunc = app.Build(); var _loggerFactory = app.ApplicationServices.GetRequiredService <ILoggerFactory>(); var diagnosticSource = app.ApplicationServices.GetRequiredService <DiagnosticSource>(); var httpContextFactory = app.ApplicationServices.GetRequiredService <IHttpContextFactory>(); //TODO: Work on counting instances (all hosts + server) and adding the count to the logger name e.g KafkaBus.AspNet (2), consider including the typename as well. var application = new HostingApplication(appFunc, _loggerFactory.CreateLogger(typeof(Server).FullName), diagnosticSource, httpContextFactory); var server = app.ApplicationServices.GetRequiredService <Server>(); server.Start(application, subscriber); }
/// <summary> /// Configures the KafkaBus server to use a specified subscriber /// </summary> /// <param name="app">The Application builder</param> /// <param name="subscriber">The KafkaBus subscriber</param> public static void ConfigureKafkaBusServer(this IApplicationBuilder app, IKafkaBusSubscriber subscriber) { if (app == null) { throw new ArgumentNullException("app"); } if (subscriber == null) { throw new ArgumentNullException("subscriber"); } var feature = app.ServerFeatures.Get <IServerInformation>(); if (feature == null) { return; //Application isn't running KafkaBus server so return } var serverInfo = feature as ServerInformation; if (serverInfo != null) { serverInfo.Subscriber = subscriber; } }
//TODO: See if it's possible to prevent middleware from being added after RunKafkaBusHost() is called, subsequent calls to RunKafkaBusHost must succeed. /// <summary> /// Starts running a new KafkaBus host. /// </summary> /// <param name="app">The Application builder</param> /// <param name="subscriber">The KafkaBus subscriber</param> /// <remarks>The KafkaBus host will not be started if the application is running a KafkaBus server.</remarks> public static void RunKafkaBusHost(this IApplicationBuilder app, IKafkaBusSubscriber subscriber) { RunKafkaBusHost(app, subscriber, false); }
public void Start <TContext>(IHttpApplication <TContext> application, IKafkaBusSubscriber subscriber) { //TODO: Code a better way to prevent same server from starting twice. if (_disposables != null) { // The server has already started and/or has not been cleaned up yet throw new InvalidOperationException("Server has already started."); } _disposables = new Stack <IDisposable>(); try { var information = this.Features.Get <IServerInformation>(); if (information?.Subscriber == null) { if (subscriber != null) { information = new ServerInformation() { Subscriber = subscriber }; //information.Subscriber = subscriber; } else { throw new InvalidOperationException($"KafkaBus subscriber could not be found. To use the KafkaBus server, call app.{nameof(ServerExtensions.ConfigureKafkaBusServer)} in Startup.Configure method and specify a subscriber to use."); } } else { subscriber = information.Subscriber; } //TODO: Add _logger properly this._logger.LogInformation($"{nameof(Server)} is starting the KafkaBus host."); var host = new KafkaBusHost <TContext>(subscriber, application, this._applicationLifetime, this._logFactory); //Register host for disposal //TODO: Make IApplicationLifeTime.Stopping to stop polling the queue. this._applicationLifetime.ApplicationStopping.Register(() => { //TODO: Make ApplicationStopping event stop dequeueing items (StopPollingQueue) host.Dispose(); }); this._applicationLifetime.ApplicationStopped.Register(() => host.Dispose()); _disposables.Push(host); host.Start(); foreach (var name in subscriber.ConnectionNames) { information.AddAddress(name); } } catch (Exception ex) { this._logger.LogError(ex.Message + Environment.NewLine + ex.StackTrace); Dispose(); throw; } }