I have three microservices: ImageService, ProductService and UserService. ImageService stores images and publish a message for the other two (or even more) services. These consumers must intercept their message based on the following record entity. TypeOfEntity says who is the proper consumer.
public record FileSavedEvent(
int FileId,
int EntityId,
EntityType TypeOfEntity,
DateTime CreatedOnUtc);
This message is dispatched like:
// This line creates a variable with a string "PRODUCT" or "USER"
var requester = request.Requester.ToRoutingKey();
await publishEndpoint.Publish(new FileSavedEvent(
fileId,
request.EntityId,
request.Requester,
DateTime.UtcNow),
ctx =>
{
ctx.SetRoutingKey(requester);
},
cancellationToken);
update: I just configured the consumer this way:
cfg.ReceiveEndpoint("product-queue", e =>
{
e.ConfigureConsumeTopology = false;
e.ConfigureConsumer<ImageSavedConsumer>(ctx);
e.Bind("exc-image", b =>
{
b.RoutingKey = "PRODUCT";
b.ExchangeType = "direct";
});
});
It creates two exchanges: exc-image (direct) and product-queue (fanout), then creates a queue product-queue bound to product-queue. Since the fanout exchanges don't support routing key this is completely illogical!
-- How could be configured both publisher and consumers services to manage this scenario?
Thanks
I have three microservices: ImageService, ProductService and UserService. ImageService stores images and publish a message for the other two (or even more) services. These consumers must intercept their message based on the following record entity. TypeOfEntity says who is the proper consumer.
public record FileSavedEvent(
int FileId,
int EntityId,
EntityType TypeOfEntity,
DateTime CreatedOnUtc);
This message is dispatched like:
// This line creates a variable with a string "PRODUCT" or "USER"
var requester = request.Requester.ToRoutingKey();
await publishEndpoint.Publish(new FileSavedEvent(
fileId,
request.EntityId,
request.Requester,
DateTime.UtcNow),
ctx =>
{
ctx.SetRoutingKey(requester);
},
cancellationToken);
update: I just configured the consumer this way:
cfg.ReceiveEndpoint("product-queue", e =>
{
e.ConfigureConsumeTopology = false;
e.ConfigureConsumer<ImageSavedConsumer>(ctx);
e.Bind("exc-image", b =>
{
b.RoutingKey = "PRODUCT";
b.ExchangeType = "direct";
});
});
It creates two exchanges: exc-image (direct) and product-queue (fanout), then creates a queue product-queue bound to product-queue. Since the fanout exchanges don't support routing key this is completely illogical!
-- How could be configured both publisher and consumers services to manage this scenario?
Thanks
Share Improve this question edited Jan 21 at 22:42 Max Bertoli asked Jan 19 at 23:35 Max BertoliMax Bertoli 6145 silver badges26 bronze badges 2 |1 Answer
Reset to default 0Did you try, if your current setup works fine? If I understand the documentation of masstransit correctly, it's the correct behavior, that it will create two exchanges. One expected exchange (here exc-image
with type direct
) and the not so expected fanout exchange, which is called exactly like your desired queue.
I can't see in your publisher code, that you're sending the event to the exchange exc-image
. As the exchange exc-image
is of type direct
, the routing key is working here. As the exchange product-queue
has type fanout
but also only one queue (product-queue
) is bound to it, it will just forward the messages to all bound queues. The exchange exc-image
binding should still do the dispatching properly.
So for your user-service
you should configure the same:
cfg.ReceiveEndpoint("user-queue", e =>
{
e.ConfigureConsumeTopology = false;
e.ConfigureConsumer<ImageSavedConsumer>(ctx);
e.Bind("exc-image", b =>
{
b.RoutingKey = "USER";
b.ExchangeType = ExchangeType.Direct;
});
});
This should create a second binding to exchange exc-image
with routing key USER
plus the unexpected fanout exchange user-queue
and the queue user-queue
.
TypeOfEntity
? – Ivan Rubinson Commented Jan 21 at 20:28