В очень простое приложение, у меня есть конечная точка, которая передает некоторые жестко запрограммированные данные в общий класс обслуживания «поставить это сообщение в очередь»:
Код: Выделить всё
public class TestFunction(IEventBusService eventBusService)
{
[Function("TestFunction")]
public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req)
{
try
{
await eventBusService.SendAsync(new TestObject { Message = "Message for service bus", SentAtDateTimeOffset = DateTimeOffset.UtcNow }, Queues.Test);
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteAsJsonAsync("Message successfully published to service bus", "application/json");
return response;
}
catch (ServiceBusOperationFailedException)
{
var response = req.CreateResponse(HttpStatusCode.InternalServerError);
await response.WriteAsJsonAsync("Unable to publish message to service bus", "application/json");
return response;
}
}
}
public class TestObject
{
public string Message { get; set; }
public DateTimeOffset SentAtDateTimeOffset { get; set; }
}
Код: Выделить всё
public class EventBusService(ServiceBusClient serviceBusClient) : IEventBusService
{
public async Task SendAsync(T dataToSend, string sendTo, CancellationToken cancellationToken = default)
{
ValidateParams(dataToSend, sendTo);
var serviceBusSender = serviceBusClient.CreateSender(sendTo);
var messageJson = new ServiceBusMessage(JsonSerializer.Serialize(dataToSend));
try
{
await serviceBusSender.SendMessageAsync(messageJson, cancellationToken);
}
catch (Exception ex)
{
throw new ServiceBusOperationFailedException($"Unable to publish message to '{sendTo}'.", ex);
}
finally
{
await serviceBusSender.DisposeAsync();
}
}
private void ValidateParams(T dataToSend, string sendTo)
{
if (dataToSend is null)
throw new ArgumentNullException(nameof(dataToSend));
if (string.IsNullOrEmpty(sendTo))
throw new ArgumentNullException(nameof(sendTo));
}
}
Чтобы убедиться, что все работает так, как ожидалось, я составил быстрый тест, который вызывал бы конечную точку...
Код: Выделить всё
[TestMethod]
public async Task Should_OnSuccessfulPublishToEventBus_ReceiveConfirmationMessage()
{
// Arrange
var testFunction = new TestFunction(EventBusHelper.CreateService());
var mockFunctionContext = EventBusHelper.GetMockFunctionContext();
//Act
var response = await testFunction.Run(new TestHttpRequestData(mockFunctionContext));
//Assert
Assert.IsNotNull(response);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
response.Body.Position = 0;
using var streamReader = new StreamReader(response.Body);
var responseBody = await streamReader.ReadToEndAsync();
Assert.AreEqual("\"Message successfully published to service bus\"", responseBody);
}
Однако, когда я посмотрел на сообщения в очереди, я увидел то же самое сообщение было добавлено в очередь дважды. С тех пор это происходило каждый раз, когда я запускал тест.
Предварительный запуск теста:
[img]https://i .sstatic.net/oJgdqLIA.png[/img]
После тестового запуска:
[img]https://i.sstatic .net/IYUaJB5W.png[/img]
Исходя из моего кода выше, есть ли какая-то причина, по которой это происходит? Я отладил и убедился, что конечная точка затрагивается только один раз, поэтому могу только думать, что это какая-то сложность организации очереди сообщений, о которой я не знаю. Любая помощь или совет приветствуются!
Спасибо,
Марк
Подробнее здесь: https://stackoverflow.com/questions/785 ... eued-twice