-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #174 from 5G-ERA/134-dynamic-gateway-reconfiguration
134 dynamic gateway reconfiguration
- Loading branch information
Showing
10 changed files
with
345 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Gateway | ||
|
||
The `Middleware` system includes diverse microservices. When a `robot/user` has to consume multiple microservices, setting up distinct endpoints for each microservice and managing them separately can be challenging. A solution for handling such tasks is placing a gateway in front of the microservices. In this way, the `robot/user` can communicate with the various microservices by using a single entry-point. | ||
|
||
## What technologies have been used and for what purposes | ||
|
||
The gateway for the `5G-ERA Middleware` has been implemented using the `Ocelot` and `YARP` reverse proxy server. `Ocelot` is an open-source application, which is lightweight, fast, scalable, cross-platform, and most importantly it was specifically designed for `.NET Core` Microservices Architecture. `Ocelot` is responsible for handling the incoming requests, by routing the traffic to the desired endpoints, retrieving the information from the backend, and relaying it back to the `robots/users`. On the other hand, `YARP` is as well an open source application built on top of the `.NET` environment, being designed to be easily customizable and tweaked. `YARP` will accommodate the functionalities for dynamic gateway configuration and websocket for robotic communication purposes. | ||
|
||
# Gateway functionalities | ||
|
||
While both technologies serve the common purpose for routing the incoming requests, their distinct functionalities are described below. | ||
|
||
## Ocelot authentication/authorization and RBAC | ||
|
||
The `Ocelot` also fulfils the role of an `Identity Service`, through a `REST API` implementation. The user credentials are stored in a safe manner using a `HASH + SALT` model, following current best practices and using cryptographically strong libraries from `.NET` environment. The passwords are SALT-ed and hashed using the `PBKDF2` algorithm with `HMACSHA256` hashing. Authentication is achieved by reconstructing the salted hash from the credentials provided at log-in and comparing the result with the salted hash stored in the system at registration. | ||
Furthermore, the security of the `Middleware` systems is enhanced using the `JWT Bearer Token` standard and `Role Based Access Control` (`RBAC`) model. More precisely when the `robots/users` are successfully authenticated they will receive a `JWT Token`. In terms of authorization, the `robots/users` will have to pass the generated token along with the request in order to be able to perform operations on the data, through the endpoints that are implemented in the `Middleware` system. Finally, the security of the system is boosted with the implementation of the `RBAC` model that will provide restricted access to the `Middleware` system based on the role of the user. | ||
|
||
## YARP dynamic gateway configuration and WebSockets | ||
|
||
The `Middleware` system offers the possibility to dynamically configure the `Gateway` in order to route the traffic through a websocket to a specific `Network Application` using the `YARP` reverse proxy functionalities. This allows enabling `RBAC` to the `Network Applications` and expose everything behind the `Gateway` using `SSL` termination. Moreover, this will also remove the need to enable the authentication on the `Network Application` level. | ||
The dynamic `Gateway` configuration is accomplished through standard `REST` requests and `WebSockets`, in fact, the whole mechanism is triggered through `RabbitMQ` queueing system for both creating the new route and deleting the Route once the `Network Application` has finished conducting the task. | ||
The messages to open or close the route are sent from the Orchestrator after the desired `Network Application` is deployed or terminated. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
src/Common/MessageContracts/GatewayAddNetAppEntryMessage.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace Middleware.Common.MessageContracts; | ||
public record GatewayAddNetAppEntryMessage : Message | ||
{ | ||
public Guid ActionPlanId { get; set; } | ||
|
||
public Guid ServiceInstanceId { get; set; } | ||
|
||
public string NetAppName { get; set; } | ||
|
||
public string DeploymentLocation { get; init; } | ||
|
||
|
||
} |
17 changes: 17 additions & 0 deletions
17
src/Common/MessageContracts/GatewayDeleteNetAppEntryMessage.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Middleware.Common.MessageContracts; | ||
public record GatewayDeleteNetAppEntryMessage : Message | ||
{ | ||
public Guid ActionPlanId { get; set; } | ||
|
||
public Guid ServiceInstanceId { get; set; } | ||
|
||
public string NetAppName { get; set; } | ||
|
||
public string DeploymentLocation { get; init; } | ||
} |
84 changes: 84 additions & 0 deletions
84
src/OcelotGateway/ExtensionMethods/ServiceCollectionExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using MassTransit; | ||
using Middleware.Common.Config; | ||
using Middleware.Common.Helpers; | ||
using Middleware.Common.MessageContracts; | ||
using Middleware.OcelotGateway.Handlers; | ||
using Middleware.OcelotGateway.Services; | ||
using RabbitMQ.Client; | ||
|
||
namespace Middleware.OcelotGateway.ExtensionMethods; | ||
|
||
public static class ServiceCollectionExtensions | ||
{ | ||
public static IServiceCollection RegisterRabbitMqConsumers(this IServiceCollection services, | ||
RabbitMqConfig mqConfig, MiddlewareConfig mwConfig) | ||
{ | ||
var routingKey = QueueHelpers.ConstructRoutingKey(mwConfig.InstanceName, mwConfig.InstanceType); | ||
|
||
services.AddMassTransit(x => | ||
{ | ||
services.AddScoped<CreateDynamicRouteConsumer>(); | ||
x.AddConsumer<CreateDynamicRouteConsumer>(); | ||
|
||
services.AddScoped<DeleteDynamicRouteConsumer>(); | ||
x.AddConsumer<DeleteDynamicRouteConsumer>(); | ||
|
||
x.UsingRabbitMq((busRegistrationContext, mqBusFactoryConfigurator) => | ||
{ | ||
mqBusFactoryConfigurator.Host(mqConfig.Address, "/", hostConfig => | ||
{ | ||
hostConfig.Username(mqConfig.User); | ||
hostConfig.Password(mqConfig.Pass); | ||
}); | ||
|
||
mqBusFactoryConfigurator.ReceiveEndpoint( | ||
QueueHelpers.ConstructGatewayAddNetAppEntryMessageQueueName(mwConfig.Organization, mwConfig.InstanceName), | ||
ec => | ||
{ | ||
ec.ConfigureConsumeTopology = false; | ||
ec.Bind(nameof(GatewayAddNetAppEntryMessage), b => | ||
{ | ||
b.ExchangeType = ExchangeType.Direct; | ||
b.RoutingKey = routingKey; | ||
}); | ||
ec.ConfigureConsumer<CreateDynamicRouteConsumer>(busRegistrationContext); | ||
}); | ||
|
||
mqBusFactoryConfigurator.ReceiveEndpoint( | ||
QueueHelpers.ConstructGatewayDeleteNetAppEntryMessageQueueName(mwConfig.Organization, mwConfig.InstanceName), | ||
ec => | ||
{ | ||
ec.ConfigureConsumeTopology = false; | ||
ec.Bind(nameof(GatewayDeleteNetAppEntryMessage), b => | ||
{ | ||
b.ExchangeType = ExchangeType.Direct; | ||
b.RoutingKey = routingKey; | ||
}); | ||
ec.ConfigureConsumer<DeleteDynamicRouteConsumer>(busRegistrationContext); | ||
}); | ||
|
||
mqBusFactoryConfigurator.ConfigureEndpoints(busRegistrationContext); | ||
}); | ||
|
||
|
||
}); | ||
|
||
|
||
services.AddOptions<MassTransitHostOptions>() | ||
.Configure(options => | ||
{ | ||
// if specified, waits until the bus is started before | ||
// returning from IHostedService.StartAsync | ||
// default is false | ||
options.WaitUntilStarted = true; | ||
|
||
// if specified, limits the wait time when starting the bus | ||
options.StartTimeout = TimeSpan.FromSeconds(10); | ||
|
||
// if specified, limits the wait time when stopping the bus | ||
options.StopTimeout = TimeSpan.FromSeconds(30); | ||
}); | ||
|
||
return services; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Middleware.Common.MessageContracts; | ||
using MassTransit; | ||
using Middleware.OcelotGateway.Services; | ||
using Middleware.Common.Config; | ||
using System.Numerics; | ||
|
||
namespace Middleware.OcelotGateway.Handlers; | ||
|
||
public class CreateDynamicRouteConsumer : IConsumer<GatewayAddNetAppEntryMessage> | ||
{ | ||
private readonly ILogger _logger; | ||
|
||
private GatewayConfigurationService _gatewayConfigurationService; | ||
|
||
private readonly IConfiguration _cfg; | ||
|
||
public CreateDynamicRouteConsumer(ILogger<CreateDynamicRouteConsumer> logger, GatewayConfigurationService gatewayConfigurationService, IConfiguration cfg) | ||
{ | ||
_logger = logger; | ||
_gatewayConfigurationService = gatewayConfigurationService; | ||
_cfg = cfg; | ||
|
||
} | ||
|
||
|
||
public Task Consume(ConsumeContext<GatewayAddNetAppEntryMessage> context) | ||
{ | ||
_logger.LogInformation("Started processing GatewayAddNetAppEntryMessage"); | ||
var mwconfig = _cfg.GetSection(MiddlewareConfig.ConfigName).Get<MiddlewareConfig>(); | ||
var msg = context.Message; | ||
_logger.LogDebug("Location {0}-{1} received message request addressed to {2}", mwconfig.InstanceName, mwconfig.InstanceType, msg.DeploymentLocation); | ||
_gatewayConfigurationService.CreateDynamicRoute(msg); | ||
return Task.CompletedTask; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using MassTransit; | ||
using Middleware.Common.Config; | ||
using Middleware.Common.MessageContracts; | ||
using Middleware.OcelotGateway.Services; | ||
|
||
namespace Middleware.OcelotGateway.Handlers; | ||
|
||
public class DeleteDynamicRouteConsumer : IConsumer<GatewayDeleteNetAppEntryMessage> | ||
{ | ||
private readonly ILogger _logger; | ||
|
||
private GatewayConfigurationService _gatewayConfigurationService; | ||
|
||
private readonly IConfiguration _cfg; | ||
|
||
public DeleteDynamicRouteConsumer(ILogger<DeleteDynamicRouteConsumer> logger, GatewayConfigurationService gatewayConfigurationService, IConfiguration cfg) | ||
{ | ||
_logger = logger; | ||
_gatewayConfigurationService = gatewayConfigurationService; | ||
_cfg = cfg; | ||
} | ||
|
||
|
||
|
||
public Task Consume(ConsumeContext<GatewayDeleteNetAppEntryMessage> context) | ||
{ | ||
_logger.LogInformation("Started processing GatewayDeleteNetAppEntryMessage"); | ||
var mwconfig = _cfg.GetSection(MiddlewareConfig.ConfigName).Get<MiddlewareConfig>(); | ||
var msg = context.Message; | ||
_logger.LogDebug("Location {0}-{1} received message request addressed to {2}", mwconfig.InstanceName, mwconfig.InstanceType, msg.DeploymentLocation); | ||
_gatewayConfigurationService.DeleteDynamicRoute(msg); | ||
return Task.CompletedTask; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.