From 0c5fc6e4569899480737ae7f85a09d3cd798a19e Mon Sep 17 00:00:00 2001 From: Yuriy Durov Date: Tue, 19 Sep 2023 16:05:03 +0400 Subject: [PATCH] Version-specific validators (#12) * Add OcpiValidator base class These validators will use a specific OCPI version to validate it's entities * Working on OcpiValidator * Forward current OcpiVersion to OcpiValidators * Working on validators for different OCPI versions * Improve sample app * Validator improvements --- OCPI.Net.sln | 6 ++ .../Attributes/OcpiAuthorizeAttribute.cs | 2 +- ...roller.cs => OcpiCredentialsController.cs} | 17 +++-- .../OcpiLocationsReceiverController.cs | 74 +++++++++++++++++++ .../OcpiLocationsSenderController.cs | 62 ++++++++++++++++ ...ontroller.cs => OcpiVersionsController.cs} | 4 +- .../Models/OcpiControllerBase.cs | 3 +- .../Models/OcpiDateTimeConverter.cs | 2 +- .../Extensions/AddOcpiValidationExtension.cs | 13 +++- .../OCPI.Net.Validation.csproj | 6 ++ .../Utility/GetCurrentOcpiVersionExtension.cs | 19 +++++ .../OcpiEnumValidationExtensions.cs | 18 ----- .../OcpiAdditionalGeolocationValidator.cs | 6 +- .../!General/OcpiBusinessDetailsValidator.cs | 6 +- .../!General/OcpiDisplayTextValidator.cs | 4 +- .../!General/OcpiGeolocationValidator.cs | 4 +- .../Validators/!General/OcpiImageValidator.cs | 6 +- .../Validators/!General/OcpiPriceValidator.cs | 4 +- .../Validators/Base/OcpiValidator.cs | 30 ++++++++ .../OcpiCredentialsRoleValidator.cs | 8 +- .../Credentials/OcpiCredentialsValidator.cs | 6 +- .../Energy/OcpiEnergyMixValidator.cs | 8 +- .../Energy/OcpiEnergySourceValidator.cs | 6 +- .../OcpiEnvironmentalImpactValidator.cs | 6 +- .../Location/OcpiConnectorValidator.cs | 24 ++++-- .../Validators/Location/OcpiEvseValidator.cs | 33 ++++++--- .../OcpiExceptionalPeriodValidator.cs | 4 +- .../Validators/Location/OcpiHoursValidator.cs | 10 +-- .../Location/OcpiLocationValidator.cs | 72 +++++++++++------- .../Location/OcpiPublishTokenTypeValidator.cs | 6 +- .../Location/OcpiRegularHoursValidator.cs | 4 +- .../Location/OcpiStatusScheduleValidator.cs | 6 +- .../Tariff/OcpiPriceComponentValidator.cs | 6 +- .../Tariff/OcpiTariffElementValidator.cs | 8 +- .../Tariff/OcpiTariffRestrictionValidator.cs | 8 +- .../Validators/Tariff/OcpiTariffValidator.cs | 20 ++--- 36 files changed, 375 insertions(+), 146 deletions(-) rename sample/OCPI.Net.Sample/Controllers/{CredentialsController.cs => OcpiCredentialsController.cs} (87%) create mode 100644 sample/OCPI.Net.Sample/Controllers/OcpiLocationsReceiverController.cs create mode 100644 sample/OCPI.Net.Sample/Controllers/OcpiLocationsSenderController.cs rename sample/OCPI.Net.Sample/Controllers/{VersionsController.cs => OcpiVersionsController.cs} (85%) create mode 100644 src/OCPI.Net.Validation/Utility/GetCurrentOcpiVersionExtension.cs delete mode 100644 src/OCPI.Net.Validation/ValidationExtensions/OcpiEnumValidationExtensions.cs create mode 100644 src/OCPI.Net.Validation/Validators/Base/OcpiValidator.cs diff --git a/OCPI.Net.sln b/OCPI.Net.sln index fb2e6ba..a9f37db 100644 --- a/OCPI.Net.sln +++ b/OCPI.Net.sln @@ -10,6 +10,12 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{1A55D222-2CD3-4C34-AE50-74D051F25E32}" ProjectSection(SolutionItems) = preProject docs\OCPI-2.2.1.pdf = docs\OCPI-2.2.1.pdf + docs\OCPI-2.2.pdf = docs\OCPI-2.2.pdf + docs\OCPI_2.0-d2.pdf = docs\OCPI_2.0-d2.pdf + docs\OCPI_2.0.pdf = docs\OCPI_2.0.pdf + docs\OCPI_2.1.1-d2.pdf = docs\OCPI_2.1.1-d2.pdf + docs\OCPI_2.1.1.pdf = docs\OCPI_2.1.1.pdf + docs\OCPI_2.1.pdf = docs\OCPI_2.1.pdf EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OCPI.Net.Tests", "tests\OCPI.Net.Tests\OCPI.Net.Tests.csproj", "{B95AB476-AA1B-44AB-9195-6B1FC2E7BBE6}" diff --git a/sample/OCPI.Net.Sample/Attributes/OcpiAuthorizeAttribute.cs b/sample/OCPI.Net.Sample/Attributes/OcpiAuthorizeAttribute.cs index a18bab7..36264e7 100644 --- a/sample/OCPI.Net.Sample/Attributes/OcpiAuthorizeAttribute.cs +++ b/sample/OCPI.Net.Sample/Attributes/OcpiAuthorizeAttribute.cs @@ -8,7 +8,7 @@ public class OcpiAuthorizeAttribute : Attribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { - var token = GetToken(context.HttpContext.Request); + //var token = GetToken(context.HttpContext.Request); // Your authorization logic. } diff --git a/sample/OCPI.Net.Sample/Controllers/CredentialsController.cs b/sample/OCPI.Net.Sample/Controllers/OcpiCredentialsController.cs similarity index 87% rename from sample/OCPI.Net.Sample/Controllers/CredentialsController.cs rename to sample/OCPI.Net.Sample/Controllers/OcpiCredentialsController.cs index 2c3f71f..2546298 100644 --- a/sample/OCPI.Net.Sample/Controllers/CredentialsController.cs +++ b/sample/OCPI.Net.Sample/Controllers/OcpiCredentialsController.cs @@ -6,36 +6,43 @@ namespace OCPI.Sample.Controllers; [OcpiEndpoint(OcpiModule.Credentials, "Receiver", "2.2, 2.2.1")] [Route("2.2/credentials")] [Route("2.2.1/credentials")] -public class CredentialsController : OcpiController +public class OcpiCredentialsController : OcpiController { [HttpGet] public IActionResult Get() { - // Retreive requesting platform's credentials + // Your Credentials GET logic + return OcpiOk(SampleCredentials); } [HttpPost] public IActionResult Post([FromBody] OcpiCredentials credentials) { - // Register requesting platform // if (platform.IsRegistered == true) throw ApiException.MethodNotAllowed("The platform is already registered."); + + // Your Credentials POST logic + return OcpiOk(SampleCredentials); } [HttpPut] public IActionResult Put([FromBody] OcpiCredentials credentials) { - // Update requesting platform's credentials // if (platform.IsRegistered == false) throw ApiException.MethodNotAllowed("The platform has to be registered in order to perform this action."); + + // Your Credentials PUT logic + return OcpiOk(SampleCredentials); } [HttpDelete] public IActionResult Delete() { - // Unregister the requesting platform // if (platform.IsRegistered == false) throw ApiException.MethodNotAllowed("The platform has to be registered in order to perform this action."); + + // Your Credentials DELETE logic + return OcpiOk("Success"); } diff --git a/sample/OCPI.Net.Sample/Controllers/OcpiLocationsReceiverController.cs b/sample/OCPI.Net.Sample/Controllers/OcpiLocationsReceiverController.cs new file mode 100644 index 0000000..3c6be19 --- /dev/null +++ b/sample/OCPI.Net.Sample/Controllers/OcpiLocationsReceiverController.cs @@ -0,0 +1,74 @@ +using Microsoft.AspNetCore.Mvc; +using OCPI.Contracts; + +namespace OCPI.Sample.Controllers; + +[OcpiEndpoint(OcpiModule.Locations, "Receiver", "2.2, 2.2.1")] +[Route("2.2/locations")] +[Route("2.2.1/locations")] +[OcpiAuthorize] +public class OcpiLocationsReceiverController : OcpiController +{ + [HttpGet("{countryCode}/{partyId}/{locationId}")] + public IActionResult Get( + [FromRoute] string countryCode, + [FromRoute] string partyId, + [FromRoute] string locationId) + { + return OcpiOk(SampleLocation); + } + + [HttpPut("{countryCode}/{partyId}/{locationId}")] + public IActionResult Put( + [FromRoute] string countryCode, + [FromRoute] string partyId, + [FromRoute] string locationId, + [FromBody] OcpiLocation location) + { + // Use a built-in OCPI validator + OcpiValidate(location); + + // Your Location PUT logic + + return OcpiOk(location); + } + + [HttpPatch("{countryCode}/{partyId}/{locationId}")] + public IActionResult Patch( + [FromRoute] string countryCode, + [FromRoute] string partyId, + [FromRoute] string locationId, + [FromBody] OcpiLocation location) + { + // Use a built-in OCPI validator + // Validator behavior will be appropriate to PATCH + // Since this is a PATCH method + // (not throw errors on missing fields) + OcpiValidate(location); + + // Your Location PATCH logic + + return OcpiOk(location); + } + + private static OcpiLocation SampleLocation => new() + { + CountryCode = CountryCode.Belgium, + PartyId = "BEC", + Id = "LOC1", + Publish = true, + Name = "Gent Zuid", + Address = "F.Rooseveltlaan 3A", + City = "Gent", + PostalCode = "9000", + Country = "BEL", + Coordinates = new OcpiGeolocation + { + Latitude = "51.047599", + Longitude = "3.729944" + }, + ParkingType = ParkingType.OnStreet, + TimeZone = "Europe/Brussels", + LastUpdated = DateTime.UtcNow + }; +} \ No newline at end of file diff --git a/sample/OCPI.Net.Sample/Controllers/OcpiLocationsSenderController.cs b/sample/OCPI.Net.Sample/Controllers/OcpiLocationsSenderController.cs new file mode 100644 index 0000000..78b5bb3 --- /dev/null +++ b/sample/OCPI.Net.Sample/Controllers/OcpiLocationsSenderController.cs @@ -0,0 +1,62 @@ +using Microsoft.AspNetCore.Mvc; +using OCPI.Contracts; + +namespace OCPI.Sample.Controllers; + +[OcpiEndpoint(OcpiModule.Locations, "Sender", "2.2, 2.2.1")] +[Route("2.2/locations")] +[Route("2.2.1/locations")] +[OcpiAuthorize] +public class OcpiLocationsSenderController : OcpiController +{ + [HttpGet] + public IActionResult GetPage([FromQuery] OcpiPageRequest pageRequest) + { + // Set maximum Limit value + // Required for OCPI.Net PageResult handling + SetMaxLimit(pageRequest, 100); + + // Process GetPage using Offset, Limit, DateFrom, DateTo from pageRequest + + // You can use BitzArt.Pagination nuget package + // https://github.com/BitzArt/Pagination + // to handle Offset and Limit (does not handle DateFrom/DateTo), + // or implement your own OcpiPageRequest handling logic. + + // Example: + var databaseLocations = Enumerable.Range(1, 100).Select(x => + { + var location = SampleLocation; + location.Id = $"SampleLocation-{x}"; + return location; + }); + + // This will handle Offset and Limit but not DateFrom or DateTo: + var result = databaseLocations.ToPage(pageRequest); + + // Returning a PageResult in OcpiOk will process the paginated response + // and add appropriate page response headers. + return OcpiOk(result); + } + + private static OcpiLocation SampleLocation => new() + { + CountryCode = CountryCode.Belgium, + PartyId = "BEC", + Id = "LOC1", + Publish = true, + Name = "Gent Zuid", + Address = "F.Rooseveltlaan 3A", + City = "Gent", + PostalCode = "9000", + Country = "BEL", + Coordinates = new OcpiGeolocation + { + Latitude = "51.047599", + Longitude = "3.729944" + }, + ParkingType = ParkingType.OnStreet, + TimeZone = "Europe/Brussels", + LastUpdated = DateTime.UtcNow + }; +} \ No newline at end of file diff --git a/sample/OCPI.Net.Sample/Controllers/VersionsController.cs b/sample/OCPI.Net.Sample/Controllers/OcpiVersionsController.cs similarity index 85% rename from sample/OCPI.Net.Sample/Controllers/VersionsController.cs rename to sample/OCPI.Net.Sample/Controllers/OcpiVersionsController.cs index 4c5e574..4835c3d 100644 --- a/sample/OCPI.Net.Sample/Controllers/VersionsController.cs +++ b/sample/OCPI.Net.Sample/Controllers/OcpiVersionsController.cs @@ -3,13 +3,13 @@ namespace OCPI.Sample.Controllers; [Route("versions")] -public class VersionsController : OcpiController +public class OcpiVersionsController : OcpiController { // This service scans your codebase and maps all OCPI paths from // controllers marked with OcpiEndpoint attribute on startup. private readonly IOcpiVersionService _versionService; - public VersionsController(IOcpiVersionService versionService) + public OcpiVersionsController(IOcpiVersionService versionService) { _versionService = versionService; } diff --git a/src/OCPI.Net.Controllers/Models/OcpiControllerBase.cs b/src/OCPI.Net.Controllers/Models/OcpiControllerBase.cs index edab361..dd80233 100644 --- a/src/OCPI.Net.Controllers/Models/OcpiControllerBase.cs +++ b/src/OCPI.Net.Controllers/Models/OcpiControllerBase.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.Extensions.DependencyInjection; +using OCPI.Contracts; using OCPI.Services; namespace OCPI; @@ -27,7 +28,7 @@ public OkObjectResult OcpiOk([ActionResultObjectValue] object? value) public void OcpiValidate(T value) { if (value is null) return; - var validator = GetRequiredService>(); + var validator = GetRequiredService>(); var validationResult = validator.Validate(value); if (!validationResult.IsValid) diff --git a/src/OCPI.Net.Controllers/Models/OcpiDateTimeConverter.cs b/src/OCPI.Net.Controllers/Models/OcpiDateTimeConverter.cs index 3aab859..f67cdfa 100644 --- a/src/OCPI.Net.Controllers/Models/OcpiDateTimeConverter.cs +++ b/src/OCPI.Net.Controllers/Models/OcpiDateTimeConverter.cs @@ -7,7 +7,7 @@ internal class OcpiDateTimeConverter : JsonConverter { private const string _format = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffZ"; - private static readonly DateTime _start = new(2020, 1, 1); + private static readonly DateTime _start = new(2010, 1, 1); private static readonly DateTime _end = new(2100, 1, 1); public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) diff --git a/src/OCPI.Net.Validation/Extensions/AddOcpiValidationExtension.cs b/src/OCPI.Net.Validation/Extensions/AddOcpiValidationExtension.cs index 43762ed..6f2606c 100644 --- a/src/OCPI.Net.Validation/Extensions/AddOcpiValidationExtension.cs +++ b/src/OCPI.Net.Validation/Extensions/AddOcpiValidationExtension.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using OCPI.Contracts; namespace OCPI; @@ -19,16 +20,20 @@ public static WebApplicationBuilder AddOcpiValidation(this WebApplicationBuilder .Assembly.DefinedTypes .Where(x => !x.IsAbstract) .Select(x => x.DeclaringType) - .Where(x => x!.IsSubclassOfRawGeneric(typeof(ActionValidator<>))); + .Where(x => x!.IsSubclassOfRawGeneric(typeof(OcpiValidator<>)) && x!.IsGenericType == false); foreach (var type in validatorTypes) { var modelType = type!.BaseType!.GenericTypeArguments.First(); - var resultingType = typeof(ActionValidator<>).MakeGenericType(modelType); + var resultingType = typeof(OcpiValidator<>).MakeGenericType(modelType); builder.Services.AddScoped(resultingType, x => { - var actionType = x.GetRequiredService().Request.Method.ToActionType(); - var instance = Activator.CreateInstance(type, actionType); + var httpContext = x.GetRequiredService(); + var request = httpContext.Request; + + var ocpiVersion = request.GetCurrentOcpiVersion(); + var actionType = request.Method.ToActionType(); + var instance = Activator.CreateInstance(type, actionType, ocpiVersion); return instance!; }); } diff --git a/src/OCPI.Net.Validation/OCPI.Net.Validation.csproj b/src/OCPI.Net.Validation/OCPI.Net.Validation.csproj index 12d7bc8..aa36d2c 100644 --- a/src/OCPI.Net.Validation/OCPI.Net.Validation.csproj +++ b/src/OCPI.Net.Validation/OCPI.Net.Validation.csproj @@ -25,4 +25,10 @@ + + + <_Parameter1>OCPI.Net.Controllers + + + diff --git a/src/OCPI.Net.Validation/Utility/GetCurrentOcpiVersionExtension.cs b/src/OCPI.Net.Validation/Utility/GetCurrentOcpiVersionExtension.cs new file mode 100644 index 0000000..3ec59ce --- /dev/null +++ b/src/OCPI.Net.Validation/Utility/GetCurrentOcpiVersionExtension.cs @@ -0,0 +1,19 @@ +using BitzArt.EnumToMemberValue; +using Microsoft.AspNetCore.Http; + +namespace OCPI; + +internal static class GetCurrentOcpiVersionExtension +{ + public static OcpiVersion GetCurrentOcpiVersion(this HttpRequest request) + { + var path = request.Path.Value!.TrimStart('/'); + var versionLength = path.IndexOf('/'); + if (versionLength == -1) versionLength = path.Length; + + var versionString = path[..versionLength]; + + var result = versionString.ToEnum(); + return result; + } +} diff --git a/src/OCPI.Net.Validation/ValidationExtensions/OcpiEnumValidationExtensions.cs b/src/OCPI.Net.Validation/ValidationExtensions/OcpiEnumValidationExtensions.cs deleted file mode 100644 index 363f2f9..0000000 --- a/src/OCPI.Net.Validation/ValidationExtensions/OcpiEnumValidationExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using FluentValidation; - -namespace OCPI.Validation; - -public static class OcpiEnumValidationExtensions -{ - public static IRuleBuilderOptions ValidEnum(this IRuleBuilder ruleBuilder) - where TEnum : struct, Enum - => ValidEnum(ruleBuilder); - - public static IRuleBuilderOptions ValidEnum(this IRuleBuilder ruleBuilder) - where TEnum : struct, Enum => - ruleBuilder.Must(ValidEnum).WithMessage($"'{{PropertyName}}' is not of a valid value."); - - public static bool ValidEnum(TEnum? value) - where TEnum : struct, Enum => - value is null || Enum.IsDefined(value!.Value); -} diff --git a/src/OCPI.Net.Validation/Validators/!General/OcpiAdditionalGeolocationValidator.cs b/src/OCPI.Net.Validation/Validators/!General/OcpiAdditionalGeolocationValidator.cs index f462365..0548dd7 100644 --- a/src/OCPI.Net.Validation/Validators/!General/OcpiAdditionalGeolocationValidator.cs +++ b/src/OCPI.Net.Validation/Validators/!General/OcpiAdditionalGeolocationValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal partial class OcpiAdditionalGeolocationValidator : ActionValidator +internal partial class OcpiAdditionalGeolocationValidator : OcpiValidator { - public OcpiAdditionalGeolocationValidator(ActionType actionType) : base(actionType) + public OcpiAdditionalGeolocationValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Latitude) .NotEmpty() @@ -16,7 +16,7 @@ public OcpiAdditionalGeolocationValidator(ActionType actionType) : base(actionTy .ValidLongitude(); JsonRuleFor(x => x.Name!) - .SetValidator(new OcpiDisplayTextValidator(actionType)) + .SetValidator(new OcpiDisplayTextValidator(actionType, ocpiVersion)) .When(x => x.Name is not null); } } diff --git a/src/OCPI.Net.Validation/Validators/!General/OcpiBusinessDetailsValidator.cs b/src/OCPI.Net.Validation/Validators/!General/OcpiBusinessDetailsValidator.cs index ed25ac4..22804fd 100644 --- a/src/OCPI.Net.Validation/Validators/!General/OcpiBusinessDetailsValidator.cs +++ b/src/OCPI.Net.Validation/Validators/!General/OcpiBusinessDetailsValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal class OcpiBusinessDetailsValidator : ActionValidator +internal class OcpiBusinessDetailsValidator : OcpiValidator { - public OcpiBusinessDetailsValidator(ActionType actionType) : base(actionType) + public OcpiBusinessDetailsValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Name) .NotEmpty() @@ -15,6 +15,6 @@ public OcpiBusinessDetailsValidator(ActionType actionType) : base(actionType) .ValidUrl(); JsonRuleFor(x => x.Logo!) - .SetValidator(new OcpiImageValidator(actionType)); + .SetValidator(new OcpiImageValidator(actionType, ocpiVersion)); } } diff --git a/src/OCPI.Net.Validation/Validators/!General/OcpiDisplayTextValidator.cs b/src/OCPI.Net.Validation/Validators/!General/OcpiDisplayTextValidator.cs index 340e0d9..9a42877 100644 --- a/src/OCPI.Net.Validation/Validators/!General/OcpiDisplayTextValidator.cs +++ b/src/OCPI.Net.Validation/Validators/!General/OcpiDisplayTextValidator.cs @@ -2,9 +2,9 @@ namespace OCPI.Contracts; -internal class OcpiDisplayTextValidator : ActionValidator +internal class OcpiDisplayTextValidator : OcpiValidator { - public OcpiDisplayTextValidator(ActionType actionType) : base(actionType) + public OcpiDisplayTextValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Language) .NotEmpty() diff --git a/src/OCPI.Net.Validation/Validators/!General/OcpiGeolocationValidator.cs b/src/OCPI.Net.Validation/Validators/!General/OcpiGeolocationValidator.cs index 1a04e55..5e5610d 100644 --- a/src/OCPI.Net.Validation/Validators/!General/OcpiGeolocationValidator.cs +++ b/src/OCPI.Net.Validation/Validators/!General/OcpiGeolocationValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal partial class OcpiGeolocationValidator : ActionValidator +internal partial class OcpiGeolocationValidator : OcpiValidator { - public OcpiGeolocationValidator(ActionType actionType) : base(actionType) + public OcpiGeolocationValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Latitude) .NotEmpty() diff --git a/src/OCPI.Net.Validation/Validators/!General/OcpiImageValidator.cs b/src/OCPI.Net.Validation/Validators/!General/OcpiImageValidator.cs index af4faf6..8e98d14 100644 --- a/src/OCPI.Net.Validation/Validators/!General/OcpiImageValidator.cs +++ b/src/OCPI.Net.Validation/Validators/!General/OcpiImageValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal class OcpiImageValidator : ActionValidator +internal class OcpiImageValidator : OcpiValidator { - public OcpiImageValidator(ActionType actionType) : base(actionType) + public OcpiImageValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Url) .NotEmpty() @@ -16,7 +16,7 @@ public OcpiImageValidator(ActionType actionType) : base(actionType) JsonRuleFor(x => x.Category) .NotEmpty() - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.Type) .NotEmpty() diff --git a/src/OCPI.Net.Validation/Validators/!General/OcpiPriceValidator.cs b/src/OCPI.Net.Validation/Validators/!General/OcpiPriceValidator.cs index cc6c35a..d2a119c 100644 --- a/src/OCPI.Net.Validation/Validators/!General/OcpiPriceValidator.cs +++ b/src/OCPI.Net.Validation/Validators/!General/OcpiPriceValidator.cs @@ -2,9 +2,9 @@ namespace OCPI.Contracts; -internal class OcpiPriceValidator : ActionValidator +internal class OcpiPriceValidator : OcpiValidator { - public OcpiPriceValidator(ActionType actionType) : base(actionType) + public OcpiPriceValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.ExclVat) .NotEmpty(); diff --git a/src/OCPI.Net.Validation/Validators/Base/OcpiValidator.cs b/src/OCPI.Net.Validation/Validators/Base/OcpiValidator.cs new file mode 100644 index 0000000..35a5e88 --- /dev/null +++ b/src/OCPI.Net.Validation/Validators/Base/OcpiValidator.cs @@ -0,0 +1,30 @@ +using BitzArt.EnumToMemberValue; +using FluentValidation; + +namespace OCPI.Contracts; + +internal abstract class OcpiValidator : ActionValidator +{ + protected readonly OcpiVersion OcpiVersion; + + protected OcpiValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType) + { + OcpiVersion = ocpiVersion; + } + + public IConditionBuilder WhenOcpiVersionAbove(string version, Action action) + => WhenOcpiVersionAbove(version.ToEnum(), action); + + public IConditionBuilder WhenOcpiVersionAbove(OcpiVersion version, Action action) + { + return When((T x) => version > OcpiVersion, action); + } + + public IConditionBuilder WhenOcpiVersionBelow(string version, Action action) + => WhenOcpiVersionBelow(version.ToEnum(), action); + + public IConditionBuilder WhenOcpiVersionBelow(OcpiVersion version, Action action) + { + return When((T x) => version < OcpiVersion, action); + } +} diff --git a/src/OCPI.Net.Validation/Validators/Credentials/OcpiCredentialsRoleValidator.cs b/src/OCPI.Net.Validation/Validators/Credentials/OcpiCredentialsRoleValidator.cs index bb9e5ca..8a36c88 100644 --- a/src/OCPI.Net.Validation/Validators/Credentials/OcpiCredentialsRoleValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Credentials/OcpiCredentialsRoleValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal class OcpiCredentialsRoleValidator : ActionValidator +internal class OcpiCredentialsRoleValidator : OcpiValidator { - public OcpiCredentialsRoleValidator(ActionType actionType) : base(actionType) + public OcpiCredentialsRoleValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.CountryCode) .NotEmpty() @@ -17,12 +17,12 @@ public OcpiCredentialsRoleValidator(ActionType actionType) : base(actionType) JsonRuleFor(x => x.Role) .NotEmpty() - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.BusinessDetails) .NotEmpty(); JsonRuleFor(x => x.BusinessDetails!) - .SetValidator(new OcpiBusinessDetailsValidator(actionType)); + .SetValidator(new OcpiBusinessDetailsValidator(actionType, ocpiVersion)); } } diff --git a/src/OCPI.Net.Validation/Validators/Credentials/OcpiCredentialsValidator.cs b/src/OCPI.Net.Validation/Validators/Credentials/OcpiCredentialsValidator.cs index 85f889b..62f650d 100644 --- a/src/OCPI.Net.Validation/Validators/Credentials/OcpiCredentialsValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Credentials/OcpiCredentialsValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Validation; -internal class OcpiCredentialsValidator : ActionValidator +internal class OcpiCredentialsValidator : OcpiValidator { - public OcpiCredentialsValidator(ActionType actionType) : base(actionType) + public OcpiCredentialsValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Token) .NotEmpty() @@ -22,6 +22,6 @@ public OcpiCredentialsValidator(ActionType actionType) : base(actionType) .NotEmpty(); RuleForEach(x => x.Roles!) - .SetValidator(new OcpiCredentialsRoleValidator(actionType)); + .SetValidator(new OcpiCredentialsRoleValidator(actionType, ocpiVersion)); } } diff --git a/src/OCPI.Net.Validation/Validators/Energy/OcpiEnergyMixValidator.cs b/src/OCPI.Net.Validation/Validators/Energy/OcpiEnergyMixValidator.cs index fed45bc..dcc9c13 100644 --- a/src/OCPI.Net.Validation/Validators/Energy/OcpiEnergyMixValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Energy/OcpiEnergyMixValidator.cs @@ -2,18 +2,18 @@ namespace OCPI.Contracts; -internal class OcpiEnergyMixValidator : ActionValidator +internal class OcpiEnergyMixValidator : OcpiValidator { - public OcpiEnergyMixValidator(ActionType actionType) : base(actionType) + public OcpiEnergyMixValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.IsGreenEnergy) .NotEmpty(); RuleForEach(x => x.EnergySources) - .SetValidator(new OcpiEnergySourceValidator(actionType)); + .SetValidator(new OcpiEnergySourceValidator(actionType, ocpiVersion)); RuleForEach(x => x.EnvironmentalImpact) - .SetValidator(new OcpiEnvironmentalImpactValidator(actionType)); + .SetValidator(new OcpiEnvironmentalImpactValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.SupplierName) .MaximumLength(64); diff --git a/src/OCPI.Net.Validation/Validators/Energy/OcpiEnergySourceValidator.cs b/src/OCPI.Net.Validation/Validators/Energy/OcpiEnergySourceValidator.cs index f37600f..449ee01 100644 --- a/src/OCPI.Net.Validation/Validators/Energy/OcpiEnergySourceValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Energy/OcpiEnergySourceValidator.cs @@ -3,13 +3,13 @@ namespace OCPI.Contracts; -internal class OcpiEnergySourceValidator : ActionValidator +internal class OcpiEnergySourceValidator : OcpiValidator { - public OcpiEnergySourceValidator(ActionType actionType) : base(actionType) + public OcpiEnergySourceValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Source) .NotEmpty() - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.Percentage) .NotEmpty() diff --git a/src/OCPI.Net.Validation/Validators/Energy/OcpiEnvironmentalImpactValidator.cs b/src/OCPI.Net.Validation/Validators/Energy/OcpiEnvironmentalImpactValidator.cs index aaae088..d005d5c 100644 --- a/src/OCPI.Net.Validation/Validators/Energy/OcpiEnvironmentalImpactValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Energy/OcpiEnvironmentalImpactValidator.cs @@ -3,13 +3,13 @@ namespace OCPI.Contracts; -internal class OcpiEnvironmentalImpactValidator : ActionValidator +internal class OcpiEnvironmentalImpactValidator : OcpiValidator { - public OcpiEnvironmentalImpactValidator(ActionType actionType) : base(actionType) + public OcpiEnvironmentalImpactValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Category) .NotEmpty() - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.Amount) .NotEmpty() diff --git a/src/OCPI.Net.Validation/Validators/Location/OcpiConnectorValidator.cs b/src/OCPI.Net.Validation/Validators/Location/OcpiConnectorValidator.cs index b496121..391a114 100644 --- a/src/OCPI.Net.Validation/Validators/Location/OcpiConnectorValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Location/OcpiConnectorValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal class OcpiConnectorValidator : ActionValidator +internal class OcpiConnectorValidator : OcpiValidator { - public OcpiConnectorValidator(ActionType actionType) : base(actionType) + public OcpiConnectorValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { Unless(ActionType.Patch, () => { @@ -13,21 +13,31 @@ public OcpiConnectorValidator(ActionType actionType) : base(actionType) JsonRuleFor(x => x.Standard).NotEmpty(); JsonRuleFor(x => x.Format).NotEmpty(); JsonRuleFor(x => x.PowerType).NotEmpty(); - JsonRuleFor(x => x.MaxVoltage).NotEmpty(); - JsonRuleFor(x => x.MaxAmperage).NotEmpty(); + + WhenOcpiVersionAbove("2.2", () => + { + JsonRuleFor(x => x.MaxVoltage).NotEmpty(); + JsonRuleFor(x => x.MaxAmperage).NotEmpty(); + }); + + WhenOcpiVersionBelow("2.2", () => + { + JsonRuleFor(x => x.Voltage).NotEmpty(); + JsonRuleFor(x => x.Amperage).NotEmpty(); + }); }); JsonRuleFor(x => x.Id) .MaximumLength(36); JsonRuleFor(x => x.Standard) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.Format) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.PowerType) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.TermsAndConditionsUrl) .ValidUrl(); diff --git a/src/OCPI.Net.Validation/Validators/Location/OcpiEvseValidator.cs b/src/OCPI.Net.Validation/Validators/Location/OcpiEvseValidator.cs index e9ddf4d..420c311 100644 --- a/src/OCPI.Net.Validation/Validators/Location/OcpiEvseValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Location/OcpiEvseValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal class OcpiEvseValidator : ActionValidator +internal class OcpiEvseValidator : OcpiValidator { - public OcpiEvseValidator(ActionType actionType) : base(actionType) + public OcpiEvseValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { Unless(ActionType.Patch, () => { @@ -16,40 +16,49 @@ public OcpiEvseValidator(ActionType actionType) : base(actionType) .NotEmpty(); }); - JsonRuleFor(x => x.Uid) - .MaximumLength(36); - JsonRuleFor(x => x.EvseId) .MaximumLength(48); JsonRuleFor(x => x.Status) - .ValidEnum(); + .IsInEnum(); RuleForEach(x => x.StatusSchedule) - .SetValidator(new OcpiStatusScheduleValidator(actionType)); + .SetValidator(new OcpiStatusScheduleValidator(actionType, ocpiVersion)); RuleForEach(x => x.Capabilities) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.FloorLevel) .MaximumLength(4); JsonRuleFor(x => x.Coordinates!) - .SetValidator(new OcpiGeolocationValidator(actionType)); + .SetValidator(new OcpiGeolocationValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.PhysicalReference); RuleForEach(x => x.Directions) - .SetValidator(new OcpiDisplayTextValidator(actionType)); + .SetValidator(new OcpiDisplayTextValidator(actionType, ocpiVersion)); RuleForEach(x => x.ParkingRestrictions) - .ValidEnum(); + .IsInEnum(); RuleForEach(x => x.Images) - .SetValidator(new OcpiImageValidator(actionType)); + .SetValidator(new OcpiImageValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.LastUpdated) .NotEmpty() .ValidDateTime(); + + WhenOcpiVersionAbove("2.2", () => + { + JsonRuleFor(x => x.Uid) + .MaximumLength(36); + }); + + WhenOcpiVersionBelow("2.2", () => + { + JsonRuleFor(x => x.Uid) + .MaximumLength(39); + }); } } diff --git a/src/OCPI.Net.Validation/Validators/Location/OcpiExceptionalPeriodValidator.cs b/src/OCPI.Net.Validation/Validators/Location/OcpiExceptionalPeriodValidator.cs index 9ea7db0..9ed5305 100644 --- a/src/OCPI.Net.Validation/Validators/Location/OcpiExceptionalPeriodValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Location/OcpiExceptionalPeriodValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal partial class OcpiExceptionalPeriodValidator : ActionValidator +internal partial class OcpiExceptionalPeriodValidator : OcpiValidator { - public OcpiExceptionalPeriodValidator(ActionType actionType) : base(actionType) + public OcpiExceptionalPeriodValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.PeriodBegin) .NotEmpty() diff --git a/src/OCPI.Net.Validation/Validators/Location/OcpiHoursValidator.cs b/src/OCPI.Net.Validation/Validators/Location/OcpiHoursValidator.cs index 1235857..39c5dc1 100644 --- a/src/OCPI.Net.Validation/Validators/Location/OcpiHoursValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Location/OcpiHoursValidator.cs @@ -2,20 +2,20 @@ namespace OCPI.Contracts; -internal partial class OcpiHoursValidator : ActionValidator +internal partial class OcpiHoursValidator : OcpiValidator { - public OcpiHoursValidator(ActionType actionType) : base(actionType) + public OcpiHoursValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.TwentyFourSeven) .NotEmpty(); RuleForEach(x => x.RegularHours) - .SetValidator(new OcpiRegularHoursValidator(actionType)); + .SetValidator(new OcpiRegularHoursValidator(actionType, ocpiVersion)); RuleForEach(x => x.ExceptionalOpenings) - .SetValidator(new OcpiExceptionalPeriodValidator(actionType)); + .SetValidator(new OcpiExceptionalPeriodValidator(actionType, ocpiVersion)); RuleForEach(x => x.ExceptionalClosings) - .SetValidator(new OcpiExceptionalPeriodValidator(actionType)); + .SetValidator(new OcpiExceptionalPeriodValidator(actionType, ocpiVersion)); } } diff --git a/src/OCPI.Net.Validation/Validators/Location/OcpiLocationValidator.cs b/src/OCPI.Net.Validation/Validators/Location/OcpiLocationValidator.cs index 307edc2..fa1b43e 100644 --- a/src/OCPI.Net.Validation/Validators/Location/OcpiLocationValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Location/OcpiLocationValidator.cs @@ -3,34 +3,41 @@ namespace OCPI.Contracts; -internal partial class OcpiLocationValidator : ActionValidator +internal partial class OcpiLocationValidator : OcpiValidator { - public OcpiLocationValidator(ActionType actionType) : base(actionType) + public OcpiLocationValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { Unless(ActionType.Patch, () => { - JsonRuleFor(x => x.CountryCode).NotEmpty(); - JsonRuleFor(x => x.PartyId).NotEmpty(); JsonRuleFor(x => x.Id).NotEmpty(); - JsonRuleFor(x => x.Publish).NotEmpty(); JsonRuleFor(x => x.Address).NotEmpty(); JsonRuleFor(x => x.City).NotEmpty(); JsonRuleFor(x => x.Country).NotEmpty(); JsonRuleFor(x => x.Coordinates).NotEmpty(); - JsonRuleFor(x => x.TimeZone).NotEmpty(); + + WhenOcpiVersionAbove("2.2", () => + { + JsonRuleFor(x => x.CountryCode).NotEmpty(); + JsonRuleFor(x => x.PartyId).NotEmpty(); + JsonRuleFor(x => x.Publish).NotEmpty(); + JsonRuleFor(x => x.TimeZone).NotEmpty(); + }); + + WhenOcpiVersionBelow("2.2", () => + { + JsonRuleFor(x => x.Type).NotEmpty(); + JsonRuleFor(x => x.PostalCode).NotEmpty(); + }); }); JsonRuleFor(x => x.CountryCode) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.PartyId) .MaximumLength(3); - JsonRuleFor(x => x.Id) - .MaximumLength(36); - RuleForEach(x => x.PublishAllowedTo) - .SetValidator(new OcpiPublishTokenTypeValidator(actionType)); + .SetValidator(new OcpiPublishTokenTypeValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.Name) .MaximumLength(255); @@ -51,50 +58,61 @@ public OcpiLocationValidator(ActionType actionType) : base(actionType) .MaximumLength(3); JsonRuleFor(x => x.Coordinates!) - .SetValidator(new OcpiGeolocationValidator(actionType)); + .SetValidator(new OcpiGeolocationValidator(actionType, ocpiVersion)); RuleForEach(x => x.RelatedLocations) - .SetValidator(new OcpiAdditionalGeolocationValidator(actionType)); - - // TODO: Specific to OCPI 2.1.1 - //JsonRuleFor(x => x.Type) - // .ValidEnum(); + .SetValidator(new OcpiAdditionalGeolocationValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.ParkingType) - .ValidEnum(); + .IsInEnum(); RuleForEach(x => x.Evses) - .SetValidator(new OcpiEvseValidator(actionType)); + .SetValidator(new OcpiEvseValidator(actionType, ocpiVersion)); RuleForEach(x => x.Directions) - .SetValidator(new OcpiDisplayTextValidator(actionType)); + .SetValidator(new OcpiDisplayTextValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.Operator!) - .SetValidator(new OcpiBusinessDetailsValidator(actionType)); + .SetValidator(new OcpiBusinessDetailsValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.Suboperator!) - .SetValidator(new OcpiBusinessDetailsValidator(actionType)); + .SetValidator(new OcpiBusinessDetailsValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.Owner!) - .SetValidator(new OcpiBusinessDetailsValidator(actionType)); + .SetValidator(new OcpiBusinessDetailsValidator(actionType, ocpiVersion)); RuleForEach(x => x.Facilities) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.TimeZone) .MaximumLength(255); JsonRuleFor(x => x.OpeningTimes!) - .SetValidator(new OcpiHoursValidator(actionType)); + .SetValidator(new OcpiHoursValidator(actionType, ocpiVersion)); RuleForEach(x => x.Images) - .SetValidator(new OcpiImageValidator(actionType)); + .SetValidator(new OcpiImageValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.EnergyMix!) - .SetValidator(new OcpiEnergyMixValidator(actionType)); + .SetValidator(new OcpiEnergyMixValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.LastUpdated) .NotEmpty() .ValidDateTime(); + + WhenOcpiVersionAbove("2.2", () => + { + JsonRuleFor(x => x.Id) + .MaximumLength(36); + }); + + WhenOcpiVersionBelow("2.2", () => + { + JsonRuleFor(x => x.Id) + .MaximumLength(39); + + JsonRuleFor(x => x.Type) + .IsInEnum(); + }); } } diff --git a/src/OCPI.Net.Validation/Validators/Location/OcpiPublishTokenTypeValidator.cs b/src/OCPI.Net.Validation/Validators/Location/OcpiPublishTokenTypeValidator.cs index 8aad8f6..e172ef8 100644 --- a/src/OCPI.Net.Validation/Validators/Location/OcpiPublishTokenTypeValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Location/OcpiPublishTokenTypeValidator.cs @@ -3,15 +3,15 @@ namespace OCPI.Contracts; -internal partial class OcpiPublishTokenTypeValidator : ActionValidator +internal partial class OcpiPublishTokenTypeValidator : OcpiValidator { - public OcpiPublishTokenTypeValidator(ActionType actionType) : base(actionType) + public OcpiPublishTokenTypeValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Uid) .MaximumLength(36); JsonRuleFor(x => x.Type) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.VisualNumber) .MaximumLength(64); diff --git a/src/OCPI.Net.Validation/Validators/Location/OcpiRegularHoursValidator.cs b/src/OCPI.Net.Validation/Validators/Location/OcpiRegularHoursValidator.cs index ec14a3d..1b4ace7 100644 --- a/src/OCPI.Net.Validation/Validators/Location/OcpiRegularHoursValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Location/OcpiRegularHoursValidator.cs @@ -3,14 +3,14 @@ namespace OCPI.Contracts; -internal partial class OcpiRegularHoursValidator : ActionValidator +internal partial class OcpiRegularHoursValidator : OcpiValidator { private const string _timePeriodRegexValue = "([0-1][0-9]|2[0-3]):[0-5][0-9]"; [GeneratedRegex(_timePeriodRegexValue)] private static partial Regex TimePeriodRegex(); - public OcpiRegularHoursValidator(ActionType actionType) : base(actionType) + public OcpiRegularHoursValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Weekday) .NotEmpty() diff --git a/src/OCPI.Net.Validation/Validators/Location/OcpiStatusScheduleValidator.cs b/src/OCPI.Net.Validation/Validators/Location/OcpiStatusScheduleValidator.cs index 0680026..70ea936 100644 --- a/src/OCPI.Net.Validation/Validators/Location/OcpiStatusScheduleValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Location/OcpiStatusScheduleValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -internal class OcpiStatusScheduleValidator : ActionValidator +internal class OcpiStatusScheduleValidator : OcpiValidator { - public OcpiStatusScheduleValidator(ActionType actionType) : base(actionType) + public OcpiStatusScheduleValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.PeriodBegin) .NotEmpty() @@ -16,6 +16,6 @@ public OcpiStatusScheduleValidator(ActionType actionType) : base(actionType) JsonRuleFor(x => x.Status) .NotEmpty() - .ValidEnum(); + .IsInEnum(); } } diff --git a/src/OCPI.Net.Validation/Validators/Tariff/OcpiPriceComponentValidator.cs b/src/OCPI.Net.Validation/Validators/Tariff/OcpiPriceComponentValidator.cs index 8ffd588..4400e4c 100644 --- a/src/OCPI.Net.Validation/Validators/Tariff/OcpiPriceComponentValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Tariff/OcpiPriceComponentValidator.cs @@ -3,13 +3,13 @@ namespace OCPI.Contracts; -public class OcpiPriceComponentValidator : ActionValidator +internal class OcpiPriceComponentValidator : OcpiValidator { - public OcpiPriceComponentValidator(ActionType actionType) : base(actionType) + public OcpiPriceComponentValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.Type) .NotEmpty() - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.Price) .NotEmpty(); diff --git a/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffElementValidator.cs b/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffElementValidator.cs index 7b43917..248a97a 100644 --- a/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffElementValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffElementValidator.cs @@ -2,17 +2,17 @@ namespace OCPI.Contracts; -public class OcpiTariffElementValidator : ActionValidator +internal class OcpiTariffElementValidator : OcpiValidator { - public OcpiTariffElementValidator(ActionType actionType) : base(actionType) + public OcpiTariffElementValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.PriceComponents) .NotEmpty(); RuleForEach(x => x.PriceComponents) - .SetValidator(new OcpiPriceComponentValidator(actionType)); + .SetValidator(new OcpiPriceComponentValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.Restrictions!) - .SetValidator(new OcpiTariffRestrictionValidator(actionType)); + .SetValidator(new OcpiTariffRestrictionValidator(actionType, ocpiVersion)); } } diff --git a/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffRestrictionValidator.cs b/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffRestrictionValidator.cs index a70ef84..963e168 100644 --- a/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffRestrictionValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffRestrictionValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -public class OcpiTariffRestrictionValidator : ActionValidator +internal class OcpiTariffRestrictionValidator : OcpiValidator { - public OcpiTariffRestrictionValidator(ActionType actionType) : base(actionType) + public OcpiTariffRestrictionValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { JsonRuleFor(x => x.StartTime) .MaximumLength(5); @@ -20,9 +20,9 @@ public OcpiTariffRestrictionValidator(ActionType actionType) : base(actionType) .MaximumLength(10); RuleForEach(x => x.DayOfWeek) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.Reservation) - .ValidEnum(); + .IsInEnum(); } } diff --git a/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffValidator.cs b/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffValidator.cs index ed31248..46b292e 100644 --- a/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffValidator.cs +++ b/src/OCPI.Net.Validation/Validators/Tariff/OcpiTariffValidator.cs @@ -3,9 +3,9 @@ namespace OCPI.Contracts; -public class OcpiTariffValidator : ActionValidator +internal class OcpiTariffValidator : OcpiValidator { - public OcpiTariffValidator(ActionType actionType) : base(actionType) + public OcpiTariffValidator(ActionType actionType, OcpiVersion ocpiVersion) : base(actionType, ocpiVersion) { Unless(ActionType.Patch, () => { @@ -18,7 +18,7 @@ public OcpiTariffValidator(ActionType actionType) : base(actionType) }); JsonRuleFor(x => x.CountryCode) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.PartyId) .MaximumLength(3); @@ -27,25 +27,25 @@ public OcpiTariffValidator(ActionType actionType) : base(actionType) .MaximumLength(36); JsonRuleFor(x => x.Currency) - .ValidEnum(); + .IsInEnum(); JsonRuleFor(x => x.Type) - .ValidEnum(); + .IsInEnum(); RuleForEach(x => x.TariffAltText) - .SetValidator(new OcpiDisplayTextValidator(actionType)); + .SetValidator(new OcpiDisplayTextValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.TariffAltUrl) .ValidUrl(); JsonRuleFor(x => x.MinPrice!) - .SetValidator(new OcpiPriceValidator(actionType)); + .SetValidator(new OcpiPriceValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.MaxPrice!) - .SetValidator(new OcpiPriceValidator(actionType)); + .SetValidator(new OcpiPriceValidator(actionType, ocpiVersion)); RuleForEach(x => x.Elements) - .SetValidator(new OcpiTariffElementValidator(actionType)); + .SetValidator(new OcpiTariffElementValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.StartDateTime) .ValidDateTime(); @@ -54,7 +54,7 @@ public OcpiTariffValidator(ActionType actionType) : base(actionType) .ValidDateTime(); JsonRuleFor(x => x.EnergyMix!) - .SetValidator(new OcpiEnergyMixValidator(actionType)); + .SetValidator(new OcpiEnergyMixValidator(actionType, ocpiVersion)); JsonRuleFor(x => x.LastUpdated) .ValidDateTime();