using System.ComponentModel.DataAnnotations;
using Fake;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using InterfaceForward.Application.Contracts;
using InterfaceForward.Application.Contracts.ForwardCore;
using InterfaceForward.Application.Filters;
using InterfaceForward.Repositories.Log.Services;
using Microsoft.AspNetCore.Mvc;
namespace InterfaceForward.Application.Services;
///
/// 接口转发服务
///
[ApiExplorerSettings(GroupName = "接口转发服务")]
[TypeFilter(typeof(ForwardAuthorizeFilter))]
[TypeFilter(typeof(ForwardExceptionFilter))]
[DisableRequestLog]
[AllowAnonymous]
[Route("InterfaceForward")]
public class InterfaceForwardService : ApplicationService, IInterfaceForwardService
{
private readonly InterfaceForwardCommon _forwardCommon;
private readonly ILogRepository _logRepository;
private readonly InterfaceRelayOptions _options;
///
public InterfaceForwardService(
ILogRepository logRepository
, InterfaceForwardCommon forwardCommon
, IOptionsSnapshot options
)
{
_logRepository = logRepository;
_forwardCommon = forwardCommon;
_options = options.Value;
}
[DisableUnifiedResult]
[HttpPost("ForwardWithSubscribe")]
public async Task ForwardWithSubscribeAsync(
[FromQuery] [Required] string upStreamCode,
[FromQuery] [Required] string serviceProviderCode,
[FromQuery] int mainBodyId,
[FromBody] [Required] object data,
[FromHeader] string? attach = null,
[FromHeader] bool isReturnMessage = false,
[FromHeader] string? failedSubscribeName = null)
{
if (JToken.FromObject(data) is not JObject jobject)
{
throw new BusinessException(message: "非法结构,请传对象");
}
var contextList = await _forwardCommon.VerifyBusinessAndBuildForwardContexts(upStreamCode, serviceProviderCode);
var context = contextList.First();
context.OriginalInterfaceInput = contextList.Count == 1
? jobject
: new JObject
{
[upStreamCode!] = jobject
};
var res = contextList.Count == 1
? await _forwardCommon.InternalForwardAsync(context)
: await _forwardCommon.InternalForward2Async(contextList);
return new InterfaceRelayUnifyResultDto
{
RequestId = context.ServiceProviderRequestLog.RequestId,
OriginalMessage = isReturnMessage ? context.ServiceProviderRequestLog.Response : null,
Attach = attach
};
}
[HttpPost("ReForward")]
public async Task ReForwardAsync(
[FromQuery] [Required] string upStreamCode,
[FromQuery] [Required] string serviceProviderCode,
[FromQuery] int mainBodyId,
[FromHeader] [Required] Guid requestId,
[FromBody] [Required] object data,
[FromHeader] string? attach = null,
[FromHeader] bool isReturnMessage = false,
[FromHeader] string? failedSubscribeName = null)
{
if (JToken.FromObject(data) is not JObject jobject)
{
throw new BusinessException(message: "非法结构,请传对象");
}
var logs = await _logRepository.GetRequestLogsAsync(requestId);
var failedLog = logs.FirstOrDefault(x => !x.IsSuccess);
if (failedLog == default) throw new BusinessException(message: "找不到失败日志,无法重试");
var contextList = await _forwardCommon.VerifyBusinessAndBuildForwardContexts(upStreamCode, serviceProviderCode);
var context = contextList.First();
context.OriginalInterfaceInput = contextList.Count == 1
? jobject
: new JObject
{
[upStreamCode] = jobject
};
// 从第一个失败的开始重试
var requestLogs = logs.Where(x => !x.IsApp).ToList();
var res = contextList.Count == 1
? await _forwardCommon.InternalForwardAsync(context)
: await _forwardCommon.InternalForward3Async(contextList, requestLogs);
return new InterfaceRelayUnifyResultDto
{
RequestId = context.ServiceProviderRequestLog.RequestId,
OriginalMessage = isReturnMessage ? _logRepository.ServiceProviderRequestLog.Response : null,
Attach = attach
};
}
}