public static async Task <IActionResult> GetCustomerByIdAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "v1/customers/{id}")] HttpRequest req, string id, [Inject] IMediator mediator, [Inject] IMapper mapper, [Inject] IServerlessLogger serverlessLogger, [Inject] IHttpContextAccessor acessor, [Inject] Presenter presenter, [Inject] BadRequestPresenter badRequestPresenter, ILogger log) { serverlessLogger.InjectLogger(log); var functionMiddleware = new GetCustomerByIdFunctionMiddleware( req, id, mediator, mapper, presenter, badRequestPresenter, serverlessLogger); return(await functionMiddleware.ExecutePipeline(serverlessLogger, req, acessor, true) .ConfigureAwait(false)); }
public CreateCustomerRepository( IDatabaseFactory <SqlServerDatabase> sqlDatabase, IServerlessLogger logger) { this.sqlDatabase = sqlDatabase.Create(); this.logger = logger; }
/// <summary> /// Initializes a new instance of the <see cref="LoggingHandler"/> class. /// </summary> /// <param name="serverlessLogger">See <see cref="IServerlessLogger"/>.</param> /// <param name="transactionFlow">See <see cref="ITransactionFlow"/>.</param> public LoggingHandler( IServerlessLogger serverlessLogger, ITransactionFlow transactionFlow) { this.serverlessLogger = serverlessLogger; this.transactionFlow = transactionFlow; }
private static List <HttpMiddleware> GetMiddlewares( HttpMiddleware functionMiddleware, IServerlessLogger serverlessLogger, IHttpContextAccessor acessor, bool allowAnonymous) { var exceptionMiddleware = new ExceptionMiddleware(serverlessLogger); var loggerMiddleware = new LoggerMiddleware(serverlessLogger); var headerMiddleware = new HeaderMiddleware(); List <HttpMiddleware> middlewares = null; if (allowAnonymous) { middlewares = MiddlewaresWithoutAuth( functionMiddleware, exceptionMiddleware, loggerMiddleware, headerMiddleware); } else { middlewares = MiddlewaresWithAuth( functionMiddleware, serverlessLogger, acessor, exceptionMiddleware, loggerMiddleware, headerMiddleware); } return(middlewares); }
/// <summary> /// Extract correlationId value from <see cref="EventData"/> properties. /// </summary> /// <param name="serverlessLogger">Logger to save log with correlationId extracted.</param> /// <param name="patternLog">Pattern log.</param> /// <returns>CorrelationId value extracted.</returns> public static string GetCorrelationId(IServerlessLogger serverlessLogger, string patternLog) { var correlationId = Guid.NewGuid(); serverlessLogger.LogInformation($"{patternLog} Processing document with {nameof(correlationId)}: {correlationId}!"); return(correlationId.ToString()); }
/// <summary> /// Create pattern log. /// </summary> /// <param name="className">Name of trigger class.</param> /// <param name="serverlessLogger">Logger to save log with pattern created and execution time.</param> /// <returns>Pattern log created.</returns> public static string CreatePatternLog(string className, IServerlessLogger serverlessLogger) { var pattern = $"[{Guid.NewGuid()} | {className}] "; serverlessLogger.LogInformation($"C# Timer trigger function executed at: {DateTime.UtcNow}"); return(pattern); }
/// <summary> /// Extract correlationId value from <see cref="EventData"/> properties. /// </summary> /// <param name="eventData">Event data.</param> /// <param name="serverlessLogger">Logger to save log with correlationId extracted.</param> /// <param name="patternLog">Pattern log.</param> /// <returns>CorrelationId value extracted.</returns> public static string GetCorrelationId(EventData eventData, IServerlessLogger serverlessLogger, string patternLog) { var properties = eventData.Properties; properties.TryGetValue("correlationId", out var correlationId); serverlessLogger.LogInformation($"{patternLog} Processing event with {nameof(correlationId)}: {correlationId}!"); return((correlationId ?? Guid.NewGuid()).ToString()); }
/// <summary> /// Initializes a new instance of the <see cref="MiddlewarePipeline"/> class. /// </summary> /// <param name="pipeline">List of <see cref="HttpMiddleware"/> to build a pipeline.</param> /// <param name="serverlessLogger">Logger to log error in case of fail.</param> public MiddlewarePipeline(List <HttpMiddleware> pipeline, IServerlessLogger serverlessLogger) { this.serverlessLogger = serverlessLogger ?? throw new ArgumentNullException(nameof(serverlessLogger)); if (pipeline != null) { foreach (var httpMiddleware in pipeline) { Register(httpMiddleware); } } }
public static object ConvertToJson(string data, IServerlessLogger serverlessLogger) { try { return(string.IsNullOrWhiteSpace(data) ? null : JsonConvert.DeserializeObject(data)); } catch (Exception ex) { serverlessLogger.LogError(ex, $"{nameof(LoggerHelper)} -> Fail using {nameof(ConvertToJson)}: data -> {data}. message: {ex.Message}"); return(data); } }
/// <summary> /// Execute middleware pipeline. /// </summary> /// <param name="functionMiddleware">Function logic as middleware to be called inside pipeline.</param> /// <param name="serverlessLogger">Modal logger.</param> /// <param name="request">Function http request.</param> /// <param name="acessor">See <see cref="IHttpContextAccessor"/>.</param> /// <param name="allowAnonymous">If true, it allows access to the endpoint without authentication.(Default: false)</param> /// <returns>Response <see cref="IActionResult"/> after pipeline execution.</returns> public static async Task <IActionResult> ExecutePipeline( this HttpMiddleware functionMiddleware, IServerlessLogger serverlessLogger, HttpRequest request, IHttpContextAccessor acessor, bool allowAnonymous = false) { var middlewares = GetMiddlewares(functionMiddleware, serverlessLogger, acessor, allowAnonymous); return(await new MiddlewarePipeline(middlewares, serverlessLogger) .ExecuteAsync(HttpFunctionContext.Build(request)) .ConfigureAwait(false)); }
public GetCustomerByIdUseCase( IMediator mediator, IMapper mapper, IServerlessLogger logger, ITransactionFlow transactionFlow, IGetCustomerByIdRepository getCustomerByIdRepository) : base(mediator, logger) { this.mapper = mapper; this.logger = logger; this.transactionFlow = transactionFlow; this.getCustomerByIdRepository = getCustomerByIdRepository; }
public CreateCustomerUseCase( IMediator mediator, IMapper mapper, IServerlessLogger logger, ITransactionFlow transactionFlow, ICreateCustomerRepository createCustomerRepository) : base(mediator, logger) { this.mapper = mapper; this.logger = logger; this.transactionFlow = transactionFlow; this.createCustomerRepository = createCustomerRepository; }
/// <summary> /// Initializes a new instance of the <see cref="AuthenticationMiddleware"/> class. /// </summary> /// <param name="serverlessLogger">Modal logger.</param> /// <param name="issuer">Authentication issuer.</param> /// <param name="audience">Authentication audience.</param> /// <param name="metadataAddress">Authentication metadata address.</param> /// <param name="acessor">See <see cref="IHttpContextAccessor"/>.</param> /// <param name="isDebug">True if environment is debug mode. Otherwise, false.</param> public AuthenticationMiddleware( IServerlessLogger serverlessLogger, string issuer, string audience, string metadataAddress, IHttpContextAccessor acessor, bool isDebug = false) { this.serverlessLogger = serverlessLogger; this.issuer = issuer; this.audience = audience; this.metadataAddress = metadataAddress; this.acessor = acessor; this.isDebug = isDebug; }
public CreateCustomerFunctionMiddleware( HttpRequest req, IMediator mediator, IMapper mapper, Presenter presenter, BadRequestPresenter badRequestPresenter, IServerlessLogger logger) { this.req = req; this.mediator = mediator; this.mapper = mapper; this.presenter = presenter; this.badRequestPresenter = badRequestPresenter; this.logger = logger; }
/// <summary> /// Start event hub process. /// </summary> /// <param name="serverlessLogger">Logger to save log.</param> /// <param name="logger">Logger to be injected in <paramref name="serverlessLogger"/>.</param> /// <param name="patternLog">Pattern log.</param> /// <param name="events">Events to be processed.</param> /// <param name="processEventAsync">Process with business rules to be processed.</param> /// <param name="publishPoisonedEventAsync">Function receiving error parameter to publish poisoned event data.</param> /// <param name="eventReliabilitySettings">Event reliability settings.</param> /// <returns>Task executed.</returns> public static async Task StartEventProcessAsync( IServerlessLogger serverlessLogger, ILogger logger, string patternLog, EventData[] events, Func <EventData, Task> processEventAsync, Func <EventData, Exception, Task> publishPoisonedEventAsync, EventReliabilitySettings eventReliabilitySettings) { try { serverlessLogger.InjectLogger(logger); if (events.Length == 0) { serverlessLogger.LogWarning($"{patternLog} No event to process."); return; } serverlessLogger.LogInformation($"{patternLog} Start processing..."); var waitAndRetryAsync = GetWaitAndRetry(eventReliabilitySettings); var eventCount = events.Length; for (int eventIndex = 0; eventIndex < eventCount; eventIndex++) { serverlessLogger.LogInformation($"{patternLog} Processing event index {eventIndex}..."); var eventData = events[eventIndex]; var fallbackAsync = GetFallback(serverlessLogger, patternLog, eventData, publishPoisonedEventAsync); await Policy .WrapAsync(fallbackAsync, waitAndRetryAsync) .ExecuteAsync(() => processEventAsync(eventData)) .ConfigureAwait(false); serverlessLogger.LogInformation($"{patternLog} Event index {eventIndex} processed!"); } serverlessLogger.LogInformation($"{patternLog} Processing completed!"); } catch (Exception ex) { serverlessLogger.LogError(ex, $"{patternLog} Processing failed!"); throw; } }
private static Polly.Fallback.AsyncFallbackPolicy GetFallback( IServerlessLogger serverlessLogger, string patternLog, EventData eventData, Func <EventData, Exception, Task> publishPoisonedEventAsync) { return(Policy .Handle <Exception>() .FallbackAsync( (exception, context, cancellationToken) => publishPoisonedEventAsync(eventData, exception), (exception, context) => { serverlessLogger.LogError(exception, $"{patternLog} Processing failed!"); return Task.CompletedTask; })); }
public GetCustomerByIdFunctionMiddleware( HttpRequest req, string id, IMediator mediator, IMapper mapper, Presenter presenter, BadRequestPresenter badRequestPresenter, IServerlessLogger logger) { this.req = req; this.id = id; this.mediator = mediator; this.mapper = mapper; this.presenter = presenter; this.badRequestPresenter = badRequestPresenter; this.logger = logger; }
/// <summary> /// End event process logging notification messages. /// </summary> /// <typeparam name="TResult">Type of result data.</typeparam> /// <param name="result">Result data. If the object is null, throw exception. Otherwise, the event was processed successfully.</param> /// <param name="correlationId">Correlation id.</param> /// <param name="notificationUseCase">Use case to extract notifications.</param> /// <param name="serverlessLogger">Logger to save log.</param> /// <param name="patternLog">Pattern log.</param> public static void EndEventProcess <TResult>( TResult result, string correlationId, DomainNotificationUseCase notificationUseCase, IServerlessLogger serverlessLogger, string patternLog) where TResult : IResult { if (result == null) { if (notificationUseCase.HasNotifications()) { var errors = GetAllMessageErrors(correlationId, notificationUseCase, patternLog); throw new Exception(errors); } throw new Exception($"{patternLog} Event item with {nameof(correlationId)}: {correlationId} processing failed."); } serverlessLogger.LogInformation($"{patternLog} Event item with {nameof(correlationId)}: {correlationId} successfully processed!"); }
/// <summary> /// Start cosmosdb process. /// </summary> /// <param name="serverlessLogger">Logger to save log.</param> /// <param name="logger">Logger to be injected in <paramref name="serverlessLogger"/>.</param> /// <param name="patternLog">Pattern log.</param> /// <param name="documents">Documents to be processed.</param> /// <param name="func">Process with business rules to be processed.</param> /// <returns>Task executed.</returns> public static async Task StartDocumentProcessAsync( IServerlessLogger serverlessLogger, ILogger logger, string patternLog, IReadOnlyList <Document> documents, Func <Document, Task> func) { try { serverlessLogger.InjectLogger(logger); if (documents.Count == 0) { serverlessLogger.LogWarning($"{patternLog} No document to process."); return; } serverlessLogger.LogInformation($"{patternLog} Start processing..."); var documentCount = documents.Count; for (int documentIndex = 0; documentIndex < documentCount; documentIndex++) { var document = documents[documentIndex]; serverlessLogger.LogInformation($"{patternLog} Processing document index: {documentIndex}, id: {document.Id} and resourceId: {document.ResourceId}!"); await func(document).ConfigureAwait(false); serverlessLogger.LogInformation($"{patternLog} Document index {documentIndex} processed!"); } serverlessLogger.LogInformation($"{patternLog} Processing completed!"); } catch (Exception ex) { serverlessLogger.LogError(ex, $"{patternLog} Processing failed!"); throw; } }
/// <summary> /// Start event hub process. /// </summary> /// <param name="serverlessLogger">Logger to save log.</param> /// <param name="logger">Logger to be injected in <paramref name="serverlessLogger"/>.</param> /// <param name="patternLog">Pattern log.</param> /// <param name="events">Events to be processed.</param> /// <param name="func">Process with business rules to be processed.</param> /// <returns>Task executed.</returns> public static async Task StartEventProcessAsync( IServerlessLogger serverlessLogger, ILogger logger, string patternLog, EventData[] events, Func <EventData, Task> func) { try { serverlessLogger.InjectLogger(logger); if (events.Length == 0) { serverlessLogger.LogWarning($"{patternLog} No event to process."); return; } serverlessLogger.LogInformation($"{patternLog} Start processing..."); var eventCount = events.Length; for (int eventIndex = 0; eventIndex < eventCount; eventIndex++) { serverlessLogger.LogInformation($"{patternLog} Processing event index {eventIndex}..."); await func(events[eventIndex]).ConfigureAwait(false); serverlessLogger.LogInformation($"{patternLog} Event index {eventIndex} processed!"); } serverlessLogger.LogInformation($"{patternLog} Processing completed!"); } catch (Exception ex) { serverlessLogger.LogError(ex, $"{patternLog} Processing failed!"); throw; } }
private static List <HttpMiddleware> MiddlewaresWithAuth(HttpMiddleware functionMiddleware, IServerlessLogger serverlessLogger, IHttpContextAccessor acessor, ExceptionMiddleware exceptionMiddleware, LoggerMiddleware loggerMiddleware, HeaderMiddleware headerMiddleware) { var authenticationMiddleware = new AuthenticationMiddleware( serverlessLogger, Environment.GetEnvironmentVariable("AUTH.ISSUER"), Environment.GetEnvironmentVariable("AUTH.AUDIENCE"), Environment.GetEnvironmentVariable("AUTH.METADATAADDRESS"), acessor); return(new List <HttpMiddleware>() { loggerMiddleware, headerMiddleware, exceptionMiddleware, authenticationMiddleware, functionMiddleware }); }
internal void CreateRequestData(HttpContext context, string requestBody, DateTimeOffset start, IServerlessLogger serverlessLogger) { Request = new LogApiRequest(); StartTimestamp = start; Request.Body = LoggerHelper.ConvertToJson(requestBody, serverlessLogger); Request.Method = context?.Request?.Method; Request.Url = $"{context?.Request.Scheme}://{context?.Request.Host}{context?.Request.Path.ToString()}"; Request.Headers = context?.Request?.Headers?.ToDictionary(h => h.Key, h => h.Value); }
/// <summary> /// Initializes a new instance of the <see cref="LoggerMiddleware"/> class. /// </summary> /// <param name="serverlessLogger"></param> public LoggerMiddleware(IServerlessLogger serverlessLogger) { this.serverlessLogger = serverlessLogger; }
internal void CreateResponseData(HttpContext context, string responseBody, DateTimeOffset end, IServerlessLogger serverlessLogger) { Response = new LogApiResponse(); EndTimestamp = end; Response.Body = LoggerHelper.ConvertToJson(responseBody, serverlessLogger); Response.StatusCode = (context?.Response?.StatusCode).GetValueOrDefault(); Response.Headers = context?.Response?.Headers?.ToDictionary(h => h.Key, h => h.Value); }
/// <summary> /// Initializes a new instance of the <see cref="HttpMessageHandlerBehavior"/> class. /// </summary> /// <param name="transactionFlow"></param> /// <param name="logger"></param> public HttpMessageHandlerBehavior(ITransactionFlow transactionFlow, IServerlessLogger logger) { this.transactionFlow = transactionFlow; this.logger = logger; }
/// <summary> /// Initializes a new instance of the <see cref="ExceptionMiddleware"/> class. /// </summary> /// <param name="serverlessLogger">Logger to log error.</param> public ExceptionMiddleware(IServerlessLogger serverlessLogger) { this.serverlessLogger = serverlessLogger ?? throw new ArgumentNullException(nameof(serverlessLogger)); }
/// <summary> /// Initializes a new instance of the <see cref="LogWcf"/> class. /// </summary> /// <param name="logger"></param> /// <param name="transactionFlow"></param> public LogWcf(IServerlessLogger logger, ITransactionFlow transactionFlow) { this.logger = logger; this.transactionFlow = transactionFlow; }