From 9ae268f4c53d40251486872162bb4b303f52c832 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Tue, 7 Jun 2022 11:14:26 +0500 Subject: [PATCH] Add ProtobufController --- .../Controllers/ProtobufController.cs | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 AsbCloudWebApi/Controllers/ProtobufController.cs diff --git a/AsbCloudWebApi/Controllers/ProtobufController.cs b/AsbCloudWebApi/Controllers/ProtobufController.cs new file mode 100644 index 00000000..0ec0f2d7 --- /dev/null +++ b/AsbCloudWebApi/Controllers/ProtobufController.cs @@ -0,0 +1,87 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using ProtoBuf.Meta; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.Controllers +{ + /// + /// контроллер схем ProtoBuf + /// + [Route("api/proto")] + [ApiController] + public class ProtobufController : ControllerBase + { + private IEnumerable GetMetaTypes() + { + var metaTypes = RuntimeTypeModel.Default + .GetTypes() + .OfType(); + var fileteredMetaTypes = metaTypes + .Where(t => t.Type.MemberType == System.Reflection.MemberTypes.TypeInfo) + .Where(t => !t.Type.IsGenericType) + .Where(t => !t.Type.IsArray); + return fileteredMetaTypes; + } + + /// + /// названия доступных типов + /// + /// + [HttpGet("types")] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public IActionResult GetTypes() + { + var typesNames = GetMetaTypes() + .Select(t => t.Type?.Name); + return Ok(typesNames); + } + + /// + /// .proto файл со всеми доступными типами + /// + /// + [HttpGet("schema")] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public IActionResult GetSchema() + { + var types = GetMetaTypes().Select(mt => mt.Type); + SchemaGenerationOptions opts = new() { }; + opts.Types.AddRange(types); + var protoFileContentString = ProtoBuf.Serializer.GetProto(opts); + var protoFileContentBytes = System.Text.Encoding.UTF8.GetBytes(protoFileContentString); + return File(protoFileContentBytes, "text/plain", "types.proto"); + } + + /// + /// .proto файл со всеми доступными типами + /// + /// + [HttpGet("schema/{typeName}")] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public IActionResult GetSchema(string typeName) + { + if (string.IsNullOrEmpty(typeName)) + return BadRequest("require typeName"); + + var type = RuntimeTypeModel.Default + .GetTypes() + .OfType() + .FirstOrDefault(t => t.Type.Name.Equals(typeName, System.StringComparison.InvariantCultureIgnoreCase)); + + if (type is null) + return NoContent(); + + SchemaGenerationOptions opts = new() { }; + opts.Types.Add(type.Type); + var protoFileContentString = ProtoBuf.Serializer.GetProto(opts); + var protoFileContentBytes = System.Text.Encoding.UTF8.GetBytes(protoFileContentString); + return File(protoFileContentBytes, "text/plain", $"{typeName}.proto"); + } + } +}