是否可以在没有管理权限策略的情况下将 MassTransit 3 与 Azure 服务总线一起使用

本文关键字:MassTransit Azure 服务 一起 总线 情况下 管理 策略 权限 管理权 是否 | 更新日期: 2023-09-27 18:32:34

我花了几天时间测试 MassTransit 3.1.2,看看我们是否可以在应用程序中将其与 Azure 服务总线一起使用。

我使用MassTransit.AzureServiceBus(3.1.2(制作了一个包含两个控制台应用程序的示例:一个发布者和一个suscriber。

效果很好。启动应用程序时,将在 Azure 上的命名空间上自动创建实体(队列、主题、订阅(。
当你在测试东西时,这很好,但在生产中,我不希望允许应用程序创建实体。我们希望预先创建它们。

为了尝试这一点,我认为使用仅具有">发送"或"侦听">权限的 SAS 策略连接到总线是个好主意(在我使用具有"管理">权限的命名空间策略之前(。

现在我在这一点上挣扎,我无法让它工作,我总是收到 401 错误 如果我不使用具有"管理"权限的策略,则此操作需要管理声明
我尝试直接在命名空间或实体上设置策略,但没有成功。

之后,我分析了堆栈跟踪异常(省略了 [...] 的无用部分(:

System.UnauthorizedAccessException: Le serveur distant a retourné une erreur : (401) Non autorisé. Manage claim is required for this operation. TrackingId:2ca420e3-aac6-467c-bacb-6e051dbc3e39_G47,TimeStamp:1/29/2016 11:20:41 PM ---> System.Net.WebException: Le serveur distant a retourné une erreur : (401) Non autorisé.
   à System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   à Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.GetAsyncResult`1.<GetAsyncSteps>b__3c(GetAsyncResult`1 thisPtr, IAsyncResult r)
   à Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.StepCallback(IAsyncResult result)
   --- Fin de la trace de la pile d'exception interne ---
Server stack trace:
Exception rethrown at [0]:
   à Microsoft.ServiceBus.Common.ExceptionDispatcher.Throw(Exception exception)
   à Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
   à Microsoft.ServiceBus.Common.AsyncResult`1.End(IAsyncResult asyncResult)
   à Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.EndGet[TEntityDescription](IAsyncResult asyncResult, String[]& resourceNames)
   à Microsoft.ServiceBus.NamespaceManager.EndGetQueue(IAsyncResult result)
   à System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
   à MassTransit.AzureServiceBusTransport.NamespaceManagerExtensions.<CreateQueueSafeAsync>d__1.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
   à MassTransit.AzureServiceBusTransport.Pipeline.PrepareReceiveQueueFilter.<Send>d__5.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
   à MassTransit.AzureServiceBusTransport.ServiceBusReceiveTransport.<>c__DisplayClass12_0.<<Receiver>b__0>d.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
   à MassTransit.Internals.Extensions.TaskExtensions.<WithCancellation>d__0`1.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception 
[...]
   à MassTransit.MassTransitBus.<StartAsync>d__30.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
   à System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   à MassTransit.MassTransitBus.<StartAsync>d__30.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
   à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   à System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   à MassTransit.Util.TaskUtil.Await[T](Func`1 taskFactory, CancellationToken cancellationToken)
   à MassTransit.MassTransitBus.MassTransit.IBusControl.Start()

我发现MassTransit.AzureServiceBusTransport.NamespaceManagerExtensions.CreateQueueSafeAsync的线路非常有趣,因为我能够查看MassTransit源代码以了解它在做什么。我看到它正在使用命名空间管理器进行一些调用以获取队列或主题。

由于此类被命名为 NamespaceManager,我认为这意味着您无论如何都需要">管理"权限。
为了尝试这一点,我仅使用 Azure SDK 创建了一个基本的控制台应用程序,以使用仅具有侦听或发送权限的策略对命名空间管理器进行一些调用:我在尝试的所有调用中都收到 401 错误。添加管理权限有效。

我在 Azure 文档中没有找到有关此假设的任何内容,或者我错过了一些东西。

最后一个问题:

有没有办法在 Azure 服务总线上使用仅具有发送或侦听策略的公共交通?我错过了什么,我走错了路吗?

是否可以在没有管理权限策略的情况下将 MassTransit 3 与 Azure 服务总线一起使用

由于 MassTransit 负责管理服务总线命名空间的拓扑,包括创建主题和队列以及创建和绑定订阅,因此需要管理权限。

虽然您可能认为在生产环境中手动创建所有内容并将该权限保留在应用程序中是个好主意,但您总是会花时间弄清楚为什么生产中出现问题并让您的工程师感到沮丧。我根据经验说这个 - 这就是为什么我们需要许可。

还有为总线管理创建的自动删除队列,这同样需要管理权限。

更新:仍然需要管理,但是,您也许可以绕过它。如果可以提前创建主题、队列和订阅,并且将 MassTransit 配置为不创建主题、队列或订阅,并且可能不发布错误(除非还要创建这些主题(,并且不使用错误或跳过的队列。

例如,此配置基本上会将 MassTransit 的使用限制为仅队列:

var bus = Bus.Factory.CreateUsingAzureServiceBus(cfg =>
{
    cfg.Host(...);
    cfg.ReceiveEndpoint("existing-queue", e =>
    {
        e.PublishFaults = false;
        e.ConfigureConsumeTopology = false;
        e.ConfigureDeadLetterQueueErrorTransport();
        e.ConfigureDeadLetterQueueDeadLetterTransport();
        e.Consumer(...);
    });
});

直接发送到队列的消息(queue:existing-queue 的目标地址(将由接收终结点使用,错误/跳过的消息将移动到 Azure 死信队列。仅当存在与消息类型匹配的主题名称(或者可以使用topic:existing-topic-name作为目标地址(时,才能调用 publish。