From e741f54555d96b0d341b8b9cff76de9125851e7c Mon Sep 17 00:00:00 2001 From: "jozsef.b@aycode.com" <9Rj@D}fVwBaN> Date: Fri, 31 May 2024 20:52:22 +0200 Subject: [PATCH] SignalRServer InvokeMethodByMessageTag is in progress... --- TIAM.Database/DataLayers/Admins/AdminDal.cs | 8 +- .../ServiceProviderAPIController.cs | 63 ++++-- .../Controllers/TransferDataAPIController.cs | 3 + .../Server/Services/DevAdminSignalRhub.cs | 183 +++++++++++++----- 4 files changed, 185 insertions(+), 72 deletions(-) diff --git a/TIAM.Database/DataLayers/Admins/AdminDal.cs b/TIAM.Database/DataLayers/Admins/AdminDal.cs index 77032437..9e539024 100644 --- a/TIAM.Database/DataLayers/Admins/AdminDal.cs +++ b/TIAM.Database/DataLayers/Admins/AdminDal.cs @@ -45,6 +45,7 @@ namespace TIAM.Database.DataLayers.Admins public Task> GetTransfersAsync() => SessionAsync(ctx => ctx.GetTransfers().OrderBy(x => x.TransferStatusType).ThenByDescending(x => x.OrderId).ToList()); public Task GetTransfersJsonAsync() => SessionAsync(ctx => ctx.GetTransfers().OrderBy(x => x.TransferStatusType).ThenByDescending(x => x.OrderId).ToJson()); + public string GetTransfersJson() => Session(ctx => ctx.GetTransfers().OrderBy(x => x.TransferStatusType).ThenByDescending(x => x.OrderId).ToJson()); public Transfer? GetTransferById(Guid transferId) => Session(ctx => ctx.GetTransferById(transferId)); public string? GetTransferJsonById(Guid transferId) => Session(ctx => ctx.GetTransferById(transferId)?.ToJson()); @@ -236,10 +237,9 @@ namespace TIAM.Database.DataLayers.Admins public Task> GetServiceProvidersAsync() => SessionAsync(ctx => ctx.GetServiceProviders().ToList()); - public Task GetServiceProvidersJsonAsync() - { - return SessionAsync(ctx => ctx.Companies.ToJson()); - } + public Task GetServiceProvidersJsonAsync() => SessionAsync(ctx => ctx.Companies.ToJson()); + public string GetServiceProvidersJson() => Session(ctx => ctx.Companies.ToJson()); + public virtual Task GetServiceProviderByIdAsync(Guid id) => SessionAsync(ctx => ctx.GetServiceProviderById(id)); diff --git a/TIAMWebApp/Server/Controllers/ServiceProviderAPIController.cs b/TIAMWebApp/Server/Controllers/ServiceProviderAPIController.cs index 0f4236e1..d5c5743c 100644 --- a/TIAMWebApp/Server/Controllers/ServiceProviderAPIController.cs +++ b/TIAMWebApp/Server/Controllers/ServiceProviderAPIController.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using QRCoder; @@ -12,6 +13,11 @@ using Product = TIAM.Entities.Products.Product; using TIAM.Entities.Addresses; using TIAM.Entities.Profiles; using AyCode.Core.Loggers; +using AyCode.Services.SignalRs; +using AyCode.Utils.Extensions; +using TIAM.Services; +using TIAMWebApp.Server.Services; +using TIAM.Entities.Transfers; namespace TIAMWebApp.Server.Controllers { @@ -51,7 +57,7 @@ namespace TIAMWebApp.Server.Controllers //no owner set yet var ownerId = serviceProvider.OwnerId == Guid.Empty ? null : serviceProvider.OwnerId; - ownerId = Guid.Parse("540271F6-C604-4C16-8160-D5A7CAFEDF00"); //TESZT - J. + //ownerId = Guid.Parse("540271F6-C604-4C16-8160-D5A7CAFEDF00"); //TESZT - J. if (name is null) { @@ -59,28 +65,12 @@ namespace TIAMWebApp.Server.Controllers } else { - - _logger.Info($@"ServiceProvider to be creating; id: {id}, name: {name}, ownerId: {ownerId}"); - - var toCreate = new Company(id, name, ownerId, Guid.NewGuid()) + var company = new Company(id, name, ownerId, Guid.NewGuid()) { CommissionPercent = commissionRate }; - toCreate.SetProfile(new Profile(Guid.NewGuid(), toCreate.Name)); - toCreate.Profile.SetAddress(new Address(Guid.NewGuid(), "Controller CreateServiceProvider; address text...")); - - var result = await adminDal.CreateServiceProviderAsync(toCreate); - if (!result) - { - serviceProvider = null; - return string.Empty;//BadRequest(result); - } - else - { - - return toCreate.ToJson();//Ok(toCreate); - } + return await AddCompanyAsync(company); } } @@ -92,15 +82,48 @@ namespace TIAMWebApp.Server.Controllers } } + [SignalR(SignalRTags.AddCompanyAsync, MethodParamType.Object, typeof(Company))] + public async Task AddCompanyAsync(Company company) + { + if (company.Id.IsNullOrEmpty()) company.Id = Guid.NewGuid(); + + _logger.Info($@"ServiceProvider to be creating; id: {company.Id}, name: {company.Name}, ownerId: {company.OwnerId}"); + + company.SetProfile(new Profile(Guid.NewGuid(), company.Name)); + company.Profile.SetAddress(new Address(Guid.NewGuid(), "Controller AddCompanyAsync; address text...")); + + var result = await adminDal.CreateServiceProviderAsync(company); + if (!result) + { + return string.Empty;//BadRequest(result); + } + else + { + return company.ToJson();//Ok(toCreate); + } + } + //16. [AllowAnonymous] [HttpGet] [Route(APIUrls.GetServiceProvidersRouteName)] + [SignalR(SignalRTags.GetCompaniesAsync, MethodParamType.None)] public async Task GetServiceProviders() { return await adminDal.GetServiceProvidersJsonAsync(); } + //[AllowAnonymous] + //[HttpGet] + //[Route(APIUrls.GetServiceProvidersRouteName)] + //public Task GetServiceProviders() => Task.FromResult(GetServiceProvidersMethod()); + + //[SignalR(SignalRTags.GetCompaniesAsync)] + //public string GetServiceProvidersMethod() + //{ + // return adminDal.GetServiceProvidersJson(); + //} + //18. [AllowAnonymous] [HttpPost] @@ -115,6 +138,7 @@ namespace TIAMWebApp.Server.Controllers [AllowAnonymous] [HttpPost] [Route(APIUrls.UpdateServiceProviderRouteName)] + [SignalR(SignalRTags.UpdateCompanyAsync, MethodParamType.Object, typeof(Company))] public async Task UpdateServiceProvider(Company companyToModify) { _logger.Info($"UpdateServiceProvider called! + {companyToModify.Id}"); @@ -129,6 +153,7 @@ namespace TIAMWebApp.Server.Controllers [HttpPost] [Route(APIUrls.GetServiceProvidersByOwnerIdRouteName)] [Tags("Finished", "ServiceProvider")] + [SignalR(SignalRTags.GetPropertiesByOwnerIdAsync, MethodParamType.Id)] public async Task> GetServiceProvidersByOwnerId([FromBody] Guid ownerId) { _logger.Info($@"GetServiceProvidersByOwnerId called with ownerId: {ownerId}"); diff --git a/TIAMWebApp/Server/Controllers/TransferDataAPIController.cs b/TIAMWebApp/Server/Controllers/TransferDataAPIController.cs index ccd1a74c..1c452d02 100644 --- a/TIAMWebApp/Server/Controllers/TransferDataAPIController.cs +++ b/TIAMWebApp/Server/Controllers/TransferDataAPIController.cs @@ -11,6 +11,7 @@ using TIAM.Core.Enums; using TIAM.Database.DataLayers.Admins; using TIAM.Entities.Emails; using TIAM.Entities.Transfers; +using TIAM.Services; using TIAM.Services.Server; using TIAMWebApp.Shared.Application.Models; using TIAMWebApp.Shared.Application.Models.ClientSide.Messages; @@ -379,6 +380,7 @@ namespace TIAMWebApp.Server.Controllers [Authorize] [HttpGet] [Route(APIUrls.GetTransfersRouteName)] + [SignalR(SignalRTags.GetTransfersAsync, MethodParamType.None)] public async Task GetTransfers() { //var token = _authService.GetAuthTokenFromRequest(Request); @@ -404,6 +406,7 @@ namespace TIAMWebApp.Server.Controllers [AllowAnonymous] [HttpPost] [Route(APIUrls.UpdateTransferRouteName)] + [SignalR(SignalRTags.UpdateTransferAsync, MethodParamType.Object, typeof(Transfer))] public async Task UpdateTransfer(Transfer transferToModify) { _logger.Info($"UpdateTransfer called! + {Request?.ReadFormAsync()}"); diff --git a/TIAMWebApp/Server/Services/DevAdminSignalRhub.cs b/TIAMWebApp/Server/Services/DevAdminSignalRhub.cs index 42315714..1d08a0a5 100644 --- a/TIAMWebApp/Server/Services/DevAdminSignalRhub.cs +++ b/TIAMWebApp/Server/Services/DevAdminSignalRhub.cs @@ -1,26 +1,88 @@ -using AyCode.Core.Extensions; -using AyCode.Core.Helpers; +using System.Collections.Concurrent; +using System.Reflection; +using AyCode.Core.Extensions; using AyCode.Core.Loggers; using AyCode.Services.SignalRs; using Microsoft.AspNetCore.SignalR; using TIAM.Database.DataLayers.Admins; -using MessagePack; using MessagePack.Resolvers; using AyCode.Services.Server.SignalRs; -using System.ServiceModel.Channels; +using DevExpress.Utils.Filtering; using TIAM.Entities.Transfers; using TIAM.Services; using TIAMWebApp.Server.Controllers; -using System.Text.Json.Nodes; -using System.Text.RegularExpressions; -using System.Web; using TIAM.Entities.ServiceProviders; +using System.Runtime.CompilerServices; +using MessagePack; +using System.Security.Cryptography.Xml; +using DevExpress.XtraPrinting.Native.WebClientUIControl; namespace TIAMWebApp.Server.Services; -public class DevAdminSignalRHub(AdminDal adminDal, ServiceProviderAPIController serviceProviderAPIController, TransferDataAPIController transferDataAPIController, IEnumerable logWriters) : Hub, IAcSignalRHubServer +public static class ExtensionMethods { - private readonly TIAM.Core.Loggers.Logger _logger = new(logWriters.ToArray()); + public static object? InvokeMethod(this MethodInfo methodInfo, object obj, params object[]? parameters) + { + if (methodInfo.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) is AsyncStateMachineAttribute isTaks) + { + dynamic awaitable = methodInfo.Invoke(obj, parameters)!; + return awaitable.GetAwaiter().GetResult(); + } + + return methodInfo.Invoke(obj, parameters); + } +} + +public enum MethodParamType : byte +{ + None = 0, + Id = 5, + Object = 10 +} + +[AttributeUsage(AttributeTargets.Method)] +public class SignalRAttribute(int messageTag, MethodParamType methodParamType, Type paramType = null) : Attribute +{ + public int MessageTag { get; init; } = messageTag; + public MethodParamType MethodParamType { get; init; } = methodParamType; + public Type ParamType { get; init; } = paramType; +} + +public class DevAdminSignalRHub : Hub, IAcSignalRHubServer +{ + private readonly ConcurrentDictionary> _methodsByMessageTag = new(); + private readonly TIAM.Core.Loggers.Logger _logger; + + private readonly AdminDal _adminDal; + private readonly ServiceProviderAPIController _serviceProviderApiController; + private readonly TransferDataAPIController _transferDataApiController; + + public DevAdminSignalRHub(AdminDal adminDal, ServiceProviderAPIController serviceProviderApiController, TransferDataAPIController transferDataApiController, IEnumerable logWriters) + { + _adminDal = adminDal; + _serviceProviderApiController = serviceProviderApiController; + _transferDataApiController = transferDataApiController; + _logger = new(logWriters.ToArray()); + + var methods = typeof(ServiceProviderAPIController).GetMethods().Where(x => x.GetCustomAttributes(typeof(SignalRAttribute), false).Length > 0); + + _methodsByMessageTag[serviceProviderApiController] = new(); + foreach (var methodInfo in methods) + { + var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute; + _methodsByMessageTag[serviceProviderApiController][atr.MessageTag] = methodInfo; + } + + methods = typeof(TransferDataAPIController).GetMethods().Where(x => x.GetCustomAttributes(typeof(SignalRAttribute), false).Length > 0); + _methodsByMessageTag[transferDataApiController] = new(); + + foreach (var methodInfo in methods) + { + var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute; + _methodsByMessageTag[transferDataApiController][atr.MessageTag] = methodInfo; + } + + } // https://docs.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-3.1#strongly-typed-hubs public override async Task OnConnectedAsync() @@ -59,53 +121,76 @@ public class DevAdminSignalRHub(AdminDal adminDal, ServiceProviderAPIController try { + foreach (var methodsByDeclaringObject in _methodsByMessageTag) + { + if (methodsByDeclaringObject.Value.TryGetValue(messageTag, out var methodInfo)) + { + var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute; + object[]? param = null; + + if (atr.MethodParamType != MethodParamType.None) + { + param = new object[1]; + if (atr.MethodParamType == MethodParamType.Id) + { + param[0] = message!.MessagePackTo().Id; + } + else + { + var msg = message!.MessagePackTo>(MessagePackSerializerOptions.Standard); + param[0] = msg.PostDataJson.JsonTo(atr.ParamType)!; + } + } + + await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, methodInfo.InvokeMethod(methodsByDeclaringObject.Key, param)), requestId); + + return; + } + } + switch (messageTag) { - case SignalRTags.GetTransfersAsync: - await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, await transferDataAPIController.GetTransfers()), requestId); - return; - - case SignalRTags.GetPropertiesByOwnerIdAsync: - var ownerId = message!.MessagePackTo().Id; - - await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, await serviceProviderAPIController.GetServiceProvidersByOwnerId(ownerId)), requestId); - - return; - - case SignalRTags.UpdateTransferAsync: - var transfer = message!.MessagePackTo>().PostData; - - await transferDataAPIController.UpdateTransfer(transfer); - await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, transfer), requestId); - - return; - - case SignalRTags.GetCompaniesAsync: - await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, await serviceProviderAPIController.GetServiceProviders()), requestId); - return; - case SignalRTags.UpdateCompanyAsync: - - var updateCompany = message!.MessagePackTo>().PostData; - - await serviceProviderAPIController.UpdateServiceProvider(updateCompany); - await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, updateCompany), requestId); - - return; - - case SignalRTags.AddCompanyAsync: - - //var createCompany = message!.MessagePackTo>().PostData; - - //await serviceProviderAPIController.CreateServiceProvider(createCompany); - //await ResponseToCaller(messageTag, new SignalResponseMessage(SignalResponseStatus.Success, createCompany), requestId); - return; - case SignalRTags.RemoveCompanyAsync: var deleteCompany = message!.MessagePackTo>().PostData; - await adminDal.RemoveCompanyAsync(deleteCompany.Id); + await _adminDal.RemoveCompanyAsync(deleteCompany.Id); await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success), requestId); + return; + + //case SignalRTags.GetTransfersAsync: + // await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, await _transferDataApiController.GetTransfers()), requestId); + + // return; + + //case SignalRTags.GetPropertiesByOwnerIdAsync: + // var ownerId = message!.MessagePackTo().Id; + + // await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, await _serviceProviderApiController.GetServiceProvidersByOwnerId(ownerId)), requestId); + + // return; + + //case SignalRTags.UpdateTransferAsync: + // var transfer = message!.MessagePackTo>().PostData; + + // await _transferDataApiController.UpdateTransfer(transfer); + // await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, transfer), requestId); + + // return; + + //case SignalRTags.GetCompaniesAsync: + // await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, await _serviceProviderApiController.GetServiceProviders()), requestId); + + // return; + //case SignalRTags.UpdateCompanyAsync: + + // var updateCompany = message!.MessagePackTo>().PostData; + + // await _serviceProviderApiController.UpdateServiceProvider(updateCompany); + // await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, updateCompany), requestId); + + // return; + default: _logger.Error($"Server OnReceiveMessage; messageTag not found! messageTag: {messageTag}"); break;