/
qwiklly
/
arc-server
Обзор
Документация
Войти
/
qwiklly
/
arc-server
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
trunk
src/AppRemoteConfig/Controllers/ParameterController.cs
155 строк
6 KB
CLTanuki
chore: modules exploded
24 янв 2024, 18:53
24 янв 2024, 18:53
6b5ba70
Код
Авторство
О чём код?
using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using AppRemoteConfig.Models.Database; namespace AppRemoteConfig.Controllers { using AppRemoteConfig.Models; using AppRemoteConfig.Models.Dto; using System.Text.Json; using AppRemoteConfig.Helpers; using Microsoft.Extensions.Logging; [Route("/api/v0/flags")] public class ParameterController : ControllerBase { private readonly ILogger<ParameterController> _logger; private readonly ApplicationContext _dbContext; public ParameterController( ILogger<ParameterController> logger, ApplicationContext dbContext) { _logger = logger; _dbContext = dbContext; } [HttpPost("get")] public async Task<FlagDefinitionDto?> GetFeatureFlag([FromBody] FlagRequestDto requestDto) { var flag = await this.GetValueFlag(requestDto.AppId, requestDto.SemVer, requestDto.FlagKey); return flag?.ToDto(); } [HttpPost("list")] public async Task<IEnumerable<FlagDefinitionDto>> ListFeatureFlags([FromBody] FlagRequestDto requestDto) { var flags = await this.GetValueFlagList(requestDto.AppId, requestDto.SemVer); return flags.Select(f => f.ToDto()); } [HttpPost("check")] public async Task<bool> IsFlagActive([FromBody] FlagRequestDto requestDto) { var values = requestDto.Parameters.Value.Deserialize<Dictionary<string, object>>(); var flag = await this.GetValueFlag(requestDto.AppId, requestDto.SemVer, requestDto.FlagKey); if (values == null || flag == null) { return false; } var parametersList = values.Select(p => new Parameter() { ParamName = p.Key, ParamValue = p.Value?.ToString() ?? string.Empty}); var beenTrue = false; var beenFalse = false; foreach (var condition in flag.Conditions.FromJson()) { var parameter = parametersList.FirstOrDefault(c => c.ParamName == condition.ParamName); if (parameter == null) { return false; } bool result = false; var isParamValueDouble = double.TryParse(parameter.ParamValue, out var paramValue); var isConditionValueDouble = double.TryParse(condition.ParamValue, out var conditionValue); if (isParamValueDouble & isConditionValueDouble) { result = CheckParam(paramValue, conditionValue, condition.RelationType); } else { result = CheckParam(parameter.ParamValue, condition.ParamValue, condition.RelationType); } if (result) { beenTrue = true; } else { beenFalse = true; } } return flag.LogicalOperand switch { LogicalOperand.And => !beenFalse, LogicalOperand.Or => beenTrue, LogicalOperand.Not => !beenTrue, _ => false, }; } private bool CheckParam(double paramValue, double conditionValue, RelationType rt) => rt switch { RelationType.EQ => paramValue == conditionValue, RelationType.NEQ => paramValue != conditionValue, RelationType.LT => paramValue < conditionValue, RelationType.GT => paramValue > conditionValue, RelationType.LTE => paramValue <= conditionValue, RelationType.GTE => paramValue >= conditionValue, _ => false, }; private bool CheckParam(string paramValue, string conditionValue, RelationType rt) => rt switch { RelationType.EQ => paramValue == conditionValue, RelationType.NEQ => paramValue != conditionValue, _ => false, }; private async Task<ValueFlag?> GetValueFlag(Guid appId, string semVer, string flagKey) { var application = await _dbContext.Applications.Include(app => app.Versions).FirstOrDefaultAsync(app => app.Id == appId); var version = application?.Versions.FirstOrDefault(version => version.GetVersionString() == semVer); var flag = await this._dbContext.ValueFlags.Include(flag => flag.ApplicableVersions).Include(valueFlag => valueFlag.Application).FirstOrDefaultAsync(flag => flag.ApplicationId == appId && flag.FeatureKey == flagKey); if (application == null || version == null || flag == null || flag.Application.Id != appId || !application.Versions.Contains(version) || !flag.ApplicableVersions.Contains(version)) // Check if the version is compatible { return null; } return flag; } private async Task<ValueFlag[]> GetValueFlagList(Guid appId, string semVer) { var flags = Array.Empty<ValueFlag>(); var application = await _dbContext.Applications.Include(app => app.Versions).FirstOrDefaultAsync(app => app.Id == appId); var version = application?.Versions.FirstOrDefault(version => version.GetVersionString() == semVer); if (application == null || version == null) // Check if the version is compatible { return flags; } var flagList = await this._dbContext.ValueFlags .Include(flag => flag.ApplicableVersions) .Include(valueFlag => valueFlag.Application) .Where(flag => flag.ApplicationId == appId && flag.ApplicableVersions.Contains(version)) .ToListAsync(); return flagList.ToArray(); } } }