Skip to main content

Metadata exchange

Overview

Metadata exchange can require and consume dependency service metadata.

Install

  • ASOL.Core.MetadataExchange - Support to require and consume dependency service metadata.
  • ASOL.Core.MetadataExchange.Contracts - Models for message broker.

Changelog

  • 0.0.1.47857-dev
    • BREAKING CHANGE: Dependency on ASOL.Core.Identity.Abstractions of the version 0.0.1.47819-dev
  • 0.0.1.45477-dev
    • support for multiple master databases
  • 0.0.1.33988-dev
    • multiversion support

How to set up source service

This pattern requires the use of IDM in the application.

Register and configure services

Startup.cs

public virtual void ConfigureServices(IServiceCollection services)
{
...
services.AddMetadataExchangeSupport();
...
}

StartupExtensions.cs - configure dependency services and areas that we require to be ready.

/// <summary>
/// Add Metadata exchange support
/// </summary>
public static IServiceCollection AddMetadataExchangeSupport(this IServiceCollection services)
{
...
services.Configure<MetadataExchangeOptions>(options =>
{
options
.AddRequestMetadata("ASOLEU-MessageProvider-AP-", "Templates1") // target service, metadata code
.AddRequestMetadata("ASOLEU-MessageProvider-AP-", "Templates2") // target service, metadata code
;
});

services.AddTransient<IMetadataAcceptHandler, MetadataAcceptHandler>();
services.AddTransient<IMetadataAcceptHandler, MetadataAcceptHandlerX>(); //Optional can be multiple handlers

return services;
}

Register and configure MassTransit

StartupMessaging.cs - Register MetadataAcceptConsumer

services.AddMessaging(config =>
{
...
config.AddMetadataExchangeConsumers();
config.UsingRabbitMq(UseRabbitMq);
...
});

private static void UseRabbitMq(IBusRegistrationContext regContext, IRabbitMqBusFactoryConfigurator cfg)
{
...
cfg.ConfigureMetadataExchangeAccept(serviceName, regContext);
...
}

Implement IMetadataAcceptHandler

Implement IMetadataAcceptHandler - handle that dependency service and area is ready

public class MetadataAcceptHandler : IMetadataAcceptHandler
{
public Task HandleAsync(MetadataAccept metadataAccept, CancellationToken ct = default)
{
if (metadataAccept.TargetService == "ASOLEU-MessageProvider-AP-" && metadataAccept.MetadataCode == "Templates1")
{
LoadMessageProviderTemplates1();
}

if (metadataAccept.TargetService == "ASOLEU-MessageProvider-AP-" && metadataAccept.MetadataCode == "Templates2")
{
LoadMessageProviderTemplates2();
}
...
}
}

How to set up target/dependency service

Register and configure services

Startup.cs

public virtual void ConfigureServices(IServiceCollection services)
{
...
services.AddMetadataExchangeSupport();
}

StartupExtensions.cs - configure that metadata code can be accepted.

/// <summary>
/// Add Metadata exchange support
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddMetadataExchangeSupport(this IServiceCollection services)
{
services.Configure<MetadataExchangeOptions>(options =>
{
options
.AddAcceptableRequestMetadata("Templates1")
.AddAcceptableRequestMetadata("Templates2");
});

return services;
}

Register and configure MassTransit

StartupMessaging.cs - register MetadataRequestConsumer

...
services.AddMessaging(config =>
{
...
config.AddMetadataExchangeConsumers();
config.UsingRabbitMq(UseRabbitMq);
...
});

private static void UseRabbitMq(IBusRegistrationContext regContext, IRabbitMqBusFactoryConfigurator cfg)
{
...
cfg.ConfigureMetadataExchangeRequest(serviceName, regContext);
...
}

Backward compatibility with the previous versions

Upgrading from version 0.0.1.33903-dev to a greater version

If you want to upgrade metadata exchange package in the source service, make sure that the target service you are pointing to also has the updated metadata exchange package.

If you've updated from version 0.0.1.33903-dev to a greater version, please contact the DevOps team to unbind previous exchange binding configuration from RabbitMQ.

Source service

 cfg.ReceiveEndpoint(serviceName, ep =>
{
...
// ep.UseMetadataExchangeAccept(regContext);
// UseMetadataExchangeAccept method is removed in newer versions.
// Use ConfigureMetadataExchangeAccept on IRabbitMqBusFactoryConfigurator instead.
...
});

Target service

 cfg.ReceiveEndpoint(serviceName, ep =>
{
...
// ep.UseMetadataExchangeRequest(regContext);
// UseMetadataExchangeRequest method is removed in newer versions.
// Use ConfigureMetadataExchangeRequest on IRabbitMqBusFactoryConfigurator instead.
...
});

Alternatives to MassTransit metadata exchange

Communication through HTTPs channel

If you want to use the functionality of the exchange meta, but do not want or cannot use the MassTransit approach, you can use an alternative communication method via https.

How to set up source service

appsettings.json

{
"MetadataExchangeOptions": {
"MetadataExchangeChannel": "Https"
}
}

services.Configure<MetadataExchangeOptions>(options =>
{
options
.SetHostService("SourceApplicationCode")
.AddRequestMetadata("TargetApplicationCode", MetadataCodeEnum.Authorization.ToString())
.SetTargetServiceMetadataUri("TargetApplicationCode", TargetServiceMetadataExchangeUri);
});

How to set up target/dependency service

Instead of consuming messages through MassTransit, you can handle metadata requests using minimal API, as you can in the example below.

Example of handle MetadataRequest using minimal API

app.UseEndpoints(endpoints =>
{
...
endpoints.MapMetadataExchange();
...
});