I have the following workflow:

  1. Service bus receives messages.
  2. Azure function triggers and tries to deliver this messages via HTTP to some service.
  3. If delivery failed - function throws exception (custom) and disables topic subscription via code below:

enter image description here

  1. The other function in parallel pings special health check endpoint of the service, and if it gets 200 - it tries to enable subscription and make the flow work again.
  2. The steps could be reproduced N times, cause health check will return 200, thus the delivery url of point 2 - 4xx code.

After the next attempt to enable subscription and deliver the message, I expect that delivery count will be increased and in the end (after 10 deliveries attempt) it will get to dead-letter. Actual - it equals 1.

enter image description here

I assume, that it may reset when I call CreateOrUpdate with status changed. If yes - what is the other way to manage subscription status instead of Microsoft.Azure.Management package so that the messages delivery count will not be reset?

UPDATE: Function code

public static class ESBTESTSubscriptionTrigger
{
    private static readonly HttpClient Client = new HttpClient();

    private static IDatabase redisCache;

    [FunctionName("ESBTESTSubscriptionTrigger")]
    [Singleton]
    public static async Task Run([ServiceBusTrigger("Notifications", "ESBTEST", AccessRights.Listen, Connection = "NotificationsBusConnectionString")]BrokeredMessage serviceBusMessage, TraceWriter log, [Inject]IKeyVaultSecretsManager keyVaultSecretsManager)
    {
        var logicAppUrl = await keyVaultSecretsManager.GetSecretAsync("NotificationsLogicAppUrl");

        if (redisCache == null)
        {
            redisCache = RedisCacheConnectionManager.GetRedisCacheConnection(
                keyVaultSecretsManager.GetSecretAsync("RedisCacheConnectionString").GetAwaiter().GetResult());
        }

        if (string.IsNullOrWhiteSpace(logicAppUrl))
        {
            log.Error("Logic App URL should be provided in Application settings of function App.");
            throw new ParameterIsMissingException("Logic App URL should be provided in Application settings of function App.");
        }

        var applicaitonId = serviceBusMessage.Properties["applicationId"].ToString();
        var eventName = serviceBusMessage.Properties.ContainsKey("Event-Name") ? serviceBusMessage.Properties["Event-Name"].ToString() : string.Empty;
        if (string.IsNullOrWhiteSpace(applicaitonId))
        {
            log.Error("ApplicationId should be present in service bus message properties.");
            throw new ParameterIsMissingException("Application id is missing in service bus message.");
        }

        Stream stream = serviceBusMessage.GetBody<Stream>();
        StreamReader reader = new StreamReader(stream);
        string s = reader.ReadToEnd();

        var content = new StringContent(s, Encoding.UTF8, "application/json");
        content.Headers.Add("ApplicationId", applicaitonId);

        HttpResponseMessage response;
        try
        {
            response = await Client.PostAsync(logicAppUrl, content);
        }
        catch (HttpRequestException e)
        {
            log.Error($"Logic App responded with {e.Message}");
            throw new LogicAppBadRequestException($"Logic App responded with {e.Message}", e);
        }

        if (!response.IsSuccessStatusCode)
        {
            log.Error($"Logic App responded with {response.StatusCode}");

            var serviceBusSubscriptionsSwitcherUrl = await keyVaultSecretsManager.GetSecretAsync("ServiceBusTopicSubscriptionSwitcherUri");
            var sbSubscriptionSwitcherResponse = await Client.SendAsync(
                                                     new HttpRequestMessage(HttpMethod.Post, serviceBusSubscriptionsSwitcherUrl)
                                                         {
                                                             Content =
                                                                 new
                                                                     StringContent(
                                                                         $"{{\"Action\":\"Disable\",\"SubscriptionName\":\"{applicaitonId}\"}}",
                                                                         Encoding.UTF8,
                                                                         "application/json")
                                                         });

            if (sbSubscriptionSwitcherResponse.IsSuccessStatusCode == false)
            {
                throw new FunctionNotAvailableException($"ServiceBusTopicSubscriptionSwitcher responded with {sbSubscriptionSwitcherResponse.StatusCode}");
            }

            throw new LogicAppBadRequestException($"Logic App responded with {response.StatusCode}");
        }

        if (!string.IsNullOrWhiteSpace(eventName))
        {
            redisCache.KeyDelete($"{applicaitonId}{eventName}DeliveryErrorEmailSent");
        }
    }
}
0

There are 0 best solutions below