Skip to content

Commit

Permalink
Feature/90 optional logging (#92)
Browse files Browse the repository at this point in the history
* Optional logging.
  • Loading branch information
Sina-Soltani authored Jun 28, 2020
1 parent 5874ff1 commit e351441
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 89 deletions.
2 changes: 1 addition & 1 deletion src/Parbad/Builder/ParbadBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static IParbadBuilder AddParbad(this IServiceCollection services)

builder.Services.TryAddTransient<IGatewayProvider, DefaultGatewayProvider>();

builder.ConfigureMessages(options => { });
builder.ConfigureOptions(options => { });

builder.ConfigurePaymentToken(tokenBuilder => tokenBuilder.UseGuidQueryStringPaymentTokenProvider());

Expand Down
81 changes: 41 additions & 40 deletions src/Parbad/Internal/DefaultOnlinePayment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,24 @@ public class DefaultOnlinePayment : IOnlinePayment
private readonly IStorageManager _storageManager;
private readonly IPaymentTokenProvider _tokenProvider;
private readonly IGatewayProvider _gatewayProvider;
private readonly IOptions<MessagesOptions> _messagesOptions;
private readonly ILogger<IOnlinePayment> _logger;
private readonly ParbadOptions _options;
private readonly ILogger<DefaultOnlinePayment> _logger;

/// <summary>
/// Initializes an instance of <see cref="DefaultOnlinePayment"/>.
/// </summary>
/// <param name="services"></param>
/// <param name="storageManager"></param>
/// <param name="tokenProvider"></param>
/// <param name="gatewayProvider"></param>
/// <param name="messagesOptions"></param>
/// <param name="logger"></param>
public DefaultOnlinePayment(
IServiceProvider services,
IStorageManager storageManager,
IPaymentTokenProvider tokenProvider,
IGatewayProvider gatewayProvider,
IOptions<MessagesOptions> messagesOptions,
ILogger<IOnlinePayment> logger)
IOptions<ParbadOptions> options,
ILogger<DefaultOnlinePayment> logger)
{
Services = services;
_storageManager = storageManager;
_tokenProvider = tokenProvider;
_messagesOptions = messagesOptions;
_options = options.Value;
_logger = logger;
_storageManager = storageManager;
_gatewayProvider = gatewayProvider;
Expand All @@ -57,18 +51,18 @@ public virtual async Task<IPaymentRequestResult> RequestAsync(Invoice invoice, C
{
if (invoice == null) throw new ArgumentNullException(nameof(invoice));

_logger.LogInformation(LoggingEvents.RequestPayment, $"Requesting the invoice {invoice.TrackingNumber} is started.");
Log(logger => logger.LogInformation(LoggingEvents.RequestPayment, $"Requesting the invoice {invoice.TrackingNumber} is started."));

// Check the tracking number
if (await _storageManager.DoesPaymentExistAsync(invoice.TrackingNumber, cancellationToken).ConfigureAwaitFalse())
{
_logger.LogInformation(LoggingEvents.RequestPayment, _messagesOptions.Value.DuplicateTrackingNumber);
Log(logger => logger.LogInformation(LoggingEvents.RequestPayment, _options.Messages.DuplicateTrackingNumber));

return new PaymentRequestResult
{
TrackingNumber = invoice.TrackingNumber,
Status = PaymentRequestResultStatus.TrackingNumberAlreadyExists,
Message = _messagesOptions.Value.DuplicateTrackingNumber,
Message = _options.Messages.DuplicateTrackingNumber,
GatewayTransporter = new NullGatewayTransporter()
};
}
Expand All @@ -88,7 +82,7 @@ public virtual async Task<IPaymentRequestResult> RequestAsync(Invoice invoice, C
{
var message = $"Requesting the invoice {invoice.TrackingNumber} is finished. The payment token \"{paymentToken}\" already exists.";

_logger.LogError(LoggingEvents.RequestPayment, message);
Log(logger => logger.LogError(LoggingEvents.RequestPayment, message));

throw new PaymentTokenProviderException(message);
}
Expand Down Expand Up @@ -119,7 +113,7 @@ public virtual async Task<IPaymentRequestResult> RequestAsync(Invoice invoice, C
}
catch (Exception exception)
{
_logger.LogError(exception, exception.Message);
Log(logger => logger.LogError(exception, exception.Message));

newPayment.IsCompleted = true;
newPayment.IsPaid = false;
Expand Down Expand Up @@ -147,21 +141,21 @@ public virtual async Task<IPaymentRequestResult> RequestAsync(Invoice invoice, C

await _storageManager.CreateTransactionAsync(newTransaction, cancellationToken).ConfigureAwaitFalse();

_logger.LogInformation(LoggingEvents.RequestPayment, $"Requesting the invoice {invoice.TrackingNumber} is finished.");
Log(logger => logger.LogInformation(LoggingEvents.RequestPayment, $"Requesting the invoice {invoice.TrackingNumber} is finished."));

return requestResult;
}

/// <inheritdoc />
public virtual async Task<IPaymentFetchResult> FetchAsync(CancellationToken cancellationToken = default)
{
_logger.LogInformation(LoggingEvents.FetchPayment, "Fetching is started.");
Log(logger => logger.LogInformation(LoggingEvents.FetchPayment, "Fetching is started."));

var paymentToken = await _tokenProvider.RetrieveTokenAsync(cancellationToken).ConfigureAwaitFalse();

if (string.IsNullOrEmpty(paymentToken))
{
_logger.LogError(LoggingEvents.FetchPayment, "Fetching failed. No payment token is received.");
Log(logger => logger.LogError(LoggingEvents.FetchPayment, "Fetching failed. No payment token is received."));

throw new PaymentTokenProviderException("No Token is received.");
}
Expand All @@ -170,18 +164,18 @@ public virtual async Task<IPaymentFetchResult> FetchAsync(CancellationToken canc

if (payment == null)
{
_logger.LogError(LoggingEvents.FetchPayment, $"Fetching failed. The operation is not valid. No payment found with the token: {paymentToken}");
Log(logger => logger.LogError(LoggingEvents.FetchPayment, $"Fetching failed. The operation is not valid. No payment found with the token: {paymentToken}"));

throw new InvoiceNotFoundException(paymentToken);
}

_logger.LogInformation(LoggingEvents.FetchPayment, "Fetching is finished.");
Log(logger => logger.LogInformation(LoggingEvents.FetchPayment, "Fetching is finished."));

string message = null;

if (payment.IsCompleted)
{
message = _messagesOptions.Value.PaymentIsAlreadyProcessedBefore;
message = _options.Messages.PaymentIsAlreadyProcessedBefore;
}

return new PaymentFetchResult
Expand All @@ -199,22 +193,22 @@ public virtual async Task<IPaymentFetchResult> FetchAsync(CancellationToken canc
/// <inheritdoc />
public virtual async Task<IPaymentVerifyResult> VerifyAsync(long trackingNumber, CancellationToken cancellationToken = default)
{
_logger.LogInformation(LoggingEvents.VerifyPayment, $"Verifying the invoice {trackingNumber} is started.");
Log(logger => logger.LogInformation(LoggingEvents.VerifyPayment, $"Verifying the invoice {trackingNumber} is started."));

var payment = await _storageManager
.GetPaymentByTrackingNumberAsync(trackingNumber, cancellationToken)
.ConfigureAwaitFalse();

if (payment == null)
{
_logger.LogError(LoggingEvents.VerifyPayment, $"Verifying the invoice {trackingNumber} is failed. The operation is not valid. No payment found with the tracking number {trackingNumber}");
Log(logger => logger.LogError(LoggingEvents.VerifyPayment, $"Verifying the invoice {trackingNumber} is failed. The operation is not valid. No payment found with the tracking number {trackingNumber}"));

throw new InvoiceNotFoundException(trackingNumber);
}

if (payment.IsCompleted)
{
_logger.LogInformation(LoggingEvents.VerifyPayment, $"Verifying the invoice {trackingNumber} is finished. The requested payment is already processed before.");
Log(logger => logger.LogInformation(LoggingEvents.VerifyPayment, $"Verifying the invoice {trackingNumber} is finished. The requested payment is already processed before."));

return new PaymentVerifyResult
{
Expand All @@ -224,7 +218,7 @@ public virtual async Task<IPaymentVerifyResult> VerifyAsync(long trackingNumber,
GatewayAccountName = payment.GatewayAccountName,
TransactionCode = payment.TransactionCode,
Status = payment.IsPaid ? PaymentVerifyResultStatus.AlreadyVerified : PaymentVerifyResultStatus.Failed,
Message = _messagesOptions.Value.PaymentIsAlreadyProcessedBefore
Message = _options.Messages.PaymentIsAlreadyProcessedBefore
};
}

Expand All @@ -243,7 +237,7 @@ public virtual async Task<IPaymentVerifyResult> VerifyAsync(long trackingNumber,
}
catch (Exception exception)
{
_logger.LogError(LoggingEvents.VerifyPayment, exception, $"Verifying the invoice {trackingNumber} is finished. An error occurred during requesting.");
Log(logger => logger.LogError(LoggingEvents.VerifyPayment, exception, $"Verifying the invoice {trackingNumber} is finished. An error occurred during requesting."));
throw;
}

Expand Down Expand Up @@ -272,23 +266,23 @@ public virtual async Task<IPaymentVerifyResult> VerifyAsync(long trackingNumber,

await _storageManager.CreateTransactionAsync(transaction, cancellationToken).ConfigureAwaitFalse();

_logger.LogInformation(LoggingEvents.VerifyPayment, $"Verifying the invoice {trackingNumber} is finished.");
Log(logger => logger.LogInformation(LoggingEvents.VerifyPayment, $"Verifying the invoice {trackingNumber} is finished."));

return verifyResult;
}

/// <inheritdoc />
public virtual async Task<IPaymentCancelResult> CancelAsync(long trackingNumber, string cancellationReason = null, CancellationToken cancellationToken = default)
{
_logger.LogInformation(LoggingEvents.CancelPayment, $"Canceling the invoice {trackingNumber} is started.");
Log(logger => logger.LogInformation(LoggingEvents.CancelPayment, $"Canceling the invoice {trackingNumber} is started."));

var payment = await _storageManager
.GetPaymentByTrackingNumberAsync(trackingNumber, cancellationToken)
.ConfigureAwaitFalse();

if (payment == null)
{
_logger.LogError(LoggingEvents.CancelPayment, $"Canceling the invoice {trackingNumber} is failed. The operation is not valid. No payment found with the tracking number {trackingNumber}");
Log(logger => logger.LogError(LoggingEvents.CancelPayment, $"Canceling the invoice {trackingNumber} is failed. The operation is not valid. No payment found with the tracking number {trackingNumber}"));

throw new InvoiceNotFoundException(trackingNumber);
}
Expand All @@ -302,13 +296,13 @@ public virtual async Task<IPaymentCancelResult> CancelAsync(long trackingNumber,
GatewayName = payment.GatewayName,
GatewayAccountName = payment.GatewayAccountName,
IsSucceed = false,
Message = _messagesOptions.Value.PaymentIsAlreadyProcessedBefore
Message = _options.Messages.PaymentIsAlreadyProcessedBefore
};
}

var message = cancellationReason ?? _messagesOptions.Value.PaymentCanceledProgrammatically;
var message = cancellationReason ?? _options.Messages.PaymentCanceledProgrammatically;

_logger.LogInformation(LoggingEvents.CancelPayment, message);
Log(logger => logger.LogInformation(LoggingEvents.CancelPayment, message));

payment.IsCompleted = true;
payment.IsPaid = false;
Expand All @@ -326,7 +320,7 @@ public virtual async Task<IPaymentCancelResult> CancelAsync(long trackingNumber,

await _storageManager.CreateTransactionAsync(newTransaction, cancellationToken).ConfigureAwaitFalse();

_logger.LogInformation(LoggingEvents.CancelPayment, $"Canceling the invoice {trackingNumber} is finished.");
Log(logger => logger.LogInformation(LoggingEvents.CancelPayment, $"Canceling the invoice {trackingNumber} is finished."));

return new PaymentCancelResult
{
Expand All @@ -344,22 +338,22 @@ public virtual async Task<IPaymentRefundResult> RefundAsync(RefundInvoice invoic
{
if (invoice == null) throw new ArgumentNullException(nameof(invoice));

_logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is started.");
Log(logger => logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is started."));

var payment = await _storageManager.GetPaymentByTrackingNumberAsync(invoice.TrackingNumber, cancellationToken).ConfigureAwaitFalse();

if (payment == null)
{
_logger.LogError(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is failed. The operation is not valid. No payment found with the tracking number {invoice.TrackingNumber}");
Log(logger => logger.LogError(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is failed. The operation is not valid. No payment found with the tracking number {invoice.TrackingNumber}"));

throw new InvoiceNotFoundException(invoice.TrackingNumber);
}

if (!payment.IsCompleted)
{
var message = $"{_messagesOptions.Value.OnlyCompletedPaymentCanBeRefunded} Tracking number: {invoice.TrackingNumber}.";
var message = $"{_options.Messages.OnlyCompletedPaymentCanBeRefunded} Tracking number: {invoice.TrackingNumber}.";

_logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is finished. {message}");
Log(logger => logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is finished. {message}"));

return PaymentRefundResult.Failed(message);
}
Expand Down Expand Up @@ -394,7 +388,7 @@ public virtual async Task<IPaymentRefundResult> RefundAsync(RefundInvoice invoic
}
catch (Exception exception)
{
_logger.LogError(exception, "Parbad exception. An error occurred during requesting.");
Log(logger => logger.LogError(exception, "Parbad exception. An error occurred during requesting."));
throw;
}

Expand All @@ -417,9 +411,16 @@ public virtual async Task<IPaymentRefundResult> RefundAsync(RefundInvoice invoic

await _storageManager.CreateTransactionAsync(newtTransaction, cancellationToken).ConfigureAwaitFalse();

_logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is finished.");
Log(logger => logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is finished."));

return refundResult;
}

private void Log(Action<ILogger> logger)
{
if (!_options.EnableLogging) return;

logger(_logger);
}
}
}
3 changes: 3 additions & 0 deletions src/Parbad/Options/MessagesOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

namespace Parbad.Options
{
/// <summary>
/// Provides configuration for Parbad messages.
/// </summary>
public class MessagesOptions
{
public string PaymentSucceed { get; set; } = "Payment is successful.";
Expand Down
35 changes: 0 additions & 35 deletions src/Parbad/Options/MessagesOptionsExtensions.cs

This file was deleted.

18 changes: 18 additions & 0 deletions src/Parbad/Options/ParbadOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Parbad.Options
{
/// <summary>
/// Provides configuration for Parbad.
/// </summary>
public class ParbadOptions
{
/// <summary>
/// Enables or disables the logging. The default value is true.
/// </summary>
public bool EnableLogging { get; set; } = true;

/// <summary>
/// Contains all messages that Parbad uses in results.
/// </summary>
public MessagesOptions Messages { get; set; } = new MessagesOptions();
}
}
Loading

0 comments on commit e351441

Please sign in to comment.