| | |
| | | using Microsoft.AspNetCore.Mvc.Controllers; |
| | | using Microsoft.AspNetCore.Routing; |
| | | using Microsoft.EntityFrameworkCore; |
| | | using Microsoft.Extensions.Caching.Distributed; |
| | | using Microsoft.Extensions.DependencyInjection; |
| | | using System; |
| | | using System.Collections.Generic; |
| | |
| | | /// <typeparam name="TRequest"></typeparam> |
| | | /// <typeparam name="TResponse"></typeparam> |
| | | /// <param name="request"></param> |
| | | /// <param name="provider"></param> |
| | | /// <returns></returns> |
| | | public static async Task<TResponse> SendHttpAsync<TRequest, TResponse>(TRequest request) |
| | | public static Task<TResponse> SendHttpAsync<TRequest, TResponse>( |
| | | TRequest request, |
| | | IResourceHttpProvider provider = null) |
| | | where TRequest : class, new() |
| | | { |
| | | var requestTypeFullName = typeof(TRequest).FullName; |
| | | var resource = await Db.GetRepository<Resource>().AsQueryable().AsNoTracking() |
| | | .Where(it => !it.IsExpired && it.RequestTypeFullName == requestTypeFullName) |
| | | .FirstOrDefaultAsync(); |
| | | var domain = await GetHealthyServiceDomain(resource); |
| | | var httpRemoteService = App.GetRequiredService<IHttpRemoteService>(); |
| | | var token = App.HttpContext.Request.Headers["Authorization"].ToString(); |
| | | var refreshToken = App.HttpContext.Request.Headers["X-Authorization"].ToString(); |
| | | TResponse response; |
| | | switch (resource.Method) |
| | | { |
| | | case EnumResourceMethod.Get: |
| | | response = await httpRemoteService.GetAsAsync<TResponse>( |
| | | $"{domain}{resource.Route}", |
| | | it => |
| | | it.WithQueryParameters(request) |
| | | .AddAuthentication(new AuthenticationHeaderValue("Authorization", token)) |
| | | .AddAuthentication(new AuthenticationHeaderValue("X-Authorization", refreshToken))); |
| | | break; |
| | | case EnumResourceMethod.Post: |
| | | response = await httpRemoteService.PostAsAsync<TResponse>( |
| | | $"{domain}{resource.Route}", |
| | | it => |
| | | it.SetJsonContent(request) |
| | | .WithHeader("Authorization", token) |
| | | .WithHeader("X-Authorization", refreshToken)); |
| | | break; |
| | | case EnumResourceMethod.Put: |
| | | response = await httpRemoteService.PutAsAsync<TResponse>( |
| | | $"{domain}{resource.Route}", |
| | | it => |
| | | it.SetJsonContent(request) |
| | | .AddAuthentication(new AuthenticationHeaderValue("Authorization", token)) |
| | | .AddAuthentication(new AuthenticationHeaderValue("X-Authorization", refreshToken))); |
| | | break; |
| | | case EnumResourceMethod.Delete: |
| | | response = await httpRemoteService.DeleteAsAsync<TResponse>( |
| | | $"{domain}{resource.Route}", |
| | | it => |
| | | it.SetJsonContent(request) |
| | | .AddAuthentication(new AuthenticationHeaderValue("Authorization", token)) |
| | | .AddAuthentication(new AuthenticationHeaderValue("X-Authorization", refreshToken))); |
| | | break; |
| | | default: |
| | | throw Oops.Oh(EnumErrorCodeType.s400, $"不支持请求方式{resource.Method}"); |
| | | } |
| | | return response; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取健康服务域名 |
| | | /// </summary> |
| | | /// <param name="resource"></param> |
| | | /// <returns></returns> |
| | | public static async Task<string> GetHealthyServiceDomain(Resource resource) |
| | | { |
| | | var client = App.GetRequiredService<IConsulClient>(); |
| | | var queryResult = await client.Health.Service(resource.ServiceName, null, true); |
| | | if (queryResult.StatusCode != System.Net.HttpStatusCode.OK) |
| | | throw Oops.Oh(EnumErrorCodeType.s404, $"微服务{resource.Service}"); |
| | | |
| | | var domains = queryResult.Response |
| | | .Select(s => $"http://{s.Service.Address}:{s.Service.Port}") |
| | | .ToList(); |
| | | if (domains.IsNull()) |
| | | throw Oops.Oh(EnumErrorCodeType.s404, $"微服务{resource.Service}"); |
| | | // 轮询选择实例 |
| | | int randomIndex = new Random().Next(domains.Count); |
| | | return domains[randomIndex]; |
| | | return App.GetRequiredService<ResourceHttpUtils>().SendHttpAsync<TRequest, TResponse>(request, provider); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | model.ResponseTypeName = responseType.GetCSharpFriendlyName(); |
| | | model.ResponseTypeFullName = responseType.FullName; |
| | | } |
| | | |
| | | |
| | | models.Add(model); |
| | | |
| | | await App.GetRequiredService<IDistributedCache>().SetStringAsync($"ResourceModel|{model.RequestTypeFullName}", model.ToJson()); |
| | | } |
| | | } |
| | | |