Files
hcs/Hcs.Client/ClientApi/HouseManagementApi/HcsHouseManagementMethod.cs
HOME-LAPTOP\kshkulev 33ab055b43 Add project
Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
2025-08-12 11:21:10 +09:00

163 lines
7.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Hcs.ClientApi.RemoteCaller;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using HouseManagement = Hcs.Service.Async.HouseManagement.v14_5_0_1;
namespace Hcs.Service.Async.HouseManagement.v14_5_0_1
{
public partial class AckRequestAck : IHcsAck { }
public partial class getStateResult : IHcsGetStateResult { }
public partial class Fault : IHcsFault { }
public partial class HeaderType : IHcsHeaderType { }
}
namespace Hcs.ClientApi.HouseManagementApi
{
public class HcsHouseManagementMethod : HcsRemoteCallMethod
{
public HcsEndPoints EndPoint => HcsEndPoints.HomeManagementAsync;
public HouseManagement.RequestHeader CreateRequestHeader() =>
HcsRequestHelper.CreateHeader<HouseManagement.RequestHeader>(ClientConfig);
public HcsHouseManagementMethod(HcsClientConfig config) : base(config) { }
public System.ServiceModel.EndpointAddress RemoteAddress
=> GetEndpointAddress(HcsConstants.EndPointLocator.GetPath(EndPoint));
private HouseManagement.HouseManagementPortsTypeAsyncClient NewPortClient()
{
var client = new HouseManagement.HouseManagementPortsTypeAsyncClient(_binding, RemoteAddress);
ConfigureEndpointCredentials(client.Endpoint, client.ClientCredentials);
return client;
}
public async Task<IHcsGetStateResult> SendAndWaitResultAsync(
object request,
Func<HouseManagement.HouseManagementPortsTypeAsyncClient, Task<IHcsAck>> sender,
CancellationToken token)
{
while (true)
{
token.ThrowIfCancellationRequested();
try
{
if (CanBeRestarted)
{
return await RunRepeatableTaskInsistentlyAsync(
async () => await SendAndWaitResultAsyncImpl(request, sender, token), token);
}
else
{
return await SendAndWaitResultAsyncImpl(request, sender, token);
}
}
catch (HcsRestartTimeoutException e)
{
if (!CanBeRestarted) throw new HcsException("Превышен лимит ожидания выполнения запроса", e);
Log($"Перезапускаем запрос типа {request.GetType().Name}...");
}
}
}
private async Task<IHcsGetStateResult> SendAndWaitResultAsyncImpl(
object request,
Func<HouseManagement.HouseManagementPortsTypeAsyncClient, Task<IHcsAck>> sender,
CancellationToken token)
{
if (request == null) throw new ArgumentNullException(nameof(request));
string version = HcsRequestHelper.GetRequestVersionString(request);
_config.Log($"Отправляем запрос: {RemoteAddress.Uri}/{request.GetType().Name} в версии {version}...");
var stopWatch = System.Diagnostics.Stopwatch.StartNew();
IHcsAck ack;
using (var client = NewPortClient())
{
ack = await sender(client);
}
stopWatch.Stop();
_config.Log($"Запрос принят в обработку за {stopWatch.ElapsedMilliseconds}мс., подтверждение {ack.MessageGUID}");
var stateResult = await WaitForResultAsync(ack, true, token);
stateResult.Items.OfType<HouseManagement.ErrorMessageType>().ToList().ForEach(x =>
{
throw HcsRemoteException.CreateNew(x.ErrorCode, x.Description);
});
return stateResult;
}
/// <summary>
/// Выполняет однократную проверку наличия результата.
/// Возвращает null если результата еще нет.
/// </summary>
protected override async Task<IHcsGetStateResult> TryGetResultAsync(IHcsAck sourceAck, CancellationToken token)
{
using (var client = NewPortClient())
{
var requestHeader = HcsRequestHelper.CreateHeader<HouseManagement.RequestHeader>(_config);
var requestBody = new HouseManagement.getStateRequest { MessageGUID = sourceAck.MessageGUID };
var response = await client.getStateAsync(requestHeader, requestBody);
var resultBody = response.getStateResult;
if (resultBody.RequestState == HcsAsyncRequestStateTypes.Ready)
{
return resultBody;
}
return null;
}
}
/// <summary>
/// Разбирает стандартный ответ HCS на операцию импорта с приемом ошибок
/// </summary>
protected HouseManagement.getStateResultImportResultCommonResult ParseSingleImportResult(IHcsGetStateResult stateResult)
{
return ParseImportResults(stateResult, 1, true).First();
}
/// <summary>
/// Разбирает стандартный ответ HCS на операцию импорта с приемом ошибок
/// </summary>
protected HouseManagement.getStateResultImportResultCommonResult[] ParseImportResults(
IHcsGetStateResult stateResult, int commonResultRequiredCount, bool checkItemErrors)
{
var importResult = RequireSingleItem<HouseManagement.getStateResultImportResult>(stateResult.Items);
if (IsArrayEmpty(importResult.Items)) throw new HcsException("Пустой ImportResult.Items");
importResult.Items.OfType<HouseManagement.ErrorMessageType>().ToList()
.ForEach(error => { throw HcsRemoteException.CreateNew(error.ErrorCode, error.Description); });
var commonResults = importResult.Items.OfType<HouseManagement.getStateResultImportResultCommonResult>();
foreach (var commonResult in commonResults)
{
if (IsArrayEmpty(commonResult.Items)) throw new HcsException("Пустой CommonResult.Items");
if (checkItemErrors) CheckCommonResultErrors(commonResult);
}
if (commonResults.Count() != commonResultRequiredCount)
{
throw new HcsException(
$"Число результатов {commonResults.Count()} типа CommonResult не равно {commonResultRequiredCount}");
}
return commonResults.ToArray();
}
protected void CheckCommonResultErrors(HouseManagement.getStateResultImportResultCommonResult commonResult)
{
commonResult.Items.OfType<HouseManagement.CommonResultTypeError>().ToList()
.ForEach(error => { throw HcsRemoteException.CreateNew(error.ErrorCode, error.Description); });
}
}
}