using System; using System.Linq.Expressions; using Hangfire; using log4net; using LeafWeb.Core.DAL; using LeafWeb.Core.Entities; using LeafWeb.Core.Remote; using Polly; namespace LeafWeb.WebCms.Services.PiscalQueue { public abstract class PiscalQueueBase : IDisposable { protected readonly DataService DataService; protected readonly PiscalService PiscalService; protected readonly ILog Logger; private readonly Policy _retryPolicy; protected PiscalQueueBase(DataService dataService, PiscalService piscalService) { DataService = dataService; PiscalService = piscalService; Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); _retryPolicy = Policy .Handle() .Retry(3, (exception, i) => Logger.Warn($"Retry {i} after exception: {exception.Message}")); } protected PiscalQueueBase() : this(new DataService(), new PiscalService()) { } protected string FormatException(Exception ex) { return (ex is PiscalClientException ? $"LeafInputId: {((PiscalClientException) ex).LeafInputId}{Environment.NewLine}" : "") + $"Class: {GetType().Name}{Environment.NewLine}" + $"Exception message: {ex.Message}{Environment.NewLine}" + (ex.InnerException != null ? $"InnerException: {ex.InnerException}{Environment.NewLine}" : string.Empty) + $"StackTrace: {ex.StackTrace}"; } protected string FormatLeafInputInfo(LeafInput leafInput) { return $"User name: {leafInput.Name}{Environment.NewLine}" + $"User email: {leafInput.Email}{Environment.NewLine}" + $"Identifier: {leafInput.Identifier}{Environment.NewLine}" + $"Site Id: {leafInput.SiteId}{Environment.NewLine}" + $"Photosynthesis Type: {leafInput.PhotosynthesisType}{Environment.NewLine}"; } protected void PiscalExceptionHandler(PiscalClientException ex, LeafInput leafInput) { var errorMessage = FormatException(ex); Logger.Error(errorMessage); // send admin an email BackgroundJobEnqueueRetry( email => email.SendAdministratorMessage( $"LeafWeb: PiscalQueue {GetType().Name} Exception", "Piscal exception reported. LeafInput info:" + Environment.NewLine + FormatLeafInputInfo(leafInput) + Environment.NewLine + "ErrorMessage:" + Environment.NewLine + errorMessage)); // send user email too BackgroundJobEnqueueRetry( email => email.SendLeafWebSystemException(leafInput.Identifier, leafInput.Email)); if (leafInput != null) { DataService.SetLeafInputStatus(leafInput, LeafInputStatusType.Exception, "Error occurred processing LeafInput", ex.Message); } } protected void PiscalWarningHandler(string warningMessage, LeafInput leafInput) { Logger.Warn(warningMessage); // send admin an email BackgroundJobEnqueueRetry( email => email.SendAdministratorMessage( $"LeafWeb: PiscalQueue {GetType().Name} Warning", "Piscal warning reported. LeafInput info:" + Environment.NewLine + FormatLeafInputInfo(leafInput) + Environment.NewLine + "Warning message:" + Environment.NewLine + warningMessage)); } public void Dispose() { DataService.Dispose(); } protected string BackgroundJobEnqueueRetry(Expression> a) { return _retryPolicy.Execute(() => BackgroundJob.Enqueue(a)); } } }