Skip to content

Commit

Permalink
feat: allow to execute middlewares when using the dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
Douglas Lima authored and dougolima committed Aug 5, 2021
1 parent 803cf31 commit 0c499a9
Show file tree
Hide file tree
Showing 10 changed files with 254 additions and 135 deletions.
50 changes: 38 additions & 12 deletions src/KafkaFlow.Admin.Dashboard/ApplicationBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace KafkaFlow.Admin.Dashboard
{
using System;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
Expand Down Expand Up @@ -28,26 +29,51 @@ public static IApplicationBuilder UseKafkaFlowDashboard(this IApplicationBuilder
/// <returns></returns>
public static IApplicationBuilder UseKafkaFlowDashboard(this IApplicationBuilder app, PathString pathMatch)
{
return app.UseKafkaFlowDashboard(pathMatch, null);
}

/// <summary>
/// Enable the KafkaFlow dashboard
/// </summary>
/// <param name="app">Instance of <see cref="IApplicationBuilder"/></param>
/// <param name="pathMatch">The request path to match.</param>
/// <param name="actionBuilder">The handler to be executed after the dashboard url is mapped.</param>
/// <returns></returns>
public static IApplicationBuilder UseKafkaFlowDashboard(
this IApplicationBuilder app,
PathString pathMatch,
Action<IDashboardConfigurationBuilder> actionBuilder)
{
var builder = new DashboardConfigurationBuilder();
actionBuilder?.Invoke(builder);
var configuration = builder.Build();

app.Map(
pathMatch,
builder =>
appBuilder =>
{
var provider = new ManifestEmbeddedFileProvider(
Assembly.GetAssembly(typeof(ApplicationBuilderExtensions)),
Assembly.GetAssembly(typeof(KafkaFlow.Admin.Dashboard.ApplicationBuilderExtensions)),
"ClientApp/dist");

builder.UseStaticFiles(new StaticFileOptions { FileProvider = provider });
appBuilder
.UseStaticFiles(new StaticFileOptions { FileProvider = provider })
.UseRouting();

builder.Run(
async context =>
{
if (context.Request.Path == "/" || context.Request.Path == string.Empty)
{
await context.Response.SendFileAsync(provider.GetFileInfo("index.html"));
}
});
});
foreach (var middleware in configuration.Middlewares)
{
appBuilder.UseMiddleware(middleware);
}

appBuilder.UseEndpoints(routeBuilder =>
{
var endpoint = routeBuilder.Map(
"/",
async context => await context.Response.SendFileAsync(provider.GetFileInfo("index.html")));

configuration.EndpointHandler?.Invoke(endpoint);
});
});
return app;
}
}
Expand Down
178 changes: 89 additions & 89 deletions src/KafkaFlow.Admin.Dashboard/ClientApp/dist/main.js

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/KafkaFlow.Admin.Dashboard/ClientApp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/KafkaFlow.Admin.Dashboard/ClientApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@angular/router": "~11.2.11",
"@ng-bootstrap/ng-bootstrap": "^9.1.0",
"bootstrap": "^4.6.0",
"ngx-cookie-service": "^11.0.2",
"ngx-mask": "^11.1.5",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse
} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {retry, catchError} from 'rxjs/operators';
import {CookieService} from 'ngx-cookie-service';
import {Injectable} from '@angular/core';

@Injectable()
export class ApiInterceptor implements HttpInterceptor {
constructor( private cookieService: CookieService ) { }

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: this.cookieService.getAll()
});
return next.handle(request)
.pipe(
retry(1),
catchError((error: HttpErrorResponse) => {
let errorMessage = '';
if (error.error instanceof ErrorEvent) {
// client-side error
errorMessage = `Error: ${error.error.message}`;
} else {
// server-side error
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
// window.alert(errorMessage);
console.error(errorMessage);
return throwError(errorMessage);
})
);
}
}
8 changes: 5 additions & 3 deletions src/KafkaFlow.Admin.Dashboard/ClientApp/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { NgxMaskModule, IConfig } from 'ngx-mask';
import { CookieService } from 'ngx-cookie-service';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { ConsumerComponent } from './consumer/consumer.component';
import { HttpErrorInterceptor } from './http-error.interceptor';
import { ApiInterceptor } from './api-interceptor.service';
import { GroupByPipe } from './group-by.pipe';
import { SortPipe } from './sort.pipe';

Expand Down Expand Up @@ -58,16 +59,17 @@ const appRoutes: Routes = [
],
exports: [RouterModule],
providers: [
CookieService,
ConsumersService,
{
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
useClass: ApiInterceptor,
multi: true
},
TelemetryService,
{
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
useClass: ApiInterceptor,
multi: true
}],
bootstrap: [AppComponent]
Expand Down

This file was deleted.

21 changes: 21 additions & 0 deletions src/KafkaFlow.Admin.Dashboard/DashboardConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace KafkaFlow.Admin.Dashboard
{
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;

internal class DashboardConfiguration
{
private readonly List<Type> middlewares;

public DashboardConfiguration(List<Type> middlewares, Action<IEndpointConventionBuilder> endpointHandler)
{
this.middlewares = middlewares;
this.EndpointHandler = endpointHandler;
}

public IReadOnlyCollection<Type> Middlewares => this.middlewares.AsReadOnly();

public Action<IEndpointConventionBuilder> EndpointHandler { get; }
}
}
29 changes: 29 additions & 0 deletions src/KafkaFlow.Admin.Dashboard/DashboardConfigurationBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace KafkaFlow.Admin.Dashboard
{
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;

internal class DashboardConfigurationBuilder : IDashboardConfigurationBuilder
{
private readonly List<Type> middlewares = new();
private Action<IEndpointConventionBuilder> endpointHandler = _ => { };

public IDashboardConfigurationBuilder UseMiddleware<T>()
{
this.middlewares.Add(typeof(T));
return this;
}

public IDashboardConfigurationBuilder ConfigureEndpoint(Action<IEndpointConventionBuilder> endpointHandler)
{
this.endpointHandler = endpointHandler;
return this;
}

public DashboardConfiguration Build()
{
return new(this.middlewares, this.endpointHandler);
}
}
}
24 changes: 24 additions & 0 deletions src/KafkaFlow.Admin.Dashboard/IDashboardConfigurationBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace KafkaFlow.Admin.Dashboard
{
using System;
using Microsoft.AspNetCore.Builder;

/// <summary>
/// Used to build the dashboard configuration
/// </summary>
public interface IDashboardConfigurationBuilder
{
/// <summary>
/// Adds a middleware type to the dashboard's request pipeline.
/// </summary>
/// <returns>The <see cref="IDashboardConfigurationBuilder"/> instance.</returns>
IDashboardConfigurationBuilder UseMiddleware<T>();

/// <summary>
/// Use this method to configure the dashboard endpoint pipeline.
/// </summary>
/// <param name="endpointHandler">A handler to configure the endpoint</param>
/// <returns>The <see cref="IDashboardConfigurationBuilder"/> instance.</returns>
IDashboardConfigurationBuilder ConfigureEndpoint(Action<IEndpointConventionBuilder> endpointHandler);
}
}

0 comments on commit 0c499a9

Please sign in to comment.