using System;
using System.Linq;
using System.Net.Http;
using Kreta.Core.Client.ClientProxy;
using Kreta.Core.Client.Exceptions;
using Kreta.Core.Client.MessageInvoker;
using Kreta.Naplo.Domain;
using Kreta.Naplo.Infrastructure;
using Newtonsoft.Json;
namespace Kreta.Naplo.BusinessLogic
{
///
/// Service base
///
abstract class Service : HttpClientProxy, IService
{
///
/// Api key
///
const string ApiKey = nameof(ApiKey);
///
/// The request default error message
///
const string RequestDefaultErrorMessage = "Proxy error requesting data from eKreta (for details see innerexception and request\response property).";
///
/// The error during response deserialization
///
const string ErrorDuringResponseDeserialization = "Proxy error during response deserialization when requesting data from eKreta web api (for details see innerexception and request\response property).";
///
/// The error during response deserialization
///
const string ErrorDuringRequestSerialization = "Proxy error during request serialization when requesting data from eKreta web api (for details see innerexception and request\response property)";
///
/// Relative url
///
protected string RelativeUrl { get; }
///
/// Gets or sets the context.
///
///
/// The context.
///
public ServiceContext Context { get; set; }
///
/// Handles the HTTP request error.
///
/// The request.
/// The response.
/// RequestUrl
/// The exception.
/// null
protected override void HandleHttpRequestError(HttpRequestMessage request, HttpResponseMessage response, Exception exception)
{
if (request != null && request.Headers.Contains(ApiKey))
{
request.Headers.Remove(nameof(ApiKey));
request.Headers.Add((nameof(ApiKey)), Infrastructure.Constants.SecretLogValue);
}
throw new HttpClientProxyException(RequestDefaultErrorMessage, exception, request, response);
}
///
/// Handles the deserialization error.
///
/// The response.
/// The exception.
///
protected override void HandleDeserializationError(HttpRequestMessage request, HttpResponseMessage response, JsonException exception)
{
throw new HttpClientProxyException(ErrorDuringResponseDeserialization, exception, request, response);
}
///
/// Handles the serialization error.
///
/// The request.
/// The exception.
///
protected override void HandleSerializationError(HttpRequestMessage request, JsonException exception)
{
throw new HttpClientProxyException(ErrorDuringRequestSerialization, exception, request, null);
}
///
/// Creates the request.
///
/// The HTTP method.
/// The relative URI.
/// The parameters.
/// The data.
///
protected override HttpRequestMessage CreateRequest(HttpMethod httpMethod, string relativeUrl, HttpClientProxyParameterCollection parameters, object data)
{
//add parameters
parameters.Add(new HttpClientProxyParameter(nameof(this.Context.UserId), this.Context.UserId));
var requestMessage = base.CreateRequest(httpMethod, relativeUrl, parameters, data);
//add header values
requestMessage.Headers.Add(ApiKey, this.Context.ApiKey);
requestMessage.Headers.Add(nameof(this.Context.InstituteCode), this.Context.InstituteCode);
requestMessage.Headers.Add(nameof(this.Context.SchoolYearId), this.Context.SchoolYearId.ToString());
requestMessage.Headers.Add(nameof(this.Context.UserId), this.Context.UserId.ToString());
requestMessage.Headers.Add(nameof(this.Context.UserRoles), this.Context.UserRoles != null ? string.Join(",", this.Context.UserRoles) : string.Empty);
string userAgentHeaderKey = requestMessage.Headers.FirstOrDefault(header => header.Key?.Equals(Constants.Http.Headers.UserAgent, StringComparison.OrdinalIgnoreCase) ?? false).Key;
if (userAgentHeaderKey != null)
{
requestMessage.Headers.Remove(userAgentHeaderKey);
}
requestMessage.Headers.TryAddWithoutValidation(Constants.Http.Headers.UserAgent, this.Context.UserAgent ?? string.Empty);
return requestMessage;
}
///
/// Initializes a new instance of the class.
///
/// Message invoker
/// The relative URL.
public Service(IHttpMessageInvokerFactory invokerFactory, string relativeUrl) :
base(invokerFactory, string.Empty)
{
this.RelativeUrl = relativeUrl ?? throw new ArgumentNullException(nameof(relativeUrl));
}
}
}