Saturday, 29 June 2019

Web api: fluent validations

using System.IO;
using FluentValidation;
using Newtonsoft.Json;
using TDX.Infrastructure.Common;
using TDX.Interfaces;
using Unity;

namespace TDX.ViewModels.Validators
{
/// <summary>
/// <see cref="AbstractValidator{T}"/> object used to validate <see cref="IngestionInputValidator"/>
/// </summary>
public class IngestionInputValidator : AbstractValidator<IngestionInputViewModel>
{
#region Private Fields

/// <summary>
/// The <see cref="IUnityContainer"/>
/// </summary>
private readonly IUnityContainer _unityContainer;

private IngestionInputSetViewModel _ingestionInputSetViewModel = new IngestionInputSetViewModel();

#endregion Private Fields

#region Public Constructors

/// <summary>
/// Constructor for the <see cref="IngestionSetValidator"/> class used to add validation rules
/// </summary>
/// <param name="unityContainer"><see cref="IUnityContainer"/></param>
public IngestionInputValidator(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
RuleFor(x => x.IngestionTypeName)
.NotEmpty()
.WithMessage("Ingestion type name is required")
.DependentRules(y =>
y.RuleFor(x => x.TdxRepositoryName)
.NotEmpty()
.WithMessage("Tdx Repository name is required")
.DependentRules(z =>
z.RuleFor(x => x)
.Must(x => ValidNames(x.IngestionTypeName, x.TdxRepositoryName))
.WithMessage("Invalid Ingestion Type Name or Tdx Repository Name.")));
RuleFor(x => x)
.Must(x => HaveFileExists(x.FilePath))
.WithMessage(x => $"File Not Found ('{x.FilePath}')")
.DependentRules(y =>
y.RuleFor(x => x)
.Must(x => HaveValidTdxRunFieldNames(x.FilePath))
.WithMessage("One or more tdx repo fields are not valid"))
.DependentRules(z =>
z.RuleFor(x => x)
.Must(HaveValidTdxRunFiles)
.WithMessage("One or more tdx run file type group name or tdx file type name are not valid"));
}

#endregion Public Constructors

#region Private Methods

/// <summary>
/// Have valid ingestion type name
/// </summary>
/// <param name="ingestionTypeName">Ingestion Type Name</param>
/// <param name="tdxRepositoryName">TDX Repository Name</param>
/// <returns>Flag denoting whether ingestion type name is valid</returns>
private bool ValidNames(string ingestionTypeName, string tdxRepositoryName)
{
var ingestionTypeService = _unityContainer.Resolve<IIngestionTypeService>();
return ingestionTypeService.GetIngestionType(ingestionTypeName, tdxRepositoryName) != null;
}

/// <summary>
/// To check file existance.
/// </summary>
/// <param name="filePath">File path of .json</param>
/// <returns>return true if file exists</returns>
private bool HaveFileExists(string filePath)
{
using (new Impersonator())
{
return File.Exists(filePath);
}
}

/// <summary>
/// To check all the file collection as valid tdx run file type group name and
/// tdx file type name
/// </summary>
/// <param name="arg"></param>
///  <returns><code>True</code> if all the file collection as valid tdx run file type group name and
///  tdx file type name.</returns>
private bool HaveValidTdxRunFiles(IngestionInputViewModel arg)
{
var repositoryFileTypeGroupService = _unityContainer.Resolve<IRepositoryFileTypeGroupService>();
var tdxFileTypeService = _unityContainer.Resolve<ITdxFileTypeService>();

foreach (var item in _ingestionInputSetViewModel.FileCollections)
{
var repoFileTypeGrp = repositoryFileTypeGroupService
.GetRepositoryFileTypeGroupByName(item.Name);

var repoField = tdxFileTypeService
.GetTdxFileTypeByName(item.TdxFileType);

if (repoFileTypeGrp == null || repoField == null)
return false;
}

return true;
}

/// <summary>
/// To check all the tdx files has valid names.
/// </summary>
/// <param name="filePath">.json file path</param>
/// <returns><code>True</code> if all the tdx run file names are valid.</returns>
private bool HaveValidTdxRunFieldNames(string filePath)
{
var repositoryFieldService = _unityContainer.Resolve<IRepositoryFieldService>();
var file = Path.Combine(filePath);

using (new Impersonator())
using (var fileStream = File.OpenRead(file))
using (var streamReader = new StreamReader(fileStream))
using (var jsonReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
_ingestionInputSetViewModel = serializer.Deserialize<IngestionInputSetViewModel>(jsonReader);
}

foreach (var item in _ingestionInputSetViewModel.Fields)
{
var tdxRepoField = repositoryFieldService.GeTdxRepositoryFieldByName(item.Name);
if (tdxRepoField == null) return false;
}

return true;
}

#endregion Private Methods
}
}

web api: Action filter

using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace TDX.Filters
{
    /// <summary>
    /// <see cref="ActionFilterAttribute"/> used to specify that the model state should be validated.
    /// </summary>
    public class ValidateModelStateFilter : ActionFilterAttribute
{
#region Public Members

/// <summary>
/// Override used to check the model state for a given request and return an error response if it is invalid.
/// </summary>
/// <param name="actionContext">The <see cref="HttpActionContext"/> associated with the request.</param>
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Response = actionContext.Request.CreateErrorResponse((HttpStatusCode)422, actionContext.ModelState);
}
}

#endregion
}
}