We are creating code to call a Rest api to attach a file and upload it to the host. This will be triggered by a message sent and picked up by a standard NSB message handler. We are using RestSharp to do this. We were considering using Polly to smooth out any retries etc with a policy. A colleague warned against this as they said NServiceBus should handle this natively. I have seen conflicting advice online and am tempted to still use Polly. Pros and cons? Here is the current Api code with the Polly policy.
using System;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Polly;
using RestSharp;
namespace Et.Sample.Console.Rest.Client
{
public class Post
{
private readonly string filePath;
private readonly string fileType;
private readonly string host;
private readonly int maxRetries;
private readonly string password;
private readonly string route;
private readonly string userId;
public Post()
{
filePath = ConfigurationManager.AppSettings["filePath"];
fileType = ConfigurationManager.AppSettings["fileType"];
host = ConfigurationManager.AppSettings["host"];
maxRetries = int.Parse(ConfigurationManager.AppSettings["maxretries"]);
password = ConfigurationManager.AppSettings["password"];
route = ConfigurationManager.AppSettings["route"];
userId = ConfigurationManager.AppSettings["userid"];
}
public async Task<string> Execute()
{
// Handle both exceptions and return values in one policy
HttpStatusCode[] httpStatusCodesWorthRetrying =
{
HttpStatusCode.RequestTimeout, // 408
HttpStatusCode.InternalServerError, // 500
HttpStatusCode.BadGateway, // 502
HttpStatusCode.ServiceUnavailable, // 503
HttpStatusCode.GatewayTimeout // 504
};
var result = await Policy
.Handle<HttpRequestException>()
.OrResult<RestResponse>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode))
.WaitAndRetryAsync(new[]
{
TimeSpan.FromSeconds(15),
TimeSpan.FromSeconds(30),
TimeSpan.FromSeconds(60),
TimeSpan.FromSeconds(120),
TimeSpan.FromMinutes(5)
})
.ExecuteAsync(() => ApiCall());
return result.StatusCode.ToString();
}
public async Task<RestResponse> ApiCall()
{
var options =
new RestClientOptions(host)
{
MaxTimeout = -1
};
var client = new RestClient(options);
var request =
new RestRequest(route,
Method.Post);
var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes(userId + ":" + password));
request.AddHeader("Authorization",
"Basic " + authString);
request.AlwaysMultipartFormData = true;
request.AddFile(fileType, filePath);
var response = await client.ExecuteAsync(request);
var responseContent = response.Content;
return response;
}
}
}