Issue #31: implement mxstatus proxy and hresult conversion
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using MxGateway.Contracts.Proto;
|
||||
|
||||
namespace MxGateway.Worker.Conversion;
|
||||
|
||||
public sealed class MxStatusProxyConverter
|
||||
{
|
||||
public MxStatusProxy Convert(object status)
|
||||
{
|
||||
if (status is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(status));
|
||||
}
|
||||
|
||||
Type statusType = status.GetType();
|
||||
int success = ReadInt32Field(status, statusType, "success");
|
||||
int rawCategory = ReadInt32Field(status, statusType, "category");
|
||||
int rawDetectedBy = ReadInt32Field(status, statusType, "detectedBy");
|
||||
int detail = ReadInt32Field(status, statusType, "detail");
|
||||
|
||||
return new MxStatusProxy
|
||||
{
|
||||
Success = success,
|
||||
Category = MapCategory(rawCategory),
|
||||
DetectedBy = MapSource(rawDetectedBy),
|
||||
Detail = detail,
|
||||
RawCategory = rawCategory,
|
||||
RawDetectedBy = rawDetectedBy,
|
||||
DiagnosticText = MxStatusDetailText.Lookup(detail),
|
||||
};
|
||||
}
|
||||
|
||||
public IReadOnlyList<MxStatusProxy> ConvertMany(Array? statuses)
|
||||
{
|
||||
if (statuses is null)
|
||||
{
|
||||
return Array.Empty<MxStatusProxy>();
|
||||
}
|
||||
|
||||
List<MxStatusProxy> converted = new(statuses.Length);
|
||||
foreach (object? status in statuses)
|
||||
{
|
||||
if (status is null)
|
||||
{
|
||||
converted.Add(new MxStatusProxy
|
||||
{
|
||||
Category = MxStatusCategory.Unknown,
|
||||
DetectedBy = MxStatusSource.Unknown,
|
||||
DiagnosticText = "Null MXSTATUS_PROXY entry.",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
converted.Add(Convert(status));
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
public string PreserveCompletionOnlyStatusBytes(byte[] statusBytes)
|
||||
{
|
||||
if (statusBytes is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(statusBytes));
|
||||
}
|
||||
|
||||
return $"completion_only_status_hex={BitConverter.ToString(statusBytes).Replace("-", string.Empty)}";
|
||||
}
|
||||
|
||||
private static int ReadInt32Field(
|
||||
object value,
|
||||
Type valueType,
|
||||
string fieldName)
|
||||
{
|
||||
FieldInfo? field = valueType.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
|
||||
if (field is null)
|
||||
{
|
||||
throw new MxStatusConversionException(
|
||||
$"Status object type '{valueType.FullName}' does not expose required field '{fieldName}'.");
|
||||
}
|
||||
|
||||
object? fieldValue = field.GetValue(value);
|
||||
if (fieldValue is null)
|
||||
{
|
||||
throw new MxStatusConversionException(
|
||||
$"Status object field '{fieldName}' on type '{valueType.FullName}' is null.");
|
||||
}
|
||||
|
||||
return System.Convert.ToInt32(fieldValue, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private static MxStatusCategory MapCategory(int rawCategory)
|
||||
{
|
||||
return rawCategory switch
|
||||
{
|
||||
-1 => MxStatusCategory.Unknown,
|
||||
0 => MxStatusCategory.Ok,
|
||||
1 => MxStatusCategory.Pending,
|
||||
2 => MxStatusCategory.Warning,
|
||||
3 => MxStatusCategory.CommunicationError,
|
||||
4 => MxStatusCategory.ConfigurationError,
|
||||
5 => MxStatusCategory.OperationalError,
|
||||
6 => MxStatusCategory.SecurityError,
|
||||
7 => MxStatusCategory.SoftwareError,
|
||||
8 => MxStatusCategory.OtherError,
|
||||
_ => MxStatusCategory.Unknown,
|
||||
};
|
||||
}
|
||||
|
||||
private static MxStatusSource MapSource(int rawDetectedBy)
|
||||
{
|
||||
return rawDetectedBy switch
|
||||
{
|
||||
-1 => MxStatusSource.Unknown,
|
||||
0 => MxStatusSource.RequestingLmx,
|
||||
1 => MxStatusSource.RespondingLmx,
|
||||
2 => MxStatusSource.RequestingNmx,
|
||||
3 => MxStatusSource.RespondingNmx,
|
||||
4 => MxStatusSource.RequestingAutomationObject,
|
||||
5 => MxStatusSource.RespondingAutomationObject,
|
||||
_ => MxStatusSource.Unknown,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user