From 01f5e6ad916e916e765366a1c1b36532ce72c197 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Fri, 1 May 2026 10:52:04 -0400 Subject: [PATCH] A.3 (worker IPC slice): proto SubscribeAlarms/Acknowledge/QueryActive commands + executor routing Adds the worker-side IPC surface for the alarm subsystem so the gateway can drive the AlarmDispatcher across the named-pipe boundary. Adds four proto MxCommandKind values + matching command messages and two MxCommandReply payload variants: - SubscribeAlarmsCommand(subscription_expression) - UnsubscribeAlarmsCommand - AcknowledgeAlarmCommand(alarm_guid, comment, operator_user/node/domain/full_name) - QueryActiveAlarmsCommand(alarm_filter_prefix) - AcknowledgeAlarmReplyPayload(native_status) - QueryActiveAlarmsReplyPayload(repeated ActiveAlarmSnapshot snapshots) Worker plumbing: - New IAlarmCommandHandler interface + AlarmCommandHandler production impl. Lazy-creates an AlarmDispatcher (with a wnwrap-backed consumer by default) on the first SubscribeAlarms; routes Acknowledge / QueryActive / Unsubscribe through it. Idempotent under repeated Unsubscribe; rejects a second Subscribe without an intervening Unsubscribe; cleans up the consumer if the underlying Subscribe call throws. - MxAccessCommandExecutor: 4 new switch arms map MxCommandKind values to IAlarmCommandHandler calls. Acknowledge surfaces the AVEVA native status into both MxCommandReply.Hresult and the dedicated AcknowledgeAlarmReplyPayload.NativeStatus so gateway-side consumers can echo it without unpacking the outer envelope. Invalid GUIDs and missing payloads return InvalidRequest; handler exceptions return MxaccessFailure with the exception message in DiagnosticMessage. - MxAccessStaSession: new constructor overload accepts an alarmCommandHandlerFactory; it's invoked on the STA thread during StartAsync and the resulting handler is passed into the executor. ShutdownGracefullyAsync + Dispose tear it down on the STA before the data-side cleanup runs. Tests: 20 new unit tests covering AlarmCommandHandler lazy lifecycle (Subscribe/Unsubscribe/Acknowledge/Query/Dispose, error paths) and the executor's 4 alarm switch arms (OK/InvalidRequest/MxaccessFailure paths, hresult propagation, prefix filtering). Worker test suite total: 192 passed / 3 skipped (live probes) / 1 pre-existing structure-test fail (untouched). Deferred to next slice: gateway-side WorkerAlarmRpcDispatcher that replaces NotWiredAlarmRpcDispatcher, builds + sends these commands across the IPC, and unwraps the resulting MxCommandReply into AcknowledgeAlarmReply / ActiveAlarmSnapshot stream. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Generated/MxaccessGateway.cs | 2417 ++++++++++++++--- .../Protos/mxaccess_gateway.proto | 64 + .../MxAccess/AlarmCommandExecutorTests.cs | 384 +++ .../MxAccess/AlarmCommandHandlerTests.cs | 232 ++ .../MxAccess/AlarmCommandHandler.cs | 192 ++ .../MxAccess/MxAccessCommandExecutor.cs | 169 +- .../MxAccess/MxAccessStaSession.cs | 64 +- 7 files changed, 3170 insertions(+), 352 deletions(-) create mode 100644 src/MxGateway.Worker.Tests/MxAccess/AlarmCommandExecutorTests.cs create mode 100644 src/MxGateway.Worker.Tests/MxAccess/AlarmCommandHandlerTests.cs create mode 100644 src/MxGateway.Worker/MxAccess/AlarmCommandHandler.cs diff --git a/src/MxGateway.Contracts/Generated/MxaccessGateway.cs b/src/MxGateway.Contracts/Generated/MxaccessGateway.cs index 05c543c..d49b977 100644 --- a/src/MxGateway.Contracts/Generated/MxaccessGateway.cs +++ b/src/MxGateway.Contracts/Generated/MxaccessGateway.cs @@ -46,7 +46,7 @@ namespace MxGateway.Contracts.Proto { "ZnRlcl93b3JrZXJfc2VxdWVuY2UYAiABKAQidgoQTXhDb21tYW5kUmVxdWVz", "dBISCgpzZXNzaW9uX2lkGAEgASgJEh0KFWNsaWVudF9jb3JyZWxhdGlvbl9p", "ZBgCIAEoCRIvCgdjb21tYW5kGAMgASgLMh4ubXhhY2Nlc3NfZ2F0ZXdheS52", - "MS5NeENvbW1hbmQizw8KCU14Q29tbWFuZBIwCgRraW5kGAEgASgOMiIubXhh", + "MS5NeENvbW1hbmQijhIKCU14Q29tbWFuZBIwCgRraW5kGAEgASgOMiIubXhh", "Y2Nlc3NfZ2F0ZXdheS52MS5NeENvbW1hbmRLaW5kEjgKCHJlZ2lzdGVyGAog", "ASgLMiQubXhhY2Nlc3NfZ2F0ZXdheS52MS5SZWdpc3RlckNvbW1hbmRIABI8", "Cgp1bnJlZ2lzdGVyGAsgASgLMiYubXhhY2Nlc3NfZ2F0ZXdheS52MS5VbnJl", @@ -83,312 +83,336 @@ namespace MxGateway.Contracts.Proto { "EkMKDnN1YnNjcmliZV9idWxrGCAgASgLMikubXhhY2Nlc3NfZ2F0ZXdheS52", "MS5TdWJzY3JpYmVCdWxrQ29tbWFuZEgAEkcKEHVuc3Vic2NyaWJlX2J1bGsY", "ISABKAsyKy5teGFjY2Vzc19nYXRld2F5LnYxLlVuc3Vic2NyaWJlQnVsa0Nv", - "bW1hbmRIABIwCgRwaW5nGGQgASgLMiAubXhhY2Nlc3NfZ2F0ZXdheS52MS5Q", - "aW5nQ29tbWFuZEgAEkgKEWdldF9zZXNzaW9uX3N0YXRlGGUgASgLMisubXhh", - "Y2Nlc3NfZ2F0ZXdheS52MS5HZXRTZXNzaW9uU3RhdGVDb21tYW5kSAASRAoP", - "Z2V0X3dvcmtlcl9pbmZvGGYgASgLMikubXhhY2Nlc3NfZ2F0ZXdheS52MS5H", - "ZXRXb3JrZXJJbmZvQ29tbWFuZEgAEj8KDGRyYWluX2V2ZW50cxhnIAEoCzIn", - "Lm14YWNjZXNzX2dhdGV3YXkudjEuRHJhaW5FdmVudHNDb21tYW5kSAASRQoP", - "c2h1dGRvd25fd29ya2VyGGggASgLMioubXhhY2Nlc3NfZ2F0ZXdheS52MS5T", - "aHV0ZG93bldvcmtlckNvbW1hbmRIAEIJCgdwYXlsb2FkIiYKD1JlZ2lzdGVy", - "Q29tbWFuZBITCgtjbGllbnRfbmFtZRgBIAEoCSIqChFVbnJlZ2lzdGVyQ29t", - "bWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFIkAKDkFkZEl0ZW1Db21tYW5k", - "EhUKDXNlcnZlcl9oYW5kbGUYASABKAUSFwoPaXRlbV9kZWZpbml0aW9uGAIg", - "ASgJIlcKD0FkZEl0ZW0yQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgF", - "EhcKD2l0ZW1fZGVmaW5pdGlvbhgCIAEoCRIUCgxpdGVtX2NvbnRleHQYAyAB", - "KAkiPwoRUmVtb3ZlSXRlbUNvbW1hbmQSFQoNc2VydmVyX2hhbmRsZRgBIAEo", - "BRITCgtpdGVtX2hhbmRsZRgCIAEoBSI7Cg1BZHZpc2VDb21tYW5kEhUKDXNl", - "cnZlcl9oYW5kbGUYASABKAUSEwoLaXRlbV9oYW5kbGUYAiABKAUiPQoPVW5B", - "ZHZpc2VDb21tYW5kEhUKDXNlcnZlcl9oYW5kbGUYASABKAUSEwoLaXRlbV9o", - "YW5kbGUYAiABKAUiRgoYQWR2aXNlU3VwZXJ2aXNvcnlDb21tYW5kEhUKDXNl", - "cnZlcl9oYW5kbGUYASABKAUSEwoLaXRlbV9oYW5kbGUYAiABKAUiXgoWQWRk", - "QnVmZmVyZWRJdGVtQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhcK", - "D2l0ZW1fZGVmaW5pdGlvbhgCIAEoCRIUCgxpdGVtX2NvbnRleHQYAyABKAki", - "XwogU2V0QnVmZmVyZWRVcGRhdGVJbnRlcnZhbENvbW1hbmQSFQoNc2VydmVy", - "X2hhbmRsZRgBIAEoBRIkChx1cGRhdGVfaW50ZXJ2YWxfbWlsbGlzZWNvbmRz", - "GAIgASgFIjwKDlN1c3BlbmRDb21tYW5kEhUKDXNlcnZlcl9oYW5kbGUYASAB", - "KAUSEwoLaXRlbV9oYW5kbGUYAiABKAUiPQoPQWN0aXZhdGVDb21tYW5kEhUK", - "DXNlcnZlcl9oYW5kbGUYASABKAUSEwoLaXRlbV9oYW5kbGUYAiABKAUieAoM", - "V3JpdGVDb21tYW5kEhUKDXNlcnZlcl9oYW5kbGUYASABKAUSEwoLaXRlbV9o", - "YW5kbGUYAiABKAUSKwoFdmFsdWUYAyABKAsyHC5teGFjY2Vzc19nYXRld2F5", - "LnYxLk14VmFsdWUSDwoHdXNlcl9pZBgEIAEoBSKwAQoNV3JpdGUyQ29tbWFu", + "bW1hbmRIABJHChBzdWJzY3JpYmVfYWxhcm1zGCIgASgLMisubXhhY2Nlc3Nf", + "Z2F0ZXdheS52MS5TdWJzY3JpYmVBbGFybXNDb21tYW5kSAASSwoSdW5zdWJz", + "Y3JpYmVfYWxhcm1zGCMgASgLMi0ubXhhY2Nlc3NfZ2F0ZXdheS52MS5VbnN1", + "YnNjcmliZUFsYXJtc0NvbW1hbmRIABJRChlhY2tub3dsZWRnZV9hbGFybV9j", + "b21tYW5kGCQgASgLMiwubXhhY2Nlc3NfZ2F0ZXdheS52MS5BY2tub3dsZWRn", + "ZUFsYXJtQ29tbWFuZEgAElQKG3F1ZXJ5X2FjdGl2ZV9hbGFybXNfY29tbWFu", + "ZBglIAEoCzItLm14YWNjZXNzX2dhdGV3YXkudjEuUXVlcnlBY3RpdmVBbGFy", + "bXNDb21tYW5kSAASMAoEcGluZxhkIAEoCzIgLm14YWNjZXNzX2dhdGV3YXku", + "djEuUGluZ0NvbW1hbmRIABJIChFnZXRfc2Vzc2lvbl9zdGF0ZRhlIAEoCzIr", + "Lm14YWNjZXNzX2dhdGV3YXkudjEuR2V0U2Vzc2lvblN0YXRlQ29tbWFuZEgA", + "EkQKD2dldF93b3JrZXJfaW5mbxhmIAEoCzIpLm14YWNjZXNzX2dhdGV3YXku", + "djEuR2V0V29ya2VySW5mb0NvbW1hbmRIABI/CgxkcmFpbl9ldmVudHMYZyAB", + "KAsyJy5teGFjY2Vzc19nYXRld2F5LnYxLkRyYWluRXZlbnRzQ29tbWFuZEgA", + "EkUKD3NodXRkb3duX3dvcmtlchhoIAEoCzIqLm14YWNjZXNzX2dhdGV3YXku", + "djEuU2h1dGRvd25Xb3JrZXJDb21tYW5kSABCCQoHcGF5bG9hZCImCg9SZWdp", + "c3RlckNvbW1hbmQSEwoLY2xpZW50X25hbWUYASABKAkiKgoRVW5yZWdpc3Rl", + "ckNvbW1hbmQSFQoNc2VydmVyX2hhbmRsZRgBIAEoBSJACg5BZGRJdGVtQ29t", + "bWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhcKD2l0ZW1fZGVmaW5pdGlv", + "bhgCIAEoCSJXCg9BZGRJdGVtMkNvbW1hbmQSFQoNc2VydmVyX2hhbmRsZRgB", + "IAEoBRIXCg9pdGVtX2RlZmluaXRpb24YAiABKAkSFAoMaXRlbV9jb250ZXh0", + "GAMgASgJIj8KEVJlbW92ZUl0ZW1Db21tYW5kEhUKDXNlcnZlcl9oYW5kbGUY", + "ASABKAUSEwoLaXRlbV9oYW5kbGUYAiABKAUiOwoNQWR2aXNlQ29tbWFuZBIV", + "Cg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhMKC2l0ZW1faGFuZGxlGAIgASgFIj0K", + "D1VuQWR2aXNlQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhMKC2l0", + "ZW1faGFuZGxlGAIgASgFIkYKGEFkdmlzZVN1cGVydmlzb3J5Q29tbWFuZBIV", + "Cg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhMKC2l0ZW1faGFuZGxlGAIgASgFIl4K", + "FkFkZEJ1ZmZlcmVkSXRlbUNvbW1hbmQSFQoNc2VydmVyX2hhbmRsZRgBIAEo", + "BRIXCg9pdGVtX2RlZmluaXRpb24YAiABKAkSFAoMaXRlbV9jb250ZXh0GAMg", + "ASgJIl8KIFNldEJ1ZmZlcmVkVXBkYXRlSW50ZXJ2YWxDb21tYW5kEhUKDXNl", + "cnZlcl9oYW5kbGUYASABKAUSJAocdXBkYXRlX2ludGVydmFsX21pbGxpc2Vj", + "b25kcxgCIAEoBSI8Cg5TdXNwZW5kQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxl", + "GAEgASgFEhMKC2l0ZW1faGFuZGxlGAIgASgFIj0KD0FjdGl2YXRlQ29tbWFu", "ZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhMKC2l0ZW1faGFuZGxlGAIgASgF", - "EisKBXZhbHVlGAMgASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFZhbHVl", - "EjUKD3RpbWVzdGFtcF92YWx1ZRgEIAEoCzIcLm14YWNjZXNzX2dhdGV3YXku", - "djEuTXhWYWx1ZRIPCgd1c2VyX2lkGAUgASgFIqEBChNXcml0ZVNlY3VyZWRD", - "b21tYW5kEhUKDXNlcnZlcl9oYW5kbGUYASABKAUSEwoLaXRlbV9oYW5kbGUY", - "AiABKAUSFwoPY3VycmVudF91c2VyX2lkGAMgASgFEhgKEHZlcmlmaWVyX3Vz", - "ZXJfaWQYBCABKAUSKwoFdmFsdWUYBSABKAsyHC5teGFjY2Vzc19nYXRld2F5", - "LnYxLk14VmFsdWUi2QEKFFdyaXRlU2VjdXJlZDJDb21tYW5kEhUKDXNlcnZl", - "cl9oYW5kbGUYASABKAUSEwoLaXRlbV9oYW5kbGUYAiABKAUSFwoPY3VycmVu", - "dF91c2VyX2lkGAMgASgFEhgKEHZlcmlmaWVyX3VzZXJfaWQYBCABKAUSKwoF", - "dmFsdWUYBSABKAsyHC5teGFjY2Vzc19nYXRld2F5LnYxLk14VmFsdWUSNQoP", - "dGltZXN0YW1wX3ZhbHVlGAYgASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5N", - "eFZhbHVlImMKF0F1dGhlbnRpY2F0ZVVzZXJDb21tYW5kEhUKDXNlcnZlcl9o", - "YW5kbGUYASABKAUSEwoLdmVyaWZ5X3VzZXIYAiABKAkSHAoUdmVyaWZ5X3Vz", - "ZXJfcGFzc3dvcmQYAyABKAkiRwoYQXJjaGVzdHJBVXNlclRvSWRDb21tYW5k", - "EhUKDXNlcnZlcl9oYW5kbGUYASABKAUSFAoMdXNlcl9pZF9ndWlkGAIgASgJ", - "IkIKEkFkZEl0ZW1CdWxrQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgF", - "EhUKDXRhZ19hZGRyZXNzZXMYAiADKAkiRAoVQWR2aXNlSXRlbUJ1bGtDb21t", - "YW5kEhUKDXNlcnZlcl9oYW5kbGUYASABKAUSFAoMaXRlbV9oYW5kbGVzGAIg", - "AygFIkQKFVJlbW92ZUl0ZW1CdWxrQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxl", - "GAEgASgFEhQKDGl0ZW1faGFuZGxlcxgCIAMoBSJGChdVbkFkdmlzZUl0ZW1C", - "dWxrQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhQKDGl0ZW1faGFu", - "ZGxlcxgCIAMoBSJEChRTdWJzY3JpYmVCdWxrQ29tbWFuZBIVCg1zZXJ2ZXJf", - "aGFuZGxlGAEgASgFEhUKDXRhZ19hZGRyZXNzZXMYAiADKAkiRQoWVW5zdWJz", - "Y3JpYmVCdWxrQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhQKDGl0", - "ZW1faGFuZGxlcxgCIAMoBSIeCgtQaW5nQ29tbWFuZBIPCgdtZXNzYWdlGAEg", - "ASgJIhgKFkdldFNlc3Npb25TdGF0ZUNvbW1hbmQiFgoUR2V0V29ya2VySW5m", - "b0NvbW1hbmQiKAoSRHJhaW5FdmVudHNDb21tYW5kEhIKCm1heF9ldmVudHMY", - "ASABKA0iSAoVU2h1dGRvd25Xb3JrZXJDb21tYW5kEi8KDGdyYWNlX3Blcmlv", - "ZBgBIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiKsCwoOTXhDb21t", - "YW5kUmVwbHkSEgoKc2Vzc2lvbl9pZBgBIAEoCRIWCg5jb3JyZWxhdGlvbl9p", - "ZBgCIAEoCRIwCgRraW5kGAMgASgOMiIubXhhY2Nlc3NfZ2F0ZXdheS52MS5N", - "eENvbW1hbmRLaW5kEjwKD3Byb3RvY29sX3N0YXR1cxgEIAEoCzIjLm14YWNj", - "ZXNzX2dhdGV3YXkudjEuUHJvdG9jb2xTdGF0dXMSFAoHaHJlc3VsdBgFIAEo", - "BUgBiAEBEjIKDHJldHVybl92YWx1ZRgGIAEoCzIcLm14YWNjZXNzX2dhdGV3", - "YXkudjEuTXhWYWx1ZRI0CghzdGF0dXNlcxgHIAMoCzIiLm14YWNjZXNzX2dh", - "dGV3YXkudjEuTXhTdGF0dXNQcm94eRIaChJkaWFnbm9zdGljX21lc3NhZ2UY", - "CCABKAkSNgoIcmVnaXN0ZXIYFCABKAsyIi5teGFjY2Vzc19nYXRld2F5LnYx", - "LlJlZ2lzdGVyUmVwbHlIABI1CghhZGRfaXRlbRgVIAEoCzIhLm14YWNjZXNz", - "X2dhdGV3YXkudjEuQWRkSXRlbVJlcGx5SAASNwoJYWRkX2l0ZW0yGBYgASgL", - "MiIubXhhY2Nlc3NfZ2F0ZXdheS52MS5BZGRJdGVtMlJlcGx5SAASRgoRYWRk", - "X2J1ZmZlcmVkX2l0ZW0YFyABKAsyKS5teGFjY2Vzc19nYXRld2F5LnYxLkFk", - "ZEJ1ZmZlcmVkSXRlbVJlcGx5SAASNAoHc3VzcGVuZBgYIAEoCzIhLm14YWNj", - "ZXNzX2dhdGV3YXkudjEuU3VzcGVuZFJlcGx5SAASNgoIYWN0aXZhdGUYGSAB", - "KAsyIi5teGFjY2Vzc19nYXRld2F5LnYxLkFjdGl2YXRlUmVwbHlIABJHChFh", - "dXRoZW50aWNhdGVfdXNlchgaIAEoCzIqLm14YWNjZXNzX2dhdGV3YXkudjEu", - "QXV0aGVudGljYXRlVXNlclJlcGx5SAASSwoUYXJjaGVzdHJhX3VzZXJfdG9f", - "aWQYGyABKAsyKy5teGFjY2Vzc19nYXRld2F5LnYxLkFyY2hlc3RyQVVzZXJU", - "b0lkUmVwbHlIABJACg1hZGRfaXRlbV9idWxrGBwgASgLMicubXhhY2Nlc3Nf", - "Z2F0ZXdheS52MS5CdWxrU3Vic2NyaWJlUmVwbHlIABJDChBhZHZpc2VfaXRl", - "bV9idWxrGB0gASgLMicubXhhY2Nlc3NfZ2F0ZXdheS52MS5CdWxrU3Vic2Ny", - "aWJlUmVwbHlIABJDChByZW1vdmVfaXRlbV9idWxrGB4gASgLMicubXhhY2Nl", - "c3NfZ2F0ZXdheS52MS5CdWxrU3Vic2NyaWJlUmVwbHlIABJGChN1bl9hZHZp", - "c2VfaXRlbV9idWxrGB8gASgLMicubXhhY2Nlc3NfZ2F0ZXdheS52MS5CdWxr", - "U3Vic2NyaWJlUmVwbHlIABJBCg5zdWJzY3JpYmVfYnVsaxggIAEoCzInLm14", - "YWNjZXNzX2dhdGV3YXkudjEuQnVsa1N1YnNjcmliZVJlcGx5SAASQwoQdW5z", - "dWJzY3JpYmVfYnVsaxghIAEoCzInLm14YWNjZXNzX2dhdGV3YXkudjEuQnVs", - "a1N1YnNjcmliZVJlcGx5SAASPwoNc2Vzc2lvbl9zdGF0ZRhkIAEoCzImLm14", - "YWNjZXNzX2dhdGV3YXkudjEuU2Vzc2lvblN0YXRlUmVwbHlIABI7Cgt3b3Jr", - "ZXJfaW5mbxhlIAEoCzIkLm14YWNjZXNzX2dhdGV3YXkudjEuV29ya2VySW5m", - "b1JlcGx5SAASPQoMZHJhaW5fZXZlbnRzGGYgASgLMiUubXhhY2Nlc3NfZ2F0", - "ZXdheS52MS5EcmFpbkV2ZW50c1JlcGx5SABCCQoHcGF5bG9hZEIKCghfaHJl", - "c3VsdCImCg1SZWdpc3RlclJlcGx5EhUKDXNlcnZlcl9oYW5kbGUYASABKAUi", - "IwoMQWRkSXRlbVJlcGx5EhMKC2l0ZW1faGFuZGxlGAEgASgFIiQKDUFkZEl0", - "ZW0yUmVwbHkSEwoLaXRlbV9oYW5kbGUYASABKAUiKwoUQWRkQnVmZmVyZWRJ", - "dGVtUmVwbHkSEwoLaXRlbV9oYW5kbGUYASABKAUiQgoMU3VzcGVuZFJlcGx5", - "EjIKBnN0YXR1cxgBIAEoCzIiLm14YWNjZXNzX2dhdGV3YXkudjEuTXhTdGF0", - "dXNQcm94eSJDCg1BY3RpdmF0ZVJlcGx5EjIKBnN0YXR1cxgBIAEoCzIiLm14", - "YWNjZXNzX2dhdGV3YXkudjEuTXhTdGF0dXNQcm94eSIoChVBdXRoZW50aWNh", - "dGVVc2VyUmVwbHkSDwoHdXNlcl9pZBgBIAEoBSIpChZBcmNoZXN0ckFVc2Vy", - "VG9JZFJlcGx5Eg8KB3VzZXJfaWQYASABKAUigQEKD1N1YnNjcmliZVJlc3Vs", - "dBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhMKC3RhZ19hZGRyZXNzGAIgASgJ", - "EhMKC2l0ZW1faGFuZGxlGAMgASgFEhYKDndhc19zdWNjZXNzZnVsGAQgASgI", - "EhUKDWVycm9yX21lc3NhZ2UYBSABKAkiSwoSQnVsa1N1YnNjcmliZVJlcGx5", - "EjUKB3Jlc3VsdHMYASADKAsyJC5teGFjY2Vzc19nYXRld2F5LnYxLlN1YnNj", - "cmliZVJlc3VsdCJFChFTZXNzaW9uU3RhdGVSZXBseRIwCgVzdGF0ZRgBIAEo", - "DjIhLm14YWNjZXNzX2dhdGV3YXkudjEuU2Vzc2lvblN0YXRlInUKD1dvcmtl", - "ckluZm9SZXBseRIZChF3b3JrZXJfcHJvY2Vzc19pZBgBIAEoBRIWCg53b3Jr", - "ZXJfdmVyc2lvbhgCIAEoCRIXCg9teGFjY2Vzc19wcm9naWQYAyABKAkSFgoO", - "bXhhY2Nlc3NfY2xzaWQYBCABKAkiQAoQRHJhaW5FdmVudHNSZXBseRIsCgZl", - "dmVudHMYASADKAsyHC5teGFjY2Vzc19nYXRld2F5LnYxLk14RXZlbnQi5wYK", - "B014RXZlbnQSMgoGZmFtaWx5GAEgASgOMiIubXhhY2Nlc3NfZ2F0ZXdheS52", - "MS5NeEV2ZW50RmFtaWx5EhIKCnNlc3Npb25faWQYAiABKAkSFQoNc2VydmVy", - "X2hhbmRsZRgDIAEoBRITCgtpdGVtX2hhbmRsZRgEIAEoBRIrCgV2YWx1ZRgF", - "IAEoCzIcLm14YWNjZXNzX2dhdGV3YXkudjEuTXhWYWx1ZRIPCgdxdWFsaXR5", - "GAYgASgFEjQKEHNvdXJjZV90aW1lc3RhbXAYByABKAsyGi5nb29nbGUucHJv", - "dG9idWYuVGltZXN0YW1wEjQKCHN0YXR1c2VzGAggAygLMiIubXhhY2Nlc3Nf", - "Z2F0ZXdheS52MS5NeFN0YXR1c1Byb3h5EhcKD3dvcmtlcl9zZXF1ZW5jZRgJ", - "IAEoBBI0ChB3b3JrZXJfdGltZXN0YW1wGAogASgLMhouZ29vZ2xlLnByb3Rv", - "YnVmLlRpbWVzdGFtcBI9ChlnYXRld2F5X3JlY2VpdmVfdGltZXN0YW1wGAsg", - "ASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIUCgdocmVzdWx0GAwg", - "ASgFSAGIAQESEgoKcmF3X3N0YXR1cxgNIAEoCRJACg5vbl9kYXRhX2NoYW5n", - "ZRgUIAEoCzImLm14YWNjZXNzX2dhdGV3YXkudjEuT25EYXRhQ2hhbmdlRXZl", - "bnRIABJGChFvbl93cml0ZV9jb21wbGV0ZRgVIAEoCzIpLm14YWNjZXNzX2dh", - "dGV3YXkudjEuT25Xcml0ZUNvbXBsZXRlRXZlbnRIABJJChJvcGVyYXRpb25f", - "Y29tcGxldGUYFiABKAsyKy5teGFjY2Vzc19nYXRld2F5LnYxLk9wZXJhdGlv", - "bkNvbXBsZXRlRXZlbnRIABJRChdvbl9idWZmZXJlZF9kYXRhX2NoYW5nZRgX", - "IAEoCzIuLm14YWNjZXNzX2dhdGV3YXkudjEuT25CdWZmZXJlZERhdGFDaGFu", - "Z2VFdmVudEgAEkoKE29uX2FsYXJtX3RyYW5zaXRpb24YGCABKAsyKy5teGFj", - "Y2Vzc19nYXRld2F5LnYxLk9uQWxhcm1UcmFuc2l0aW9uRXZlbnRIAEIGCgRi", - "b2R5QgoKCF9ocmVzdWx0IhMKEU9uRGF0YUNoYW5nZUV2ZW50IhYKFE9uV3Jp", - "dGVDb21wbGV0ZUV2ZW50IhgKFk9wZXJhdGlvbkNvbXBsZXRlRXZlbnQi1AEK", - "GU9uQnVmZmVyZWREYXRhQ2hhbmdlRXZlbnQSMgoJZGF0YV90eXBlGAEgASgO", - "Mh8ubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeERhdGFUeXBlEjQKDnF1YWxpdHlf", - "dmFsdWVzGAIgASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeEFycmF5EjYK", - "EHRpbWVzdGFtcF92YWx1ZXMYAyABKAsyHC5teGFjY2Vzc19nYXRld2F5LnYx", - "Lk14QXJyYXkSFQoNcmF3X2RhdGFfdHlwZRgEIAEoBSL9AwoWT25BbGFybVRy", - "YW5zaXRpb25FdmVudBIcChRhbGFybV9mdWxsX3JlZmVyZW5jZRgBIAEoCRIf", - "Chdzb3VyY2Vfb2JqZWN0X3JlZmVyZW5jZRgCIAEoCRIXCg9hbGFybV90eXBl", - "X25hbWUYAyABKAkSQQoPdHJhbnNpdGlvbl9raW5kGAQgASgOMigubXhhY2Nl", - "c3NfZ2F0ZXdheS52MS5BbGFybVRyYW5zaXRpb25LaW5kEhAKCHNldmVyaXR5", - "GAUgASgFEjwKGG9yaWdpbmFsX3JhaXNlX3RpbWVzdGFtcBgGIAEoCzIaLmdv", - "b2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASOAoUdHJhbnNpdGlvbl90aW1lc3Rh", - "bXAYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhUKDW9wZXJh", - "dG9yX3VzZXIYCCABKAkSGAoQb3BlcmF0b3JfY29tbWVudBgJIAEoCRIQCghj", - "YXRlZ29yeRgKIAEoCRITCgtkZXNjcmlwdGlvbhgLIAEoCRIzCg1jdXJyZW50", - "X3ZhbHVlGAwgASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFZhbHVlEjEK", - "C2xpbWl0X3ZhbHVlGA0gASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFZh", - "bHVlIv0DChNBY3RpdmVBbGFybVNuYXBzaG90EhwKFGFsYXJtX2Z1bGxfcmVm", - "ZXJlbmNlGAEgASgJEh8KF3NvdXJjZV9vYmplY3RfcmVmZXJlbmNlGAIgASgJ", - "EhcKD2FsYXJtX3R5cGVfbmFtZRgDIAEoCRIQCghzZXZlcml0eRgEIAEoBRI8", - "ChhvcmlnaW5hbF9yYWlzZV90aW1lc3RhbXAYBSABKAsyGi5nb29nbGUucHJv", - "dG9idWYuVGltZXN0YW1wEj8KDWN1cnJlbnRfc3RhdGUYBiABKA4yKC5teGFj", - "Y2Vzc19nYXRld2F5LnYxLkFsYXJtQ29uZGl0aW9uU3RhdGUSEAoIY2F0ZWdv", - "cnkYByABKAkSEwoLZGVzY3JpcHRpb24YCCABKAkSPQoZbGFzdF90cmFuc2l0", - "aW9uX3RpbWVzdGFtcBgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3Rh", - "bXASFQoNb3BlcmF0b3JfdXNlchgKIAEoCRIYChBvcGVyYXRvcl9jb21tZW50", - "GAsgASgJEjMKDWN1cnJlbnRfdmFsdWUYDCABKAsyHC5teGFjY2Vzc19nYXRl", - "d2F5LnYxLk14VmFsdWUSMQoLbGltaXRfdmFsdWUYDSABKAsyHC5teGFjY2Vz", - "c19nYXRld2F5LnYxLk14VmFsdWUikgEKF0Fja25vd2xlZGdlQWxhcm1SZXF1", - "ZXN0EhIKCnNlc3Npb25faWQYASABKAkSHQoVY2xpZW50X2NvcnJlbGF0aW9u", - "X2lkGAIgASgJEhwKFGFsYXJtX2Z1bGxfcmVmZXJlbmNlGAMgASgJEg8KB2Nv", - "bW1lbnQYBCABKAkSFQoNb3BlcmF0b3JfdXNlchgFIAEoCSLzAQoVQWNrbm93", - "bGVkZ2VBbGFybVJlcGx5EhIKCnNlc3Npb25faWQYASABKAkSFgoOY29ycmVs", - "YXRpb25faWQYAiABKAkSPAoPcHJvdG9jb2xfc3RhdHVzGAMgASgLMiMubXhh", - "Y2Nlc3NfZ2F0ZXdheS52MS5Qcm90b2NvbFN0YXR1cxIUCgdocmVzdWx0GAQg", - "ASgFSACIAQESMgoGc3RhdHVzGAUgASgLMiIubXhhY2Nlc3NfZ2F0ZXdheS52", - "MS5NeFN0YXR1c1Byb3h5EhoKEmRpYWdub3N0aWNfbWVzc2FnZRgGIAEoCUIK", - "CghfaHJlc3VsdCJqChhRdWVyeUFjdGl2ZUFsYXJtc1JlcXVlc3QSEgoKc2Vz", - "c2lvbl9pZBgBIAEoCRIdChVjbGllbnRfY29ycmVsYXRpb25faWQYAiABKAkS", - "GwoTYWxhcm1fZmlsdGVyX3ByZWZpeBgDIAEoCSLrAQoNTXhTdGF0dXNQcm94", - "eRIPCgdzdWNjZXNzGAEgASgFEjcKCGNhdGVnb3J5GAIgASgOMiUubXhhY2Nl", - "c3NfZ2F0ZXdheS52MS5NeFN0YXR1c0NhdGVnb3J5EjgKC2RldGVjdGVkX2J5", - "GAMgASgOMiMubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFN0YXR1c1NvdXJjZRIO", - "CgZkZXRhaWwYBCABKAUSFAoMcmF3X2NhdGVnb3J5GAUgASgFEhcKD3Jhd19k", - "ZXRlY3RlZF9ieRgGIAEoBRIXCg9kaWFnbm9zdGljX3RleHQYByABKAkipwMK", - "B014VmFsdWUSMgoJZGF0YV90eXBlGAEgASgOMh8ubXhhY2Nlc3NfZ2F0ZXdh", - "eS52MS5NeERhdGFUeXBlEhQKDHZhcmlhbnRfdHlwZRgCIAEoCRIPCgdpc19u", - "dWxsGAMgASgIEhYKDnJhd19kaWFnbm9zdGljGAQgASgJEhUKDXJhd19kYXRh", - "X3R5cGUYBSABKAUSFAoKYm9vbF92YWx1ZRgKIAEoCEgAEhUKC2ludDMyX3Zh", - "bHVlGAsgASgFSAASFQoLaW50NjRfdmFsdWUYDCABKANIABIVCgtmbG9hdF92", - "YWx1ZRgNIAEoAkgAEhYKDGRvdWJsZV92YWx1ZRgOIAEoAUgAEhYKDHN0cmlu", - "Z192YWx1ZRgPIAEoCUgAEjUKD3RpbWVzdGFtcF92YWx1ZRgQIAEoCzIaLmdv", - "b2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIABIzCgthcnJheV92YWx1ZRgRIAEo", - "CzIcLm14YWNjZXNzX2dhdGV3YXkudjEuTXhBcnJheUgAEhMKCXJhd192YWx1", - "ZRgSIAEoDEgAQgYKBGtpbmQi/gQKB014QXJyYXkSOgoRZWxlbWVudF9kYXRh", - "X3R5cGUYASABKA4yHy5teGFjY2Vzc19nYXRld2F5LnYxLk14RGF0YVR5cGUS", - "FAoMdmFyaWFudF90eXBlGAIgASgJEhIKCmRpbWVuc2lvbnMYAyADKA0SFgoO", - "cmF3X2RpYWdub3N0aWMYBCABKAkSHQoVcmF3X2VsZW1lbnRfZGF0YV90eXBl", - "GAUgASgFEjUKC2Jvb2xfdmFsdWVzGAogASgLMh4ubXhhY2Nlc3NfZ2F0ZXdh", - "eS52MS5Cb29sQXJyYXlIABI3CgxpbnQzMl92YWx1ZXMYCyABKAsyHy5teGFj", - "Y2Vzc19nYXRld2F5LnYxLkludDMyQXJyYXlIABI3CgxpbnQ2NF92YWx1ZXMY", - "DCABKAsyHy5teGFjY2Vzc19nYXRld2F5LnYxLkludDY0QXJyYXlIABI3Cgxm", - "bG9hdF92YWx1ZXMYDSABKAsyHy5teGFjY2Vzc19nYXRld2F5LnYxLkZsb2F0", - "QXJyYXlIABI5Cg1kb3VibGVfdmFsdWVzGA4gASgLMiAubXhhY2Nlc3NfZ2F0", - "ZXdheS52MS5Eb3VibGVBcnJheUgAEjkKDXN0cmluZ192YWx1ZXMYDyABKAsy", - "IC5teGFjY2Vzc19nYXRld2F5LnYxLlN0cmluZ0FycmF5SAASPwoQdGltZXN0", - "YW1wX3ZhbHVlcxgQIAEoCzIjLm14YWNjZXNzX2dhdGV3YXkudjEuVGltZXN0", - "YW1wQXJyYXlIABIzCgpyYXdfdmFsdWVzGBEgASgLMh0ubXhhY2Nlc3NfZ2F0", - "ZXdheS52MS5SYXdBcnJheUgAQggKBnZhbHVlcyIbCglCb29sQXJyYXkSDgoG", - "dmFsdWVzGAEgAygIIhwKCkludDMyQXJyYXkSDgoGdmFsdWVzGAEgAygFIhwK", - "CkludDY0QXJyYXkSDgoGdmFsdWVzGAEgAygDIhwKCkZsb2F0QXJyYXkSDgoG", - "dmFsdWVzGAEgAygCIh0KC0RvdWJsZUFycmF5Eg4KBnZhbHVlcxgBIAMoASId", - "CgtTdHJpbmdBcnJheRIOCgZ2YWx1ZXMYASADKAkiPAoOVGltZXN0YW1wQXJy", - "YXkSKgoGdmFsdWVzGAEgAygLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFt", - "cCIaCghSYXdBcnJheRIOCgZ2YWx1ZXMYASADKAwiWAoOUHJvdG9jb2xTdGF0", - "dXMSNQoEY29kZRgBIAEoDjInLm14YWNjZXNzX2dhdGV3YXkudjEuUHJvdG9j", - "b2xTdGF0dXNDb2RlEg8KB21lc3NhZ2UYAiABKAkqoQgKDU14Q29tbWFuZEtp", - "bmQSHwobTVhfQ09NTUFORF9LSU5EX1VOU1BFQ0lGSUVEEAASHAoYTVhfQ09N", - "TUFORF9LSU5EX1JFR0lTVEVSEAESHgoaTVhfQ09NTUFORF9LSU5EX1VOUkVH", - "SVNURVIQAhIcChhNWF9DT01NQU5EX0tJTkRfQUREX0lURU0QAxIdChlNWF9D", - "T01NQU5EX0tJTkRfQUREX0lURU0yEAQSHwobTVhfQ09NTUFORF9LSU5EX1JF", - "TU9WRV9JVEVNEAUSGgoWTVhfQ09NTUFORF9LSU5EX0FEVklTRRAGEh0KGU1Y", - "X0NPTU1BTkRfS0lORF9VTl9BRFZJU0UQBxImCiJNWF9DT01NQU5EX0tJTkRf", - "QURWSVNFX1NVUEVSVklTT1JZEAgSJQohTVhfQ09NTUFORF9LSU5EX0FERF9C", - "VUZGRVJFRF9JVEVNEAkSMAosTVhfQ09NTUFORF9LSU5EX1NFVF9CVUZGRVJF", - "RF9VUERBVEVfSU5URVJWQUwQChIbChdNWF9DT01NQU5EX0tJTkRfU1VTUEVO", - "RBALEhwKGE1YX0NPTU1BTkRfS0lORF9BQ1RJVkFURRAMEhkKFU1YX0NPTU1B", - "TkRfS0lORF9XUklURRANEhoKFk1YX0NPTU1BTkRfS0lORF9XUklURTIQDhIh", - "Ch1NWF9DT01NQU5EX0tJTkRfV1JJVEVfU0VDVVJFRBAPEiIKHk1YX0NPTU1B", - "TkRfS0lORF9XUklURV9TRUNVUkVEMhAQEiUKIU1YX0NPTU1BTkRfS0lORF9B", - "VVRIRU5USUNBVEVfVVNFUhAREigKJE1YX0NPTU1BTkRfS0lORF9BUkNIRVNU", - "UkFfVVNFUl9UT19JRBASEiEKHU1YX0NPTU1BTkRfS0lORF9BRERfSVRFTV9C", - "VUxLEBMSJAogTVhfQ09NTUFORF9LSU5EX0FEVklTRV9JVEVNX0JVTEsQFBIk", - "CiBNWF9DT01NQU5EX0tJTkRfUkVNT1ZFX0lURU1fQlVMSxAVEicKI01YX0NP", - "TU1BTkRfS0lORF9VTl9BRFZJU0VfSVRFTV9CVUxLEBYSIgoeTVhfQ09NTUFO", - "RF9LSU5EX1NVQlNDUklCRV9CVUxLEBcSJAogTVhfQ09NTUFORF9LSU5EX1VO", - "U1VCU0NSSUJFX0JVTEsQGBIYChRNWF9DT01NQU5EX0tJTkRfUElORxBkEiUK", - "IU1YX0NPTU1BTkRfS0lORF9HRVRfU0VTU0lPTl9TVEFURRBlEiMKH01YX0NP", - "TU1BTkRfS0lORF9HRVRfV09SS0VSX0lORk8QZhIgChxNWF9DT01NQU5EX0tJ", - "TkRfRFJBSU5fRVZFTlRTEGcSIwofTVhfQ09NTUFORF9LSU5EX1NIVVRET1dO", - "X1dPUktFUhBoKvkBCg1NeEV2ZW50RmFtaWx5Eh8KG01YX0VWRU5UX0ZBTUlM", - "WV9VTlNQRUNJRklFRBAAEiIKHk1YX0VWRU5UX0ZBTUlMWV9PTl9EQVRBX0NI", - "QU5HRRABEiUKIU1YX0VWRU5UX0ZBTUlMWV9PTl9XUklURV9DT01QTEVURRAC", - "EiYKIk1YX0VWRU5UX0ZBTUlMWV9PUEVSQVRJT05fQ09NUExFVEUQAxIrCidN", - "WF9FVkVOVF9GQU1JTFlfT05fQlVGRkVSRURfREFUQV9DSEFOR0UQBBInCiNN", - "WF9FVkVOVF9GQU1JTFlfT05fQUxBUk1fVFJBTlNJVElPThAFKsoBChNBbGFy", - "bVRyYW5zaXRpb25LaW5kEiUKIUFMQVJNX1RSQU5TSVRJT05fS0lORF9VTlNQ", - "RUNJRklFRBAAEh8KG0FMQVJNX1RSQU5TSVRJT05fS0lORF9SQUlTRRABEiUK", - "IUFMQVJNX1RSQU5TSVRJT05fS0lORF9BQ0tOT1dMRURHRRACEh8KG0FMQVJN", - "X1RSQU5TSVRJT05fS0lORF9DTEVBUhADEiMKH0FMQVJNX1RSQU5TSVRJT05f", - "S0lORF9SRVRSSUdHRVIQBCqqAQoTQWxhcm1Db25kaXRpb25TdGF0ZRIlCiFB", - "TEFSTV9DT05ESVRJT05fU1RBVEVfVU5TUEVDSUZJRUQQABIgChxBTEFSTV9D", - "T05ESVRJT05fU1RBVEVfQUNUSVZFEAESJgoiQUxBUk1fQ09ORElUSU9OX1NU", - "QVRFX0FDVElWRV9BQ0tFRBACEiIKHkFMQVJNX0NPTkRJVElPTl9TVEFURV9J", - "TkFDVElWRRADKqUDChBNeFN0YXR1c0NhdGVnb3J5EiIKHk1YX1NUQVRVU19D", - "QVRFR09SWV9VTlNQRUNJRklFRBAAEh4KGk1YX1NUQVRVU19DQVRFR09SWV9V", - "TktOT1dOEAESGQoVTVhfU1RBVFVTX0NBVEVHT1JZX09LEAISHgoaTVhfU1RB", - "VFVTX0NBVEVHT1JZX1BFTkRJTkcQAxIeChpNWF9TVEFUVVNfQ0FURUdPUllf", - "V0FSTklORxAEEioKJk1YX1NUQVRVU19DQVRFR09SWV9DT01NVU5JQ0FUSU9O", - "X0VSUk9SEAUSKgomTVhfU1RBVFVTX0NBVEVHT1JZX0NPTkZJR1VSQVRJT05f", - "RVJST1IQBhIoCiRNWF9TVEFUVVNfQ0FURUdPUllfT1BFUkFUSU9OQUxfRVJS", - "T1IQBxIlCiFNWF9TVEFUVVNfQ0FURUdPUllfU0VDVVJJVFlfRVJST1IQCBIl", - "CiFNWF9TVEFUVVNfQ0FURUdPUllfU09GVFdBUkVfRVJST1IQCRIiCh5NWF9T", - "VEFUVVNfQ0FURUdPUllfT1RIRVJfRVJST1IQCirKAgoOTXhTdGF0dXNTb3Vy", - "Y2USIAocTVhfU1RBVFVTX1NPVVJDRV9VTlNQRUNJRklFRBAAEhwKGE1YX1NU", - "QVRVU19TT1VSQ0VfVU5LTk9XThABEiMKH01YX1NUQVRVU19TT1VSQ0VfUkVR", - "VUVTVElOR19MTVgQAhIjCh9NWF9TVEFUVVNfU09VUkNFX1JFU1BPTkRJTkdf", - "TE1YEAMSIwofTVhfU1RBVFVTX1NPVVJDRV9SRVFVRVNUSU5HX05NWBAEEiMK", - "H01YX1NUQVRVU19TT1VSQ0VfUkVTUE9ORElOR19OTVgQBRIxCi1NWF9TVEFU", - "VVNfU09VUkNFX1JFUVVFU1RJTkdfQVVUT01BVElPTl9PQkpFQ1QQBhIxCi1N", - "WF9TVEFUVVNfU09VUkNFX1JFU1BPTkRJTkdfQVVUT01BVElPTl9PQkpFQ1QQ", - "ByrdBAoKTXhEYXRhVHlwZRIcChhNWF9EQVRBX1RZUEVfVU5TUEVDSUZJRUQQ", - "ABIYChRNWF9EQVRBX1RZUEVfVU5LTk9XThABEhgKFE1YX0RBVEFfVFlQRV9O", - "T19EQVRBEAISGAoUTVhfREFUQV9UWVBFX0JPT0xFQU4QAxIYChRNWF9EQVRB", - "X1RZUEVfSU5URUdFUhAEEhYKEk1YX0RBVEFfVFlQRV9GTE9BVBAFEhcKE01Y", - "X0RBVEFfVFlQRV9ET1VCTEUQBhIXChNNWF9EQVRBX1RZUEVfU1RSSU5HEAcS", - "FQoRTVhfREFUQV9UWVBFX1RJTUUQCBIdChlNWF9EQVRBX1RZUEVfRUxBUFNF", - "RF9USU1FEAkSHwobTVhfREFUQV9UWVBFX1JFRkVSRU5DRV9UWVBFEAoSHAoY", - "TVhfREFUQV9UWVBFX1NUQVRVU19UWVBFEAsSFQoRTVhfREFUQV9UWVBFX0VO", - "VU0QDBItCilNWF9EQVRBX1RZUEVfU0VDVVJJVFlfQ0xBU1NJRklDQVRJT05f", - "RU5VTRANEiIKHk1YX0RBVEFfVFlQRV9EQVRBX1FVQUxJVFlfVFlQRRAOEh8K", - "G01YX0RBVEFfVFlQRV9RVUFMSUZJRURfRU5VTRAPEiEKHU1YX0RBVEFfVFlQ", - "RV9RVUFMSUZJRURfU1RSVUNUEBASKQolTVhfREFUQV9UWVBFX0lOVEVSTkFU", - "SU9OQUxJWkVEX1NUUklORxAREhsKF01YX0RBVEFfVFlQRV9CSUdfU1RSSU5H", - "EBISFAoQTVhfREFUQV9UWVBFX0VORBATKqMDChJQcm90b2NvbFN0YXR1c0Nv", - "ZGUSJAogUFJPVE9DT0xfU1RBVFVTX0NPREVfVU5TUEVDSUZJRUQQABIbChdQ", - "Uk9UT0NPTF9TVEFUVVNfQ09ERV9PSxABEigKJFBST1RPQ09MX1NUQVRVU19D", - "T0RFX0lOVkFMSURfUkVRVUVTVBACEioKJlBST1RPQ09MX1NUQVRVU19DT0RF", - "X1NFU1NJT05fTk9UX0ZPVU5EEAMSKgomUFJPVE9DT0xfU1RBVFVTX0NPREVf", - "U0VTU0lPTl9OT1RfUkVBRFkQBBIrCidQUk9UT0NPTF9TVEFUVVNfQ09ERV9X", - "T1JLRVJfVU5BVkFJTEFCTEUQBRIgChxQUk9UT0NPTF9TVEFUVVNfQ09ERV9U", - "SU1FT1VUEAYSIQodUFJPVE9DT0xfU1RBVFVTX0NPREVfQ0FOQ0VMRUQQBxIr", - "CidQUk9UT0NPTF9TVEFUVVNfQ09ERV9QUk9UT0NPTF9WSU9MQVRJT04QCBIp", - "CiVQUk9UT0NPTF9TVEFUVVNfQ09ERV9NWEFDQ0VTU19GQUlMVVJFEAkqvwIK", - "DFNlc3Npb25TdGF0ZRIdChlTRVNTSU9OX1NUQVRFX1VOU1BFQ0lGSUVEEAAS", - "GgoWU0VTU0lPTl9TVEFURV9DUkVBVElORxABEiEKHVNFU1NJT05fU1RBVEVf", - "U1RBUlRJTkdfV09SS0VSEAISIgoeU0VTU0lPTl9TVEFURV9XQUlUSU5HX0ZP", - "Ul9QSVBFEAMSHQoZU0VTU0lPTl9TVEFURV9IQU5EU0hBS0lORxAEEiUKIVNF", - "U1NJT05fU1RBVEVfSU5JVElBTElaSU5HX1dPUktFUhAFEhcKE1NFU1NJT05f", - "U1RBVEVfUkVBRFkQBhIZChVTRVNTSU9OX1NUQVRFX0NMT1NJTkcQBxIYChRT", - "RVNTSU9OX1NUQVRFX0NMT1NFRBAIEhkKFVNFU1NJT05fU1RBVEVfRkFVTFRF", - "RBAJMuAECg9NeEFjY2Vzc0dhdGV3YXkSXQoLT3BlblNlc3Npb24SJy5teGFj", - "Y2Vzc19nYXRld2F5LnYxLk9wZW5TZXNzaW9uUmVxdWVzdBolLm14YWNjZXNz", - "X2dhdGV3YXkudjEuT3BlblNlc3Npb25SZXBseRJgCgxDbG9zZVNlc3Npb24S", - "KC5teGFjY2Vzc19nYXRld2F5LnYxLkNsb3NlU2Vzc2lvblJlcXVlc3QaJi5t", - "eGFjY2Vzc19nYXRld2F5LnYxLkNsb3NlU2Vzc2lvblJlcGx5ElQKBkludm9r", - "ZRIlLm14YWNjZXNzX2dhdGV3YXkudjEuTXhDb21tYW5kUmVxdWVzdBojLm14", - "YWNjZXNzX2dhdGV3YXkudjEuTXhDb21tYW5kUmVwbHkSWAoMU3RyZWFtRXZl", - "bnRzEigubXhhY2Nlc3NfZ2F0ZXdheS52MS5TdHJlYW1FdmVudHNSZXF1ZXN0", - "GhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeEV2ZW50MAESbAoQQWNrbm93bGVk", - "Z2VBbGFybRIsLm14YWNjZXNzX2dhdGV3YXkudjEuQWNrbm93bGVkZ2VBbGFy", - "bVJlcXVlc3QaKi5teGFjY2Vzc19nYXRld2F5LnYxLkFja25vd2xlZGdlQWxh", - "cm1SZXBseRJuChFRdWVyeUFjdGl2ZUFsYXJtcxItLm14YWNjZXNzX2dhdGV3", - "YXkudjEuUXVlcnlBY3RpdmVBbGFybXNSZXF1ZXN0GigubXhhY2Nlc3NfZ2F0", - "ZXdheS52MS5BY3RpdmVBbGFybVNuYXBzaG90MAFCHKoCGU14R2F0ZXdheS5D", - "b250cmFjdHMuUHJvdG9iBnByb3RvMw==")); + "IngKDFdyaXRlQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhMKC2l0", + "ZW1faGFuZGxlGAIgASgFEisKBXZhbHVlGAMgASgLMhwubXhhY2Nlc3NfZ2F0", + "ZXdheS52MS5NeFZhbHVlEg8KB3VzZXJfaWQYBCABKAUisAEKDVdyaXRlMkNv", + "bW1hbmQSFQoNc2VydmVyX2hhbmRsZRgBIAEoBRITCgtpdGVtX2hhbmRsZRgC", + "IAEoBRIrCgV2YWx1ZRgDIAEoCzIcLm14YWNjZXNzX2dhdGV3YXkudjEuTXhW", + "YWx1ZRI1Cg90aW1lc3RhbXBfdmFsdWUYBCABKAsyHC5teGFjY2Vzc19nYXRl", + "d2F5LnYxLk14VmFsdWUSDwoHdXNlcl9pZBgFIAEoBSKhAQoTV3JpdGVTZWN1", + "cmVkQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhMKC2l0ZW1faGFu", + "ZGxlGAIgASgFEhcKD2N1cnJlbnRfdXNlcl9pZBgDIAEoBRIYChB2ZXJpZmll", + "cl91c2VyX2lkGAQgASgFEisKBXZhbHVlGAUgASgLMhwubXhhY2Nlc3NfZ2F0", + "ZXdheS52MS5NeFZhbHVlItkBChRXcml0ZVNlY3VyZWQyQ29tbWFuZBIVCg1z", + "ZXJ2ZXJfaGFuZGxlGAEgASgFEhMKC2l0ZW1faGFuZGxlGAIgASgFEhcKD2N1", + "cnJlbnRfdXNlcl9pZBgDIAEoBRIYChB2ZXJpZmllcl91c2VyX2lkGAQgASgF", + "EisKBXZhbHVlGAUgASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFZhbHVl", + "EjUKD3RpbWVzdGFtcF92YWx1ZRgGIAEoCzIcLm14YWNjZXNzX2dhdGV3YXku", + "djEuTXhWYWx1ZSJjChdBdXRoZW50aWNhdGVVc2VyQ29tbWFuZBIVCg1zZXJ2", + "ZXJfaGFuZGxlGAEgASgFEhMKC3ZlcmlmeV91c2VyGAIgASgJEhwKFHZlcmlm", + "eV91c2VyX3Bhc3N3b3JkGAMgASgJIkcKGEFyY2hlc3RyQVVzZXJUb0lkQ29t", + "bWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhQKDHVzZXJfaWRfZ3VpZBgC", + "IAEoCSJCChJBZGRJdGVtQnVsa0NvbW1hbmQSFQoNc2VydmVyX2hhbmRsZRgB", + "IAEoBRIVCg10YWdfYWRkcmVzc2VzGAIgAygJIkQKFUFkdmlzZUl0ZW1CdWxr", + "Q29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhQKDGl0ZW1faGFuZGxl", + "cxgCIAMoBSJEChVSZW1vdmVJdGVtQnVsa0NvbW1hbmQSFQoNc2VydmVyX2hh", + "bmRsZRgBIAEoBRIUCgxpdGVtX2hhbmRsZXMYAiADKAUiRgoXVW5BZHZpc2VJ", + "dGVtQnVsa0NvbW1hbmQSFQoNc2VydmVyX2hhbmRsZRgBIAEoBRIUCgxpdGVt", + "X2hhbmRsZXMYAiADKAUiRAoUU3Vic2NyaWJlQnVsa0NvbW1hbmQSFQoNc2Vy", + "dmVyX2hhbmRsZRgBIAEoBRIVCg10YWdfYWRkcmVzc2VzGAIgAygJIjkKFlN1", + "YnNjcmliZUFsYXJtc0NvbW1hbmQSHwoXc3Vic2NyaXB0aW9uX2V4cHJlc3Np", + "b24YASABKAkiGgoYVW5zdWJzY3JpYmVBbGFybXNDb21tYW5kIqEBChdBY2tu", + "b3dsZWRnZUFsYXJtQ29tbWFuZBISCgphbGFybV9ndWlkGAEgASgJEg8KB2Nv", + "bW1lbnQYAiABKAkSFQoNb3BlcmF0b3JfdXNlchgDIAEoCRIVCg1vcGVyYXRv", + "cl9ub2RlGAQgASgJEhcKD29wZXJhdG9yX2RvbWFpbhgFIAEoCRIaChJvcGVy", + "YXRvcl9mdWxsX25hbWUYBiABKAkiNwoYUXVlcnlBY3RpdmVBbGFybXNDb21t", + "YW5kEhsKE2FsYXJtX2ZpbHRlcl9wcmVmaXgYASABKAkiRQoWVW5zdWJzY3Jp", + "YmVCdWxrQ29tbWFuZBIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFEhQKDGl0ZW1f", + "aGFuZGxlcxgCIAMoBSIeCgtQaW5nQ29tbWFuZBIPCgdtZXNzYWdlGAEgASgJ", + "IhgKFkdldFNlc3Npb25TdGF0ZUNvbW1hbmQiFgoUR2V0V29ya2VySW5mb0Nv", + "bW1hbmQiKAoSRHJhaW5FdmVudHNDb21tYW5kEhIKCm1heF9ldmVudHMYASAB", + "KA0iSAoVU2h1dGRvd25Xb3JrZXJDb21tYW5kEi8KDGdyYWNlX3BlcmlvZBgB", + "IAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiLPDAoOTXhDb21tYW5k", + "UmVwbHkSEgoKc2Vzc2lvbl9pZBgBIAEoCRIWCg5jb3JyZWxhdGlvbl9pZBgC", + "IAEoCRIwCgRraW5kGAMgASgOMiIubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeENv", + "bW1hbmRLaW5kEjwKD3Byb3RvY29sX3N0YXR1cxgEIAEoCzIjLm14YWNjZXNz", + "X2dhdGV3YXkudjEuUHJvdG9jb2xTdGF0dXMSFAoHaHJlc3VsdBgFIAEoBUgB", + "iAEBEjIKDHJldHVybl92YWx1ZRgGIAEoCzIcLm14YWNjZXNzX2dhdGV3YXku", + "djEuTXhWYWx1ZRI0CghzdGF0dXNlcxgHIAMoCzIiLm14YWNjZXNzX2dhdGV3", + "YXkudjEuTXhTdGF0dXNQcm94eRIaChJkaWFnbm9zdGljX21lc3NhZ2UYCCAB", + "KAkSNgoIcmVnaXN0ZXIYFCABKAsyIi5teGFjY2Vzc19nYXRld2F5LnYxLlJl", + "Z2lzdGVyUmVwbHlIABI1CghhZGRfaXRlbRgVIAEoCzIhLm14YWNjZXNzX2dh", + "dGV3YXkudjEuQWRkSXRlbVJlcGx5SAASNwoJYWRkX2l0ZW0yGBYgASgLMiIu", + "bXhhY2Nlc3NfZ2F0ZXdheS52MS5BZGRJdGVtMlJlcGx5SAASRgoRYWRkX2J1", + "ZmZlcmVkX2l0ZW0YFyABKAsyKS5teGFjY2Vzc19nYXRld2F5LnYxLkFkZEJ1", + "ZmZlcmVkSXRlbVJlcGx5SAASNAoHc3VzcGVuZBgYIAEoCzIhLm14YWNjZXNz", + "X2dhdGV3YXkudjEuU3VzcGVuZFJlcGx5SAASNgoIYWN0aXZhdGUYGSABKAsy", + "Ii5teGFjY2Vzc19nYXRld2F5LnYxLkFjdGl2YXRlUmVwbHlIABJHChFhdXRo", + "ZW50aWNhdGVfdXNlchgaIAEoCzIqLm14YWNjZXNzX2dhdGV3YXkudjEuQXV0", + "aGVudGljYXRlVXNlclJlcGx5SAASSwoUYXJjaGVzdHJhX3VzZXJfdG9faWQY", + "GyABKAsyKy5teGFjY2Vzc19nYXRld2F5LnYxLkFyY2hlc3RyQVVzZXJUb0lk", + "UmVwbHlIABJACg1hZGRfaXRlbV9idWxrGBwgASgLMicubXhhY2Nlc3NfZ2F0", + "ZXdheS52MS5CdWxrU3Vic2NyaWJlUmVwbHlIABJDChBhZHZpc2VfaXRlbV9i", + "dWxrGB0gASgLMicubXhhY2Nlc3NfZ2F0ZXdheS52MS5CdWxrU3Vic2NyaWJl", + "UmVwbHlIABJDChByZW1vdmVfaXRlbV9idWxrGB4gASgLMicubXhhY2Nlc3Nf", + "Z2F0ZXdheS52MS5CdWxrU3Vic2NyaWJlUmVwbHlIABJGChN1bl9hZHZpc2Vf", + "aXRlbV9idWxrGB8gASgLMicubXhhY2Nlc3NfZ2F0ZXdheS52MS5CdWxrU3Vi", + "c2NyaWJlUmVwbHlIABJBCg5zdWJzY3JpYmVfYnVsaxggIAEoCzInLm14YWNj", + "ZXNzX2dhdGV3YXkudjEuQnVsa1N1YnNjcmliZVJlcGx5SAASQwoQdW5zdWJz", + "Y3JpYmVfYnVsaxghIAEoCzInLm14YWNjZXNzX2dhdGV3YXkudjEuQnVsa1N1", + "YnNjcmliZVJlcGx5SAASTgoRYWNrbm93bGVkZ2VfYWxhcm0YIiABKAsyMS5t", + "eGFjY2Vzc19nYXRld2F5LnYxLkFja25vd2xlZGdlQWxhcm1SZXBseVBheWxv", + "YWRIABJRChNxdWVyeV9hY3RpdmVfYWxhcm1zGCMgASgLMjIubXhhY2Nlc3Nf", + "Z2F0ZXdheS52MS5RdWVyeUFjdGl2ZUFsYXJtc1JlcGx5UGF5bG9hZEgAEj8K", + "DXNlc3Npb25fc3RhdGUYZCABKAsyJi5teGFjY2Vzc19nYXRld2F5LnYxLlNl", + "c3Npb25TdGF0ZVJlcGx5SAASOwoLd29ya2VyX2luZm8YZSABKAsyJC5teGFj", + "Y2Vzc19nYXRld2F5LnYxLldvcmtlckluZm9SZXBseUgAEj0KDGRyYWluX2V2", + "ZW50cxhmIAEoCzIlLm14YWNjZXNzX2dhdGV3YXkudjEuRHJhaW5FdmVudHNS", + "ZXBseUgAQgkKB3BheWxvYWRCCgoIX2hyZXN1bHQiJgoNUmVnaXN0ZXJSZXBs", + "eRIVCg1zZXJ2ZXJfaGFuZGxlGAEgASgFIiMKDEFkZEl0ZW1SZXBseRITCgtp", + "dGVtX2hhbmRsZRgBIAEoBSIkCg1BZGRJdGVtMlJlcGx5EhMKC2l0ZW1faGFu", + "ZGxlGAEgASgFIisKFEFkZEJ1ZmZlcmVkSXRlbVJlcGx5EhMKC2l0ZW1faGFu", + "ZGxlGAEgASgFIkIKDFN1c3BlbmRSZXBseRIyCgZzdGF0dXMYASABKAsyIi5t", + "eGFjY2Vzc19nYXRld2F5LnYxLk14U3RhdHVzUHJveHkiQwoNQWN0aXZhdGVS", + "ZXBseRIyCgZzdGF0dXMYASABKAsyIi5teGFjY2Vzc19nYXRld2F5LnYxLk14", + "U3RhdHVzUHJveHkiKAoVQXV0aGVudGljYXRlVXNlclJlcGx5Eg8KB3VzZXJf", + "aWQYASABKAUiKQoWQXJjaGVzdHJBVXNlclRvSWRSZXBseRIPCgd1c2VyX2lk", + "GAEgASgFIoEBCg9TdWJzY3JpYmVSZXN1bHQSFQoNc2VydmVyX2hhbmRsZRgB", + "IAEoBRITCgt0YWdfYWRkcmVzcxgCIAEoCRITCgtpdGVtX2hhbmRsZRgDIAEo", + "BRIWCg53YXNfc3VjY2Vzc2Z1bBgEIAEoCBIVCg1lcnJvcl9tZXNzYWdlGAUg", + "ASgJIksKEkJ1bGtTdWJzY3JpYmVSZXBseRI1CgdyZXN1bHRzGAEgAygLMiQu", + "bXhhY2Nlc3NfZ2F0ZXdheS52MS5TdWJzY3JpYmVSZXN1bHQiRQoRU2Vzc2lv", + "blN0YXRlUmVwbHkSMAoFc3RhdGUYASABKA4yIS5teGFjY2Vzc19nYXRld2F5", + "LnYxLlNlc3Npb25TdGF0ZSJ1Cg9Xb3JrZXJJbmZvUmVwbHkSGQoRd29ya2Vy", + "X3Byb2Nlc3NfaWQYASABKAUSFgoOd29ya2VyX3ZlcnNpb24YAiABKAkSFwoP", + "bXhhY2Nlc3NfcHJvZ2lkGAMgASgJEhYKDm14YWNjZXNzX2Nsc2lkGAQgASgJ", + "IkAKEERyYWluRXZlbnRzUmVwbHkSLAoGZXZlbnRzGAEgAygLMhwubXhhY2Nl", + "c3NfZ2F0ZXdheS52MS5NeEV2ZW50IjUKHEFja25vd2xlZGdlQWxhcm1SZXBs", + "eVBheWxvYWQSFQoNbmF0aXZlX3N0YXR1cxgBIAEoBSJcCh1RdWVyeUFjdGl2", + "ZUFsYXJtc1JlcGx5UGF5bG9hZBI7CglzbmFwc2hvdHMYASADKAsyKC5teGFj", + "Y2Vzc19nYXRld2F5LnYxLkFjdGl2ZUFsYXJtU25hcHNob3Qi5wYKB014RXZl", + "bnQSMgoGZmFtaWx5GAEgASgOMiIubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeEV2", + "ZW50RmFtaWx5EhIKCnNlc3Npb25faWQYAiABKAkSFQoNc2VydmVyX2hhbmRs", + "ZRgDIAEoBRITCgtpdGVtX2hhbmRsZRgEIAEoBRIrCgV2YWx1ZRgFIAEoCzIc", + "Lm14YWNjZXNzX2dhdGV3YXkudjEuTXhWYWx1ZRIPCgdxdWFsaXR5GAYgASgF", + "EjQKEHNvdXJjZV90aW1lc3RhbXAYByABKAsyGi5nb29nbGUucHJvdG9idWYu", + "VGltZXN0YW1wEjQKCHN0YXR1c2VzGAggAygLMiIubXhhY2Nlc3NfZ2F0ZXdh", + "eS52MS5NeFN0YXR1c1Byb3h5EhcKD3dvcmtlcl9zZXF1ZW5jZRgJIAEoBBI0", + "ChB3b3JrZXJfdGltZXN0YW1wGAogASgLMhouZ29vZ2xlLnByb3RvYnVmLlRp", + "bWVzdGFtcBI9ChlnYXRld2F5X3JlY2VpdmVfdGltZXN0YW1wGAsgASgLMhou", + "Z29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIUCgdocmVzdWx0GAwgASgFSAGI", + "AQESEgoKcmF3X3N0YXR1cxgNIAEoCRJACg5vbl9kYXRhX2NoYW5nZRgUIAEo", + "CzImLm14YWNjZXNzX2dhdGV3YXkudjEuT25EYXRhQ2hhbmdlRXZlbnRIABJG", + "ChFvbl93cml0ZV9jb21wbGV0ZRgVIAEoCzIpLm14YWNjZXNzX2dhdGV3YXku", + "djEuT25Xcml0ZUNvbXBsZXRlRXZlbnRIABJJChJvcGVyYXRpb25fY29tcGxl", + "dGUYFiABKAsyKy5teGFjY2Vzc19nYXRld2F5LnYxLk9wZXJhdGlvbkNvbXBs", + "ZXRlRXZlbnRIABJRChdvbl9idWZmZXJlZF9kYXRhX2NoYW5nZRgXIAEoCzIu", + "Lm14YWNjZXNzX2dhdGV3YXkudjEuT25CdWZmZXJlZERhdGFDaGFuZ2VFdmVu", + "dEgAEkoKE29uX2FsYXJtX3RyYW5zaXRpb24YGCABKAsyKy5teGFjY2Vzc19n", + "YXRld2F5LnYxLk9uQWxhcm1UcmFuc2l0aW9uRXZlbnRIAEIGCgRib2R5QgoK", + "CF9ocmVzdWx0IhMKEU9uRGF0YUNoYW5nZUV2ZW50IhYKFE9uV3JpdGVDb21w", + "bGV0ZUV2ZW50IhgKFk9wZXJhdGlvbkNvbXBsZXRlRXZlbnQi1AEKGU9uQnVm", + "ZmVyZWREYXRhQ2hhbmdlRXZlbnQSMgoJZGF0YV90eXBlGAEgASgOMh8ubXhh", + "Y2Nlc3NfZ2F0ZXdheS52MS5NeERhdGFUeXBlEjQKDnF1YWxpdHlfdmFsdWVz", + "GAIgASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeEFycmF5EjYKEHRpbWVz", + "dGFtcF92YWx1ZXMYAyABKAsyHC5teGFjY2Vzc19nYXRld2F5LnYxLk14QXJy", + "YXkSFQoNcmF3X2RhdGFfdHlwZRgEIAEoBSL9AwoWT25BbGFybVRyYW5zaXRp", + "b25FdmVudBIcChRhbGFybV9mdWxsX3JlZmVyZW5jZRgBIAEoCRIfChdzb3Vy", + "Y2Vfb2JqZWN0X3JlZmVyZW5jZRgCIAEoCRIXCg9hbGFybV90eXBlX25hbWUY", + "AyABKAkSQQoPdHJhbnNpdGlvbl9raW5kGAQgASgOMigubXhhY2Nlc3NfZ2F0", + "ZXdheS52MS5BbGFybVRyYW5zaXRpb25LaW5kEhAKCHNldmVyaXR5GAUgASgF", + "EjwKGG9yaWdpbmFsX3JhaXNlX3RpbWVzdGFtcBgGIAEoCzIaLmdvb2dsZS5w", + "cm90b2J1Zi5UaW1lc3RhbXASOAoUdHJhbnNpdGlvbl90aW1lc3RhbXAYByAB", + "KAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhUKDW9wZXJhdG9yX3Vz", + "ZXIYCCABKAkSGAoQb3BlcmF0b3JfY29tbWVudBgJIAEoCRIQCghjYXRlZ29y", + "eRgKIAEoCRITCgtkZXNjcmlwdGlvbhgLIAEoCRIzCg1jdXJyZW50X3ZhbHVl", + "GAwgASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFZhbHVlEjEKC2xpbWl0", + "X3ZhbHVlGA0gASgLMhwubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFZhbHVlIv0D", + "ChNBY3RpdmVBbGFybVNuYXBzaG90EhwKFGFsYXJtX2Z1bGxfcmVmZXJlbmNl", + "GAEgASgJEh8KF3NvdXJjZV9vYmplY3RfcmVmZXJlbmNlGAIgASgJEhcKD2Fs", + "YXJtX3R5cGVfbmFtZRgDIAEoCRIQCghzZXZlcml0eRgEIAEoBRI8Chhvcmln", + "aW5hbF9yYWlzZV90aW1lc3RhbXAYBSABKAsyGi5nb29nbGUucHJvdG9idWYu", + "VGltZXN0YW1wEj8KDWN1cnJlbnRfc3RhdGUYBiABKA4yKC5teGFjY2Vzc19n", + "YXRld2F5LnYxLkFsYXJtQ29uZGl0aW9uU3RhdGUSEAoIY2F0ZWdvcnkYByAB", + "KAkSEwoLZGVzY3JpcHRpb24YCCABKAkSPQoZbGFzdF90cmFuc2l0aW9uX3Rp", + "bWVzdGFtcBgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFQoN", + "b3BlcmF0b3JfdXNlchgKIAEoCRIYChBvcGVyYXRvcl9jb21tZW50GAsgASgJ", + "EjMKDWN1cnJlbnRfdmFsdWUYDCABKAsyHC5teGFjY2Vzc19nYXRld2F5LnYx", + "Lk14VmFsdWUSMQoLbGltaXRfdmFsdWUYDSABKAsyHC5teGFjY2Vzc19nYXRl", + "d2F5LnYxLk14VmFsdWUikgEKF0Fja25vd2xlZGdlQWxhcm1SZXF1ZXN0EhIK", + "CnNlc3Npb25faWQYASABKAkSHQoVY2xpZW50X2NvcnJlbGF0aW9uX2lkGAIg", + "ASgJEhwKFGFsYXJtX2Z1bGxfcmVmZXJlbmNlGAMgASgJEg8KB2NvbW1lbnQY", + "BCABKAkSFQoNb3BlcmF0b3JfdXNlchgFIAEoCSLzAQoVQWNrbm93bGVkZ2VB", + "bGFybVJlcGx5EhIKCnNlc3Npb25faWQYASABKAkSFgoOY29ycmVsYXRpb25f", + "aWQYAiABKAkSPAoPcHJvdG9jb2xfc3RhdHVzGAMgASgLMiMubXhhY2Nlc3Nf", + "Z2F0ZXdheS52MS5Qcm90b2NvbFN0YXR1cxIUCgdocmVzdWx0GAQgASgFSACI", + "AQESMgoGc3RhdHVzGAUgASgLMiIubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFN0", + "YXR1c1Byb3h5EhoKEmRpYWdub3N0aWNfbWVzc2FnZRgGIAEoCUIKCghfaHJl", + "c3VsdCJqChhRdWVyeUFjdGl2ZUFsYXJtc1JlcXVlc3QSEgoKc2Vzc2lvbl9p", + "ZBgBIAEoCRIdChVjbGllbnRfY29ycmVsYXRpb25faWQYAiABKAkSGwoTYWxh", + "cm1fZmlsdGVyX3ByZWZpeBgDIAEoCSLrAQoNTXhTdGF0dXNQcm94eRIPCgdz", + "dWNjZXNzGAEgASgFEjcKCGNhdGVnb3J5GAIgASgOMiUubXhhY2Nlc3NfZ2F0", + "ZXdheS52MS5NeFN0YXR1c0NhdGVnb3J5EjgKC2RldGVjdGVkX2J5GAMgASgO", + "MiMubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeFN0YXR1c1NvdXJjZRIOCgZkZXRh", + "aWwYBCABKAUSFAoMcmF3X2NhdGVnb3J5GAUgASgFEhcKD3Jhd19kZXRlY3Rl", + "ZF9ieRgGIAEoBRIXCg9kaWFnbm9zdGljX3RleHQYByABKAkipwMKB014VmFs", + "dWUSMgoJZGF0YV90eXBlGAEgASgOMh8ubXhhY2Nlc3NfZ2F0ZXdheS52MS5N", + "eERhdGFUeXBlEhQKDHZhcmlhbnRfdHlwZRgCIAEoCRIPCgdpc19udWxsGAMg", + "ASgIEhYKDnJhd19kaWFnbm9zdGljGAQgASgJEhUKDXJhd19kYXRhX3R5cGUY", + "BSABKAUSFAoKYm9vbF92YWx1ZRgKIAEoCEgAEhUKC2ludDMyX3ZhbHVlGAsg", + "ASgFSAASFQoLaW50NjRfdmFsdWUYDCABKANIABIVCgtmbG9hdF92YWx1ZRgN", + "IAEoAkgAEhYKDGRvdWJsZV92YWx1ZRgOIAEoAUgAEhYKDHN0cmluZ192YWx1", + "ZRgPIAEoCUgAEjUKD3RpbWVzdGFtcF92YWx1ZRgQIAEoCzIaLmdvb2dsZS5w", + "cm90b2J1Zi5UaW1lc3RhbXBIABIzCgthcnJheV92YWx1ZRgRIAEoCzIcLm14", + "YWNjZXNzX2dhdGV3YXkudjEuTXhBcnJheUgAEhMKCXJhd192YWx1ZRgSIAEo", + "DEgAQgYKBGtpbmQi/gQKB014QXJyYXkSOgoRZWxlbWVudF9kYXRhX3R5cGUY", + "ASABKA4yHy5teGFjY2Vzc19nYXRld2F5LnYxLk14RGF0YVR5cGUSFAoMdmFy", + "aWFudF90eXBlGAIgASgJEhIKCmRpbWVuc2lvbnMYAyADKA0SFgoOcmF3X2Rp", + "YWdub3N0aWMYBCABKAkSHQoVcmF3X2VsZW1lbnRfZGF0YV90eXBlGAUgASgF", + "EjUKC2Jvb2xfdmFsdWVzGAogASgLMh4ubXhhY2Nlc3NfZ2F0ZXdheS52MS5C", + "b29sQXJyYXlIABI3CgxpbnQzMl92YWx1ZXMYCyABKAsyHy5teGFjY2Vzc19n", + "YXRld2F5LnYxLkludDMyQXJyYXlIABI3CgxpbnQ2NF92YWx1ZXMYDCABKAsy", + "Hy5teGFjY2Vzc19nYXRld2F5LnYxLkludDY0QXJyYXlIABI3CgxmbG9hdF92", + "YWx1ZXMYDSABKAsyHy5teGFjY2Vzc19nYXRld2F5LnYxLkZsb2F0QXJyYXlI", + "ABI5Cg1kb3VibGVfdmFsdWVzGA4gASgLMiAubXhhY2Nlc3NfZ2F0ZXdheS52", + "MS5Eb3VibGVBcnJheUgAEjkKDXN0cmluZ192YWx1ZXMYDyABKAsyIC5teGFj", + "Y2Vzc19nYXRld2F5LnYxLlN0cmluZ0FycmF5SAASPwoQdGltZXN0YW1wX3Zh", + "bHVlcxgQIAEoCzIjLm14YWNjZXNzX2dhdGV3YXkudjEuVGltZXN0YW1wQXJy", + "YXlIABIzCgpyYXdfdmFsdWVzGBEgASgLMh0ubXhhY2Nlc3NfZ2F0ZXdheS52", + "MS5SYXdBcnJheUgAQggKBnZhbHVlcyIbCglCb29sQXJyYXkSDgoGdmFsdWVz", + "GAEgAygIIhwKCkludDMyQXJyYXkSDgoGdmFsdWVzGAEgAygFIhwKCkludDY0", + "QXJyYXkSDgoGdmFsdWVzGAEgAygDIhwKCkZsb2F0QXJyYXkSDgoGdmFsdWVz", + "GAEgAygCIh0KC0RvdWJsZUFycmF5Eg4KBnZhbHVlcxgBIAMoASIdCgtTdHJp", + "bmdBcnJheRIOCgZ2YWx1ZXMYASADKAkiPAoOVGltZXN0YW1wQXJyYXkSKgoG", + "dmFsdWVzGAEgAygLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIaCghS", + "YXdBcnJheRIOCgZ2YWx1ZXMYASADKAwiWAoOUHJvdG9jb2xTdGF0dXMSNQoE", + "Y29kZRgBIAEoDjInLm14YWNjZXNzX2dhdGV3YXkudjEuUHJvdG9jb2xTdGF0", + "dXNDb2RlEg8KB21lc3NhZ2UYAiABKAkqvwkKDU14Q29tbWFuZEtpbmQSHwob", + "TVhfQ09NTUFORF9LSU5EX1VOU1BFQ0lGSUVEEAASHAoYTVhfQ09NTUFORF9L", + "SU5EX1JFR0lTVEVSEAESHgoaTVhfQ09NTUFORF9LSU5EX1VOUkVHSVNURVIQ", + "AhIcChhNWF9DT01NQU5EX0tJTkRfQUREX0lURU0QAxIdChlNWF9DT01NQU5E", + "X0tJTkRfQUREX0lURU0yEAQSHwobTVhfQ09NTUFORF9LSU5EX1JFTU9WRV9J", + "VEVNEAUSGgoWTVhfQ09NTUFORF9LSU5EX0FEVklTRRAGEh0KGU1YX0NPTU1B", + "TkRfS0lORF9VTl9BRFZJU0UQBxImCiJNWF9DT01NQU5EX0tJTkRfQURWSVNF", + "X1NVUEVSVklTT1JZEAgSJQohTVhfQ09NTUFORF9LSU5EX0FERF9CVUZGRVJF", + "RF9JVEVNEAkSMAosTVhfQ09NTUFORF9LSU5EX1NFVF9CVUZGRVJFRF9VUERB", + "VEVfSU5URVJWQUwQChIbChdNWF9DT01NQU5EX0tJTkRfU1VTUEVORBALEhwK", + "GE1YX0NPTU1BTkRfS0lORF9BQ1RJVkFURRAMEhkKFU1YX0NPTU1BTkRfS0lO", + "RF9XUklURRANEhoKFk1YX0NPTU1BTkRfS0lORF9XUklURTIQDhIhCh1NWF9D", + "T01NQU5EX0tJTkRfV1JJVEVfU0VDVVJFRBAPEiIKHk1YX0NPTU1BTkRfS0lO", + "RF9XUklURV9TRUNVUkVEMhAQEiUKIU1YX0NPTU1BTkRfS0lORF9BVVRIRU5U", + "SUNBVEVfVVNFUhAREigKJE1YX0NPTU1BTkRfS0lORF9BUkNIRVNUUkFfVVNF", + "Ul9UT19JRBASEiEKHU1YX0NPTU1BTkRfS0lORF9BRERfSVRFTV9CVUxLEBMS", + "JAogTVhfQ09NTUFORF9LSU5EX0FEVklTRV9JVEVNX0JVTEsQFBIkCiBNWF9D", + "T01NQU5EX0tJTkRfUkVNT1ZFX0lURU1fQlVMSxAVEicKI01YX0NPTU1BTkRf", + "S0lORF9VTl9BRFZJU0VfSVRFTV9CVUxLEBYSIgoeTVhfQ09NTUFORF9LSU5E", + "X1NVQlNDUklCRV9CVUxLEBcSJAogTVhfQ09NTUFORF9LSU5EX1VOU1VCU0NS", + "SUJFX0JVTEsQGBIkCiBNWF9DT01NQU5EX0tJTkRfU1VCU0NSSUJFX0FMQVJN", + "UxAZEiYKIk1YX0NPTU1BTkRfS0lORF9VTlNVQlNDUklCRV9BTEFSTVMQGhIl", + "CiFNWF9DT01NQU5EX0tJTkRfQUNLTk9XTEVER0VfQUxBUk0QGxInCiNNWF9D", + "T01NQU5EX0tJTkRfUVVFUllfQUNUSVZFX0FMQVJNUxAcEhgKFE1YX0NPTU1B", + "TkRfS0lORF9QSU5HEGQSJQohTVhfQ09NTUFORF9LSU5EX0dFVF9TRVNTSU9O", + "X1NUQVRFEGUSIwofTVhfQ09NTUFORF9LSU5EX0dFVF9XT1JLRVJfSU5GTxBm", + "EiAKHE1YX0NPTU1BTkRfS0lORF9EUkFJTl9FVkVOVFMQZxIjCh9NWF9DT01N", + "QU5EX0tJTkRfU0hVVERPV05fV09SS0VSEGgq+QEKDU14RXZlbnRGYW1pbHkS", + "HwobTVhfRVZFTlRfRkFNSUxZX1VOU1BFQ0lGSUVEEAASIgoeTVhfRVZFTlRf", + "RkFNSUxZX09OX0RBVEFfQ0hBTkdFEAESJQohTVhfRVZFTlRfRkFNSUxZX09O", + "X1dSSVRFX0NPTVBMRVRFEAISJgoiTVhfRVZFTlRfRkFNSUxZX09QRVJBVElP", + "Tl9DT01QTEVURRADEisKJ01YX0VWRU5UX0ZBTUlMWV9PTl9CVUZGRVJFRF9E", + "QVRBX0NIQU5HRRAEEicKI01YX0VWRU5UX0ZBTUlMWV9PTl9BTEFSTV9UUkFO", + "U0lUSU9OEAUqygEKE0FsYXJtVHJhbnNpdGlvbktpbmQSJQohQUxBUk1fVFJB", + "TlNJVElPTl9LSU5EX1VOU1BFQ0lGSUVEEAASHwobQUxBUk1fVFJBTlNJVElP", + "Tl9LSU5EX1JBSVNFEAESJQohQUxBUk1fVFJBTlNJVElPTl9LSU5EX0FDS05P", + "V0xFREdFEAISHwobQUxBUk1fVFJBTlNJVElPTl9LSU5EX0NMRUFSEAMSIwof", + "QUxBUk1fVFJBTlNJVElPTl9LSU5EX1JFVFJJR0dFUhAEKqoBChNBbGFybUNv", + "bmRpdGlvblN0YXRlEiUKIUFMQVJNX0NPTkRJVElPTl9TVEFURV9VTlNQRUNJ", + "RklFRBAAEiAKHEFMQVJNX0NPTkRJVElPTl9TVEFURV9BQ1RJVkUQARImCiJB", + "TEFSTV9DT05ESVRJT05fU1RBVEVfQUNUSVZFX0FDS0VEEAISIgoeQUxBUk1f", + "Q09ORElUSU9OX1NUQVRFX0lOQUNUSVZFEAMqpQMKEE14U3RhdHVzQ2F0ZWdv", + "cnkSIgoeTVhfU1RBVFVTX0NBVEVHT1JZX1VOU1BFQ0lGSUVEEAASHgoaTVhf", + "U1RBVFVTX0NBVEVHT1JZX1VOS05PV04QARIZChVNWF9TVEFUVVNfQ0FURUdP", + "UllfT0sQAhIeChpNWF9TVEFUVVNfQ0FURUdPUllfUEVORElORxADEh4KGk1Y", + "X1NUQVRVU19DQVRFR09SWV9XQVJOSU5HEAQSKgomTVhfU1RBVFVTX0NBVEVH", + "T1JZX0NPTU1VTklDQVRJT05fRVJST1IQBRIqCiZNWF9TVEFUVVNfQ0FURUdP", + "UllfQ09ORklHVVJBVElPTl9FUlJPUhAGEigKJE1YX1NUQVRVU19DQVRFR09S", + "WV9PUEVSQVRJT05BTF9FUlJPUhAHEiUKIU1YX1NUQVRVU19DQVRFR09SWV9T", + "RUNVUklUWV9FUlJPUhAIEiUKIU1YX1NUQVRVU19DQVRFR09SWV9TT0ZUV0FS", + "RV9FUlJPUhAJEiIKHk1YX1NUQVRVU19DQVRFR09SWV9PVEhFUl9FUlJPUhAK", + "KsoCCg5NeFN0YXR1c1NvdXJjZRIgChxNWF9TVEFUVVNfU09VUkNFX1VOU1BF", + "Q0lGSUVEEAASHAoYTVhfU1RBVFVTX1NPVVJDRV9VTktOT1dOEAESIwofTVhf", + "U1RBVFVTX1NPVVJDRV9SRVFVRVNUSU5HX0xNWBACEiMKH01YX1NUQVRVU19T", + "T1VSQ0VfUkVTUE9ORElOR19MTVgQAxIjCh9NWF9TVEFUVVNfU09VUkNFX1JF", + "UVVFU1RJTkdfTk1YEAQSIwofTVhfU1RBVFVTX1NPVVJDRV9SRVNQT05ESU5H", + "X05NWBAFEjEKLU1YX1NUQVRVU19TT1VSQ0VfUkVRVUVTVElOR19BVVRPTUFU", + "SU9OX09CSkVDVBAGEjEKLU1YX1NUQVRVU19TT1VSQ0VfUkVTUE9ORElOR19B", + "VVRPTUFUSU9OX09CSkVDVBAHKt0ECgpNeERhdGFUeXBlEhwKGE1YX0RBVEFf", + "VFlQRV9VTlNQRUNJRklFRBAAEhgKFE1YX0RBVEFfVFlQRV9VTktOT1dOEAES", + "GAoUTVhfREFUQV9UWVBFX05PX0RBVEEQAhIYChRNWF9EQVRBX1RZUEVfQk9P", + "TEVBThADEhgKFE1YX0RBVEFfVFlQRV9JTlRFR0VSEAQSFgoSTVhfREFUQV9U", + "WVBFX0ZMT0FUEAUSFwoTTVhfREFUQV9UWVBFX0RPVUJMRRAGEhcKE01YX0RB", + "VEFfVFlQRV9TVFJJTkcQBxIVChFNWF9EQVRBX1RZUEVfVElNRRAIEh0KGU1Y", + "X0RBVEFfVFlQRV9FTEFQU0VEX1RJTUUQCRIfChtNWF9EQVRBX1RZUEVfUkVG", + "RVJFTkNFX1RZUEUQChIcChhNWF9EQVRBX1RZUEVfU1RBVFVTX1RZUEUQCxIV", + "ChFNWF9EQVRBX1RZUEVfRU5VTRAMEi0KKU1YX0RBVEFfVFlQRV9TRUNVUklU", + "WV9DTEFTU0lGSUNBVElPTl9FTlVNEA0SIgoeTVhfREFUQV9UWVBFX0RBVEFf", + "UVVBTElUWV9UWVBFEA4SHwobTVhfREFUQV9UWVBFX1FVQUxJRklFRF9FTlVN", + "EA8SIQodTVhfREFUQV9UWVBFX1FVQUxJRklFRF9TVFJVQ1QQEBIpCiVNWF9E", + "QVRBX1RZUEVfSU5URVJOQVRJT05BTElaRURfU1RSSU5HEBESGwoXTVhfREFU", + "QV9UWVBFX0JJR19TVFJJTkcQEhIUChBNWF9EQVRBX1RZUEVfRU5EEBMqowMK", + "ElByb3RvY29sU3RhdHVzQ29kZRIkCiBQUk9UT0NPTF9TVEFUVVNfQ09ERV9V", + "TlNQRUNJRklFRBAAEhsKF1BST1RPQ09MX1NUQVRVU19DT0RFX09LEAESKAok", + "UFJPVE9DT0xfU1RBVFVTX0NPREVfSU5WQUxJRF9SRVFVRVNUEAISKgomUFJP", + "VE9DT0xfU1RBVFVTX0NPREVfU0VTU0lPTl9OT1RfRk9VTkQQAxIqCiZQUk9U", + "T0NPTF9TVEFUVVNfQ09ERV9TRVNTSU9OX05PVF9SRUFEWRAEEisKJ1BST1RP", + "Q09MX1NUQVRVU19DT0RFX1dPUktFUl9VTkFWQUlMQUJMRRAFEiAKHFBST1RP", + "Q09MX1NUQVRVU19DT0RFX1RJTUVPVVQQBhIhCh1QUk9UT0NPTF9TVEFUVVNf", + "Q09ERV9DQU5DRUxFRBAHEisKJ1BST1RPQ09MX1NUQVRVU19DT0RFX1BST1RP", + "Q09MX1ZJT0xBVElPThAIEikKJVBST1RPQ09MX1NUQVRVU19DT0RFX01YQUND", + "RVNTX0ZBSUxVUkUQCSq/AgoMU2Vzc2lvblN0YXRlEh0KGVNFU1NJT05fU1RB", + "VEVfVU5TUEVDSUZJRUQQABIaChZTRVNTSU9OX1NUQVRFX0NSRUFUSU5HEAES", + "IQodU0VTU0lPTl9TVEFURV9TVEFSVElOR19XT1JLRVIQAhIiCh5TRVNTSU9O", + "X1NUQVRFX1dBSVRJTkdfRk9SX1BJUEUQAxIdChlTRVNTSU9OX1NUQVRFX0hB", + "TkRTSEFLSU5HEAQSJQohU0VTU0lPTl9TVEFURV9JTklUSUFMSVpJTkdfV09S", + "S0VSEAUSFwoTU0VTU0lPTl9TVEFURV9SRUFEWRAGEhkKFVNFU1NJT05fU1RB", + "VEVfQ0xPU0lORxAHEhgKFFNFU1NJT05fU1RBVEVfQ0xPU0VEEAgSGQoVU0VT", + "U0lPTl9TVEFURV9GQVVMVEVEEAky4AQKD014QWNjZXNzR2F0ZXdheRJdCgtP", + "cGVuU2Vzc2lvbhInLm14YWNjZXNzX2dhdGV3YXkudjEuT3BlblNlc3Npb25S", + "ZXF1ZXN0GiUubXhhY2Nlc3NfZ2F0ZXdheS52MS5PcGVuU2Vzc2lvblJlcGx5", + "EmAKDENsb3NlU2Vzc2lvbhIoLm14YWNjZXNzX2dhdGV3YXkudjEuQ2xvc2VT", + "ZXNzaW9uUmVxdWVzdBomLm14YWNjZXNzX2dhdGV3YXkudjEuQ2xvc2VTZXNz", + "aW9uUmVwbHkSVAoGSW52b2tlEiUubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeENv", + "bW1hbmRSZXF1ZXN0GiMubXhhY2Nlc3NfZ2F0ZXdheS52MS5NeENvbW1hbmRS", + "ZXBseRJYCgxTdHJlYW1FdmVudHMSKC5teGFjY2Vzc19nYXRld2F5LnYxLlN0", + "cmVhbUV2ZW50c1JlcXVlc3QaHC5teGFjY2Vzc19nYXRld2F5LnYxLk14RXZl", + "bnQwARJsChBBY2tub3dsZWRnZUFsYXJtEiwubXhhY2Nlc3NfZ2F0ZXdheS52", + "MS5BY2tub3dsZWRnZUFsYXJtUmVxdWVzdBoqLm14YWNjZXNzX2dhdGV3YXku", + "djEuQWNrbm93bGVkZ2VBbGFybVJlcGx5Em4KEVF1ZXJ5QWN0aXZlQWxhcm1z", + "Ei0ubXhhY2Nlc3NfZ2F0ZXdheS52MS5RdWVyeUFjdGl2ZUFsYXJtc1JlcXVl", + "c3QaKC5teGFjY2Vzc19nYXRld2F5LnYxLkFjdGl2ZUFsYXJtU25hcHNob3Qw", + "AUIcqgIZTXhHYXRld2F5LkNvbnRyYWN0cy5Qcm90b2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::MxGateway.Contracts.Proto.MxCommandKind), typeof(global::MxGateway.Contracts.Proto.MxEventFamily), typeof(global::MxGateway.Contracts.Proto.AlarmTransitionKind), typeof(global::MxGateway.Contracts.Proto.AlarmConditionState), typeof(global::MxGateway.Contracts.Proto.MxStatusCategory), typeof(global::MxGateway.Contracts.Proto.MxStatusSource), typeof(global::MxGateway.Contracts.Proto.MxDataType), typeof(global::MxGateway.Contracts.Proto.ProtocolStatusCode), typeof(global::MxGateway.Contracts.Proto.SessionState), }, null, new pbr::GeneratedClrTypeInfo[] { @@ -398,7 +422,7 @@ namespace MxGateway.Contracts.Proto { new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.CloseSessionReply), global::MxGateway.Contracts.Proto.CloseSessionReply.Parser, new[]{ "SessionId", "FinalState", "ProtocolStatus" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.StreamEventsRequest), global::MxGateway.Contracts.Proto.StreamEventsRequest.Parser, new[]{ "SessionId", "AfterWorkerSequence" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.MxCommandRequest), global::MxGateway.Contracts.Proto.MxCommandRequest.Parser, new[]{ "SessionId", "ClientCorrelationId", "Command" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.MxCommand), global::MxGateway.Contracts.Proto.MxCommand.Parser, new[]{ "Kind", "Register", "Unregister", "AddItem", "AddItem2", "RemoveItem", "Advise", "UnAdvise", "AdviseSupervisory", "AddBufferedItem", "SetBufferedUpdateInterval", "Suspend", "Activate", "Write", "Write2", "WriteSecured", "WriteSecured2", "AuthenticateUser", "ArchestraUserToId", "AddItemBulk", "AdviseItemBulk", "RemoveItemBulk", "UnAdviseItemBulk", "SubscribeBulk", "UnsubscribeBulk", "Ping", "GetSessionState", "GetWorkerInfo", "DrainEvents", "ShutdownWorker" }, new[]{ "Payload" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.MxCommand), global::MxGateway.Contracts.Proto.MxCommand.Parser, new[]{ "Kind", "Register", "Unregister", "AddItem", "AddItem2", "RemoveItem", "Advise", "UnAdvise", "AdviseSupervisory", "AddBufferedItem", "SetBufferedUpdateInterval", "Suspend", "Activate", "Write", "Write2", "WriteSecured", "WriteSecured2", "AuthenticateUser", "ArchestraUserToId", "AddItemBulk", "AdviseItemBulk", "RemoveItemBulk", "UnAdviseItemBulk", "SubscribeBulk", "UnsubscribeBulk", "SubscribeAlarms", "UnsubscribeAlarms", "AcknowledgeAlarmCommand", "QueryActiveAlarmsCommand", "Ping", "GetSessionState", "GetWorkerInfo", "DrainEvents", "ShutdownWorker" }, new[]{ "Payload" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.RegisterCommand), global::MxGateway.Contracts.Proto.RegisterCommand.Parser, new[]{ "ClientName" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.UnregisterCommand), global::MxGateway.Contracts.Proto.UnregisterCommand.Parser, new[]{ "ServerHandle" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.AddItemCommand), global::MxGateway.Contracts.Proto.AddItemCommand.Parser, new[]{ "ServerHandle", "ItemDefinition" }, null, null, null, null), @@ -422,13 +446,17 @@ namespace MxGateway.Contracts.Proto { new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.RemoveItemBulkCommand), global::MxGateway.Contracts.Proto.RemoveItemBulkCommand.Parser, new[]{ "ServerHandle", "ItemHandles" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.UnAdviseItemBulkCommand), global::MxGateway.Contracts.Proto.UnAdviseItemBulkCommand.Parser, new[]{ "ServerHandle", "ItemHandles" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.SubscribeBulkCommand), global::MxGateway.Contracts.Proto.SubscribeBulkCommand.Parser, new[]{ "ServerHandle", "TagAddresses" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand), global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand.Parser, new[]{ "SubscriptionExpression" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand), global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand.Parser, null, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand), global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand.Parser, new[]{ "AlarmGuid", "Comment", "OperatorUser", "OperatorNode", "OperatorDomain", "OperatorFullName" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand), global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand.Parser, new[]{ "AlarmFilterPrefix" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.UnsubscribeBulkCommand), global::MxGateway.Contracts.Proto.UnsubscribeBulkCommand.Parser, new[]{ "ServerHandle", "ItemHandles" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.PingCommand), global::MxGateway.Contracts.Proto.PingCommand.Parser, new[]{ "Message" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.GetSessionStateCommand), global::MxGateway.Contracts.Proto.GetSessionStateCommand.Parser, null, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.GetWorkerInfoCommand), global::MxGateway.Contracts.Proto.GetWorkerInfoCommand.Parser, null, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.DrainEventsCommand), global::MxGateway.Contracts.Proto.DrainEventsCommand.Parser, new[]{ "MaxEvents" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.ShutdownWorkerCommand), global::MxGateway.Contracts.Proto.ShutdownWorkerCommand.Parser, new[]{ "GracePeriod" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.MxCommandReply), global::MxGateway.Contracts.Proto.MxCommandReply.Parser, new[]{ "SessionId", "CorrelationId", "Kind", "ProtocolStatus", "Hresult", "ReturnValue", "Statuses", "DiagnosticMessage", "Register", "AddItem", "AddItem2", "AddBufferedItem", "Suspend", "Activate", "AuthenticateUser", "ArchestraUserToId", "AddItemBulk", "AdviseItemBulk", "RemoveItemBulk", "UnAdviseItemBulk", "SubscribeBulk", "UnsubscribeBulk", "SessionState", "WorkerInfo", "DrainEvents" }, new[]{ "Payload", "Hresult" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.MxCommandReply), global::MxGateway.Contracts.Proto.MxCommandReply.Parser, new[]{ "SessionId", "CorrelationId", "Kind", "ProtocolStatus", "Hresult", "ReturnValue", "Statuses", "DiagnosticMessage", "Register", "AddItem", "AddItem2", "AddBufferedItem", "Suspend", "Activate", "AuthenticateUser", "ArchestraUserToId", "AddItemBulk", "AdviseItemBulk", "RemoveItemBulk", "UnAdviseItemBulk", "SubscribeBulk", "UnsubscribeBulk", "AcknowledgeAlarm", "QueryActiveAlarms", "SessionState", "WorkerInfo", "DrainEvents" }, new[]{ "Payload", "Hresult" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.RegisterReply), global::MxGateway.Contracts.Proto.RegisterReply.Parser, new[]{ "ServerHandle" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.AddItemReply), global::MxGateway.Contracts.Proto.AddItemReply.Parser, new[]{ "ItemHandle" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.AddItem2Reply), global::MxGateway.Contracts.Proto.AddItem2Reply.Parser, new[]{ "ItemHandle" }, null, null, null, null), @@ -442,6 +470,8 @@ namespace MxGateway.Contracts.Proto { new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.SessionStateReply), global::MxGateway.Contracts.Proto.SessionStateReply.Parser, new[]{ "State" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.WorkerInfoReply), global::MxGateway.Contracts.Proto.WorkerInfoReply.Parser, new[]{ "WorkerProcessId", "WorkerVersion", "MxaccessProgid", "MxaccessClsid" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.DrainEventsReply), global::MxGateway.Contracts.Proto.DrainEventsReply.Parser, new[]{ "Events" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload), global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload.Parser, new[]{ "NativeStatus" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload), global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload.Parser, new[]{ "Snapshots" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.MxEvent), global::MxGateway.Contracts.Proto.MxEvent.Parser, new[]{ "Family", "SessionId", "ServerHandle", "ItemHandle", "Value", "Quality", "SourceTimestamp", "Statuses", "WorkerSequence", "WorkerTimestamp", "GatewayReceiveTimestamp", "Hresult", "RawStatus", "OnDataChange", "OnWriteComplete", "OperationComplete", "OnBufferedDataChange", "OnAlarmTransition" }, new[]{ "Body", "Hresult" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.OnDataChangeEvent), global::MxGateway.Contracts.Proto.OnDataChangeEvent.Parser, null, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::MxGateway.Contracts.Proto.OnWriteCompleteEvent), global::MxGateway.Contracts.Proto.OnWriteCompleteEvent.Parser, null, null, null, null, null), @@ -496,6 +526,10 @@ namespace MxGateway.Contracts.Proto { [pbr::OriginalName("MX_COMMAND_KIND_UN_ADVISE_ITEM_BULK")] UnAdviseItemBulk = 22, [pbr::OriginalName("MX_COMMAND_KIND_SUBSCRIBE_BULK")] SubscribeBulk = 23, [pbr::OriginalName("MX_COMMAND_KIND_UNSUBSCRIBE_BULK")] UnsubscribeBulk = 24, + [pbr::OriginalName("MX_COMMAND_KIND_SUBSCRIBE_ALARMS")] SubscribeAlarms = 25, + [pbr::OriginalName("MX_COMMAND_KIND_UNSUBSCRIBE_ALARMS")] UnsubscribeAlarms = 26, + [pbr::OriginalName("MX_COMMAND_KIND_ACKNOWLEDGE_ALARM")] AcknowledgeAlarm = 27, + [pbr::OriginalName("MX_COMMAND_KIND_QUERY_ACTIVE_ALARMS")] QueryActiveAlarms = 28, [pbr::OriginalName("MX_COMMAND_KIND_PING")] Ping = 100, [pbr::OriginalName("MX_COMMAND_KIND_GET_SESSION_STATE")] GetSessionState = 101, [pbr::OriginalName("MX_COMMAND_KIND_GET_WORKER_INFO")] GetWorkerInfo = 102, @@ -2532,6 +2566,18 @@ namespace MxGateway.Contracts.Proto { case PayloadOneofCase.UnsubscribeBulk: UnsubscribeBulk = other.UnsubscribeBulk.Clone(); break; + case PayloadOneofCase.SubscribeAlarms: + SubscribeAlarms = other.SubscribeAlarms.Clone(); + break; + case PayloadOneofCase.UnsubscribeAlarms: + UnsubscribeAlarms = other.UnsubscribeAlarms.Clone(); + break; + case PayloadOneofCase.AcknowledgeAlarmCommand: + AcknowledgeAlarmCommand = other.AcknowledgeAlarmCommand.Clone(); + break; + case PayloadOneofCase.QueryActiveAlarmsCommand: + QueryActiveAlarmsCommand = other.QueryActiveAlarmsCommand.Clone(); + break; case PayloadOneofCase.Ping: Ping = other.Ping.Clone(); break; @@ -2858,6 +2904,54 @@ namespace MxGateway.Contracts.Proto { } } + /// Field number for the "subscribe_alarms" field. + public const int SubscribeAlarmsFieldNumber = 34; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand SubscribeAlarms { + get { return payloadCase_ == PayloadOneofCase.SubscribeAlarms ? (global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand) payload_ : null; } + set { + payload_ = value; + payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.SubscribeAlarms; + } + } + + /// Field number for the "unsubscribe_alarms" field. + public const int UnsubscribeAlarmsFieldNumber = 35; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand UnsubscribeAlarms { + get { return payloadCase_ == PayloadOneofCase.UnsubscribeAlarms ? (global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand) payload_ : null; } + set { + payload_ = value; + payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.UnsubscribeAlarms; + } + } + + /// Field number for the "acknowledge_alarm_command" field. + public const int AcknowledgeAlarmCommandFieldNumber = 36; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand AcknowledgeAlarmCommand { + get { return payloadCase_ == PayloadOneofCase.AcknowledgeAlarmCommand ? (global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand) payload_ : null; } + set { + payload_ = value; + payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.AcknowledgeAlarmCommand; + } + } + + /// Field number for the "query_active_alarms_command" field. + public const int QueryActiveAlarmsCommandFieldNumber = 37; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand QueryActiveAlarmsCommand { + get { return payloadCase_ == PayloadOneofCase.QueryActiveAlarmsCommand ? (global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand) payload_ : null; } + set { + payload_ = value; + payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.QueryActiveAlarmsCommand; + } + } + /// Field number for the "ping" field. public const int PingFieldNumber = 100; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2946,6 +3040,10 @@ namespace MxGateway.Contracts.Proto { UnAdviseItemBulk = 31, SubscribeBulk = 32, UnsubscribeBulk = 33, + SubscribeAlarms = 34, + UnsubscribeAlarms = 35, + AcknowledgeAlarmCommand = 36, + QueryActiveAlarmsCommand = 37, Ping = 100, GetSessionState = 101, GetWorkerInfo = 102, @@ -3006,6 +3104,10 @@ namespace MxGateway.Contracts.Proto { if (!object.Equals(UnAdviseItemBulk, other.UnAdviseItemBulk)) return false; if (!object.Equals(SubscribeBulk, other.SubscribeBulk)) return false; if (!object.Equals(UnsubscribeBulk, other.UnsubscribeBulk)) return false; + if (!object.Equals(SubscribeAlarms, other.SubscribeAlarms)) return false; + if (!object.Equals(UnsubscribeAlarms, other.UnsubscribeAlarms)) return false; + if (!object.Equals(AcknowledgeAlarmCommand, other.AcknowledgeAlarmCommand)) return false; + if (!object.Equals(QueryActiveAlarmsCommand, other.QueryActiveAlarmsCommand)) return false; if (!object.Equals(Ping, other.Ping)) return false; if (!object.Equals(GetSessionState, other.GetSessionState)) return false; if (!object.Equals(GetWorkerInfo, other.GetWorkerInfo)) return false; @@ -3044,6 +3146,10 @@ namespace MxGateway.Contracts.Proto { if (payloadCase_ == PayloadOneofCase.UnAdviseItemBulk) hash ^= UnAdviseItemBulk.GetHashCode(); if (payloadCase_ == PayloadOneofCase.SubscribeBulk) hash ^= SubscribeBulk.GetHashCode(); if (payloadCase_ == PayloadOneofCase.UnsubscribeBulk) hash ^= UnsubscribeBulk.GetHashCode(); + if (payloadCase_ == PayloadOneofCase.SubscribeAlarms) hash ^= SubscribeAlarms.GetHashCode(); + if (payloadCase_ == PayloadOneofCase.UnsubscribeAlarms) hash ^= UnsubscribeAlarms.GetHashCode(); + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarmCommand) hash ^= AcknowledgeAlarmCommand.GetHashCode(); + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarmsCommand) hash ^= QueryActiveAlarmsCommand.GetHashCode(); if (payloadCase_ == PayloadOneofCase.Ping) hash ^= Ping.GetHashCode(); if (payloadCase_ == PayloadOneofCase.GetSessionState) hash ^= GetSessionState.GetHashCode(); if (payloadCase_ == PayloadOneofCase.GetWorkerInfo) hash ^= GetWorkerInfo.GetHashCode(); @@ -3168,6 +3274,22 @@ namespace MxGateway.Contracts.Proto { output.WriteRawTag(138, 2); output.WriteMessage(UnsubscribeBulk); } + if (payloadCase_ == PayloadOneofCase.SubscribeAlarms) { + output.WriteRawTag(146, 2); + output.WriteMessage(SubscribeAlarms); + } + if (payloadCase_ == PayloadOneofCase.UnsubscribeAlarms) { + output.WriteRawTag(154, 2); + output.WriteMessage(UnsubscribeAlarms); + } + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarmCommand) { + output.WriteRawTag(162, 2); + output.WriteMessage(AcknowledgeAlarmCommand); + } + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarmsCommand) { + output.WriteRawTag(170, 2); + output.WriteMessage(QueryActiveAlarmsCommand); + } if (payloadCase_ == PayloadOneofCase.Ping) { output.WriteRawTag(162, 6); output.WriteMessage(Ping); @@ -3298,6 +3420,22 @@ namespace MxGateway.Contracts.Proto { output.WriteRawTag(138, 2); output.WriteMessage(UnsubscribeBulk); } + if (payloadCase_ == PayloadOneofCase.SubscribeAlarms) { + output.WriteRawTag(146, 2); + output.WriteMessage(SubscribeAlarms); + } + if (payloadCase_ == PayloadOneofCase.UnsubscribeAlarms) { + output.WriteRawTag(154, 2); + output.WriteMessage(UnsubscribeAlarms); + } + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarmCommand) { + output.WriteRawTag(162, 2); + output.WriteMessage(AcknowledgeAlarmCommand); + } + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarmsCommand) { + output.WriteRawTag(170, 2); + output.WriteMessage(QueryActiveAlarmsCommand); + } if (payloadCase_ == PayloadOneofCase.Ping) { output.WriteRawTag(162, 6); output.WriteMessage(Ping); @@ -3403,6 +3541,18 @@ namespace MxGateway.Contracts.Proto { if (payloadCase_ == PayloadOneofCase.UnsubscribeBulk) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(UnsubscribeBulk); } + if (payloadCase_ == PayloadOneofCase.SubscribeAlarms) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(SubscribeAlarms); + } + if (payloadCase_ == PayloadOneofCase.UnsubscribeAlarms) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(UnsubscribeAlarms); + } + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarmCommand) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(AcknowledgeAlarmCommand); + } + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarmsCommand) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(QueryActiveAlarmsCommand); + } if (payloadCase_ == PayloadOneofCase.Ping) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(Ping); } @@ -3578,6 +3728,30 @@ namespace MxGateway.Contracts.Proto { } UnsubscribeBulk.MergeFrom(other.UnsubscribeBulk); break; + case PayloadOneofCase.SubscribeAlarms: + if (SubscribeAlarms == null) { + SubscribeAlarms = new global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand(); + } + SubscribeAlarms.MergeFrom(other.SubscribeAlarms); + break; + case PayloadOneofCase.UnsubscribeAlarms: + if (UnsubscribeAlarms == null) { + UnsubscribeAlarms = new global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand(); + } + UnsubscribeAlarms.MergeFrom(other.UnsubscribeAlarms); + break; + case PayloadOneofCase.AcknowledgeAlarmCommand: + if (AcknowledgeAlarmCommand == null) { + AcknowledgeAlarmCommand = new global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand(); + } + AcknowledgeAlarmCommand.MergeFrom(other.AcknowledgeAlarmCommand); + break; + case PayloadOneofCase.QueryActiveAlarmsCommand: + if (QueryActiveAlarmsCommand == null) { + QueryActiveAlarmsCommand = new global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand(); + } + QueryActiveAlarmsCommand.MergeFrom(other.QueryActiveAlarmsCommand); + break; case PayloadOneofCase.Ping: if (Ping == null) { Ping = new global::MxGateway.Contracts.Proto.PingCommand(); @@ -3849,6 +4023,42 @@ namespace MxGateway.Contracts.Proto { UnsubscribeBulk = subBuilder; break; } + case 274: { + global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand subBuilder = new global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand(); + if (payloadCase_ == PayloadOneofCase.SubscribeAlarms) { + subBuilder.MergeFrom(SubscribeAlarms); + } + input.ReadMessage(subBuilder); + SubscribeAlarms = subBuilder; + break; + } + case 282: { + global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand subBuilder = new global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand(); + if (payloadCase_ == PayloadOneofCase.UnsubscribeAlarms) { + subBuilder.MergeFrom(UnsubscribeAlarms); + } + input.ReadMessage(subBuilder); + UnsubscribeAlarms = subBuilder; + break; + } + case 290: { + global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand subBuilder = new global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand(); + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarmCommand) { + subBuilder.MergeFrom(AcknowledgeAlarmCommand); + } + input.ReadMessage(subBuilder); + AcknowledgeAlarmCommand = subBuilder; + break; + } + case 298: { + global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand subBuilder = new global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand(); + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarmsCommand) { + subBuilder.MergeFrom(QueryActiveAlarmsCommand); + } + input.ReadMessage(subBuilder); + QueryActiveAlarmsCommand = subBuilder; + break; + } case 802: { global::MxGateway.Contracts.Proto.PingCommand subBuilder = new global::MxGateway.Contracts.Proto.PingCommand(); if (payloadCase_ == PayloadOneofCase.Ping) { @@ -4133,6 +4343,42 @@ namespace MxGateway.Contracts.Proto { UnsubscribeBulk = subBuilder; break; } + case 274: { + global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand subBuilder = new global::MxGateway.Contracts.Proto.SubscribeAlarmsCommand(); + if (payloadCase_ == PayloadOneofCase.SubscribeAlarms) { + subBuilder.MergeFrom(SubscribeAlarms); + } + input.ReadMessage(subBuilder); + SubscribeAlarms = subBuilder; + break; + } + case 282: { + global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand subBuilder = new global::MxGateway.Contracts.Proto.UnsubscribeAlarmsCommand(); + if (payloadCase_ == PayloadOneofCase.UnsubscribeAlarms) { + subBuilder.MergeFrom(UnsubscribeAlarms); + } + input.ReadMessage(subBuilder); + UnsubscribeAlarms = subBuilder; + break; + } + case 290: { + global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand subBuilder = new global::MxGateway.Contracts.Proto.AcknowledgeAlarmCommand(); + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarmCommand) { + subBuilder.MergeFrom(AcknowledgeAlarmCommand); + } + input.ReadMessage(subBuilder); + AcknowledgeAlarmCommand = subBuilder; + break; + } + case 298: { + global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand subBuilder = new global::MxGateway.Contracts.Proto.QueryActiveAlarmsCommand(); + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarmsCommand) { + subBuilder.MergeFrom(QueryActiveAlarmsCommand); + } + input.ReadMessage(subBuilder); + QueryActiveAlarmsCommand = subBuilder; + break; + } case 802: { global::MxGateway.Contracts.Proto.PingCommand subBuilder = new global::MxGateway.Contracts.Proto.PingCommand(); if (payloadCase_ == PayloadOneofCase.Ping) { @@ -10088,6 +10334,972 @@ namespace MxGateway.Contracts.Proto { } + /// + /// Subscribe the worker's alarm consumer to an AVEVA alarm provider. + /// Subscription expression follows the canonical + /// `\\<machine>\Galaxy!<area>` format (literal "Galaxy" provider). The + /// worker spins up a wnwrapConsumer-backed subscription on its STA on + /// first call; subsequent calls are an error (use UnsubscribeAlarms then + /// SubscribeAlarms to reconfigure). + /// + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class SubscribeAlarmsCommand : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SubscribeAlarmsCommand()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[30]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public SubscribeAlarmsCommand() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public SubscribeAlarmsCommand(SubscribeAlarmsCommand other) : this() { + subscriptionExpression_ = other.subscriptionExpression_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public SubscribeAlarmsCommand Clone() { + return new SubscribeAlarmsCommand(this); + } + + /// Field number for the "subscription_expression" field. + public const int SubscriptionExpressionFieldNumber = 1; + private string subscriptionExpression_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string SubscriptionExpression { + get { return subscriptionExpression_; } + set { + subscriptionExpression_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as SubscribeAlarmsCommand); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(SubscribeAlarmsCommand other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (SubscriptionExpression != other.SubscriptionExpression) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (SubscriptionExpression.Length != 0) hash ^= SubscriptionExpression.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (SubscriptionExpression.Length != 0) { + output.WriteRawTag(10); + output.WriteString(SubscriptionExpression); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (SubscriptionExpression.Length != 0) { + output.WriteRawTag(10); + output.WriteString(SubscriptionExpression); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (SubscriptionExpression.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(SubscriptionExpression); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(SubscribeAlarmsCommand other) { + if (other == null) { + return; + } + if (other.SubscriptionExpression.Length != 0) { + SubscriptionExpression = other.SubscriptionExpression; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + SubscriptionExpression = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + SubscriptionExpression = input.ReadString(); + break; + } + } + } + } + #endif + + } + + /// + /// Tear down the worker's alarm consumer. No-op if no subscription is + /// currently active. + /// + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class UnsubscribeAlarmsCommand : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new UnsubscribeAlarmsCommand()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[31]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public UnsubscribeAlarmsCommand() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public UnsubscribeAlarmsCommand(UnsubscribeAlarmsCommand other) : this() { + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public UnsubscribeAlarmsCommand Clone() { + return new UnsubscribeAlarmsCommand(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as UnsubscribeAlarmsCommand); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(UnsubscribeAlarmsCommand other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(UnsubscribeAlarmsCommand other) { + if (other == null) { + return; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } + } + #endif + + } + + /// + /// Acknowledge a single alarm by its GUID. Operator identity fields are + /// recorded atomically with the ack transition in the alarm-history log. + /// The reply's hresult / native_status surfaces AVEVA's + /// AlarmAckByGUID return code. + /// + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class AcknowledgeAlarmCommand : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new AcknowledgeAlarmCommand()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[32]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public AcknowledgeAlarmCommand() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public AcknowledgeAlarmCommand(AcknowledgeAlarmCommand other) : this() { + alarmGuid_ = other.alarmGuid_; + comment_ = other.comment_; + operatorUser_ = other.operatorUser_; + operatorNode_ = other.operatorNode_; + operatorDomain_ = other.operatorDomain_; + operatorFullName_ = other.operatorFullName_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public AcknowledgeAlarmCommand Clone() { + return new AcknowledgeAlarmCommand(this); + } + + /// Field number for the "alarm_guid" field. + public const int AlarmGuidFieldNumber = 1; + private string alarmGuid_ = ""; + /// + /// Canonical 8-4-4-4-12 GUID string (e.g. "BCC47053-9542-4D65-BDAA-BCDEA6A32A73"). + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string AlarmGuid { + get { return alarmGuid_; } + set { + alarmGuid_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "comment" field. + public const int CommentFieldNumber = 2; + private string comment_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Comment { + get { return comment_; } + set { + comment_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "operator_user" field. + public const int OperatorUserFieldNumber = 3; + private string operatorUser_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string OperatorUser { + get { return operatorUser_; } + set { + operatorUser_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "operator_node" field. + public const int OperatorNodeFieldNumber = 4; + private string operatorNode_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string OperatorNode { + get { return operatorNode_; } + set { + operatorNode_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "operator_domain" field. + public const int OperatorDomainFieldNumber = 5; + private string operatorDomain_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string OperatorDomain { + get { return operatorDomain_; } + set { + operatorDomain_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "operator_full_name" field. + public const int OperatorFullNameFieldNumber = 6; + private string operatorFullName_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string OperatorFullName { + get { return operatorFullName_; } + set { + operatorFullName_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as AcknowledgeAlarmCommand); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(AcknowledgeAlarmCommand other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (AlarmGuid != other.AlarmGuid) return false; + if (Comment != other.Comment) return false; + if (OperatorUser != other.OperatorUser) return false; + if (OperatorNode != other.OperatorNode) return false; + if (OperatorDomain != other.OperatorDomain) return false; + if (OperatorFullName != other.OperatorFullName) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (AlarmGuid.Length != 0) hash ^= AlarmGuid.GetHashCode(); + if (Comment.Length != 0) hash ^= Comment.GetHashCode(); + if (OperatorUser.Length != 0) hash ^= OperatorUser.GetHashCode(); + if (OperatorNode.Length != 0) hash ^= OperatorNode.GetHashCode(); + if (OperatorDomain.Length != 0) hash ^= OperatorDomain.GetHashCode(); + if (OperatorFullName.Length != 0) hash ^= OperatorFullName.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (AlarmGuid.Length != 0) { + output.WriteRawTag(10); + output.WriteString(AlarmGuid); + } + if (Comment.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Comment); + } + if (OperatorUser.Length != 0) { + output.WriteRawTag(26); + output.WriteString(OperatorUser); + } + if (OperatorNode.Length != 0) { + output.WriteRawTag(34); + output.WriteString(OperatorNode); + } + if (OperatorDomain.Length != 0) { + output.WriteRawTag(42); + output.WriteString(OperatorDomain); + } + if (OperatorFullName.Length != 0) { + output.WriteRawTag(50); + output.WriteString(OperatorFullName); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (AlarmGuid.Length != 0) { + output.WriteRawTag(10); + output.WriteString(AlarmGuid); + } + if (Comment.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Comment); + } + if (OperatorUser.Length != 0) { + output.WriteRawTag(26); + output.WriteString(OperatorUser); + } + if (OperatorNode.Length != 0) { + output.WriteRawTag(34); + output.WriteString(OperatorNode); + } + if (OperatorDomain.Length != 0) { + output.WriteRawTag(42); + output.WriteString(OperatorDomain); + } + if (OperatorFullName.Length != 0) { + output.WriteRawTag(50); + output.WriteString(OperatorFullName); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (AlarmGuid.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(AlarmGuid); + } + if (Comment.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Comment); + } + if (OperatorUser.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OperatorUser); + } + if (OperatorNode.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OperatorNode); + } + if (OperatorDomain.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OperatorDomain); + } + if (OperatorFullName.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OperatorFullName); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(AcknowledgeAlarmCommand other) { + if (other == null) { + return; + } + if (other.AlarmGuid.Length != 0) { + AlarmGuid = other.AlarmGuid; + } + if (other.Comment.Length != 0) { + Comment = other.Comment; + } + if (other.OperatorUser.Length != 0) { + OperatorUser = other.OperatorUser; + } + if (other.OperatorNode.Length != 0) { + OperatorNode = other.OperatorNode; + } + if (other.OperatorDomain.Length != 0) { + OperatorDomain = other.OperatorDomain; + } + if (other.OperatorFullName.Length != 0) { + OperatorFullName = other.OperatorFullName; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + AlarmGuid = input.ReadString(); + break; + } + case 18: { + Comment = input.ReadString(); + break; + } + case 26: { + OperatorUser = input.ReadString(); + break; + } + case 34: { + OperatorNode = input.ReadString(); + break; + } + case 42: { + OperatorDomain = input.ReadString(); + break; + } + case 50: { + OperatorFullName = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + AlarmGuid = input.ReadString(); + break; + } + case 18: { + Comment = input.ReadString(); + break; + } + case 26: { + OperatorUser = input.ReadString(); + break; + } + case 34: { + OperatorNode = input.ReadString(); + break; + } + case 42: { + OperatorDomain = input.ReadString(); + break; + } + case 50: { + OperatorFullName = input.ReadString(); + break; + } + } + } + } + #endif + + } + + /// + /// Snapshot the currently-active alarm set. Optional filter prefix scopes + /// the snapshot to alarms whose alarm_full_reference starts with the + /// supplied string (matches QueryActiveAlarmsRequest.alarm_filter_prefix). + /// + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class QueryActiveAlarmsCommand : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new QueryActiveAlarmsCommand()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[33]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public QueryActiveAlarmsCommand() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public QueryActiveAlarmsCommand(QueryActiveAlarmsCommand other) : this() { + alarmFilterPrefix_ = other.alarmFilterPrefix_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public QueryActiveAlarmsCommand Clone() { + return new QueryActiveAlarmsCommand(this); + } + + /// Field number for the "alarm_filter_prefix" field. + public const int AlarmFilterPrefixFieldNumber = 1; + private string alarmFilterPrefix_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string AlarmFilterPrefix { + get { return alarmFilterPrefix_; } + set { + alarmFilterPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as QueryActiveAlarmsCommand); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(QueryActiveAlarmsCommand other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (AlarmFilterPrefix != other.AlarmFilterPrefix) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (AlarmFilterPrefix.Length != 0) hash ^= AlarmFilterPrefix.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (AlarmFilterPrefix.Length != 0) { + output.WriteRawTag(10); + output.WriteString(AlarmFilterPrefix); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (AlarmFilterPrefix.Length != 0) { + output.WriteRawTag(10); + output.WriteString(AlarmFilterPrefix); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (AlarmFilterPrefix.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(AlarmFilterPrefix); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(QueryActiveAlarmsCommand other) { + if (other == null) { + return; + } + if (other.AlarmFilterPrefix.Length != 0) { + AlarmFilterPrefix = other.AlarmFilterPrefix; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + AlarmFilterPrefix = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + AlarmFilterPrefix = input.ReadString(); + break; + } + } + } + } + #endif + + } + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] public sealed partial class UnsubscribeBulkCommand : pb::IMessage #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE @@ -10103,7 +11315,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[30]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[34]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -10329,7 +11541,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[31]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[35]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -10527,7 +11739,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[32]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[36]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -10688,7 +11900,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[33]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[37]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -10849,7 +12061,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[34]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[38]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -11047,7 +12259,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[35]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[39]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -11255,7 +12467,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[36]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[40]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -11327,6 +12539,12 @@ namespace MxGateway.Contracts.Proto { case PayloadOneofCase.UnsubscribeBulk: UnsubscribeBulk = other.UnsubscribeBulk.Clone(); break; + case PayloadOneofCase.AcknowledgeAlarm: + AcknowledgeAlarm = other.AcknowledgeAlarm.Clone(); + break; + case PayloadOneofCase.QueryActiveAlarms: + QueryActiveAlarms = other.QueryActiveAlarms.Clone(); + break; case PayloadOneofCase.SessionState: SessionState = other.SessionState.Clone(); break; @@ -11630,6 +12848,30 @@ namespace MxGateway.Contracts.Proto { } } + /// Field number for the "acknowledge_alarm" field. + public const int AcknowledgeAlarmFieldNumber = 34; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload AcknowledgeAlarm { + get { return payloadCase_ == PayloadOneofCase.AcknowledgeAlarm ? (global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload) payload_ : null; } + set { + payload_ = value; + payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.AcknowledgeAlarm; + } + } + + /// Field number for the "query_active_alarms" field. + public const int QueryActiveAlarmsFieldNumber = 35; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload QueryActiveAlarms { + get { return payloadCase_ == PayloadOneofCase.QueryActiveAlarms ? (global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload) payload_ : null; } + set { + payload_ = value; + payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.QueryActiveAlarms; + } + } + /// Field number for the "session_state" field. public const int SessionStateFieldNumber = 100; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -11684,6 +12926,8 @@ namespace MxGateway.Contracts.Proto { UnAdviseItemBulk = 31, SubscribeBulk = 32, UnsubscribeBulk = 33, + AcknowledgeAlarm = 34, + QueryActiveAlarms = 35, SessionState = 100, WorkerInfo = 101, DrainEvents = 102, @@ -11739,6 +12983,8 @@ namespace MxGateway.Contracts.Proto { if (!object.Equals(UnAdviseItemBulk, other.UnAdviseItemBulk)) return false; if (!object.Equals(SubscribeBulk, other.SubscribeBulk)) return false; if (!object.Equals(UnsubscribeBulk, other.UnsubscribeBulk)) return false; + if (!object.Equals(AcknowledgeAlarm, other.AcknowledgeAlarm)) return false; + if (!object.Equals(QueryActiveAlarms, other.QueryActiveAlarms)) return false; if (!object.Equals(SessionState, other.SessionState)) return false; if (!object.Equals(WorkerInfo, other.WorkerInfo)) return false; if (!object.Equals(DrainEvents, other.DrainEvents)) return false; @@ -11772,6 +13018,8 @@ namespace MxGateway.Contracts.Proto { if (payloadCase_ == PayloadOneofCase.UnAdviseItemBulk) hash ^= UnAdviseItemBulk.GetHashCode(); if (payloadCase_ == PayloadOneofCase.SubscribeBulk) hash ^= SubscribeBulk.GetHashCode(); if (payloadCase_ == PayloadOneofCase.UnsubscribeBulk) hash ^= UnsubscribeBulk.GetHashCode(); + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarm) hash ^= AcknowledgeAlarm.GetHashCode(); + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarms) hash ^= QueryActiveAlarms.GetHashCode(); if (payloadCase_ == PayloadOneofCase.SessionState) hash ^= SessionState.GetHashCode(); if (payloadCase_ == PayloadOneofCase.WorkerInfo) hash ^= WorkerInfo.GetHashCode(); if (payloadCase_ == PayloadOneofCase.DrainEvents) hash ^= DrainEvents.GetHashCode(); @@ -11879,6 +13127,14 @@ namespace MxGateway.Contracts.Proto { output.WriteRawTag(138, 2); output.WriteMessage(UnsubscribeBulk); } + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarm) { + output.WriteRawTag(146, 2); + output.WriteMessage(AcknowledgeAlarm); + } + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarms) { + output.WriteRawTag(154, 2); + output.WriteMessage(QueryActiveAlarms); + } if (payloadCase_ == PayloadOneofCase.SessionState) { output.WriteRawTag(162, 6); output.WriteMessage(SessionState); @@ -11986,6 +13242,14 @@ namespace MxGateway.Contracts.Proto { output.WriteRawTag(138, 2); output.WriteMessage(UnsubscribeBulk); } + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarm) { + output.WriteRawTag(146, 2); + output.WriteMessage(AcknowledgeAlarm); + } + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarms) { + output.WriteRawTag(154, 2); + output.WriteMessage(QueryActiveAlarms); + } if (payloadCase_ == PayloadOneofCase.SessionState) { output.WriteRawTag(162, 6); output.WriteMessage(SessionState); @@ -12072,6 +13336,12 @@ namespace MxGateway.Contracts.Proto { if (payloadCase_ == PayloadOneofCase.UnsubscribeBulk) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(UnsubscribeBulk); } + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarm) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(AcknowledgeAlarm); + } + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarms) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(QueryActiveAlarms); + } if (payloadCase_ == PayloadOneofCase.SessionState) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(SessionState); } @@ -12206,6 +13476,18 @@ namespace MxGateway.Contracts.Proto { } UnsubscribeBulk.MergeFrom(other.UnsubscribeBulk); break; + case PayloadOneofCase.AcknowledgeAlarm: + if (AcknowledgeAlarm == null) { + AcknowledgeAlarm = new global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload(); + } + AcknowledgeAlarm.MergeFrom(other.AcknowledgeAlarm); + break; + case PayloadOneofCase.QueryActiveAlarms: + if (QueryActiveAlarms == null) { + QueryActiveAlarms = new global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload(); + } + QueryActiveAlarms.MergeFrom(other.QueryActiveAlarms); + break; case PayloadOneofCase.SessionState: if (SessionState == null) { SessionState = new global::MxGateway.Contracts.Proto.SessionStateReply(); @@ -12409,6 +13691,24 @@ namespace MxGateway.Contracts.Proto { UnsubscribeBulk = subBuilder; break; } + case 274: { + global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload subBuilder = new global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload(); + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarm) { + subBuilder.MergeFrom(AcknowledgeAlarm); + } + input.ReadMessage(subBuilder); + AcknowledgeAlarm = subBuilder; + break; + } + case 282: { + global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload subBuilder = new global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload(); + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarms) { + subBuilder.MergeFrom(QueryActiveAlarms); + } + input.ReadMessage(subBuilder); + QueryActiveAlarms = subBuilder; + break; + } case 802: { global::MxGateway.Contracts.Proto.SessionStateReply subBuilder = new global::MxGateway.Contracts.Proto.SessionStateReply(); if (payloadCase_ == PayloadOneofCase.SessionState) { @@ -12619,6 +13919,24 @@ namespace MxGateway.Contracts.Proto { UnsubscribeBulk = subBuilder; break; } + case 274: { + global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload subBuilder = new global::MxGateway.Contracts.Proto.AcknowledgeAlarmReplyPayload(); + if (payloadCase_ == PayloadOneofCase.AcknowledgeAlarm) { + subBuilder.MergeFrom(AcknowledgeAlarm); + } + input.ReadMessage(subBuilder); + AcknowledgeAlarm = subBuilder; + break; + } + case 282: { + global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload subBuilder = new global::MxGateway.Contracts.Proto.QueryActiveAlarmsReplyPayload(); + if (payloadCase_ == PayloadOneofCase.QueryActiveAlarms) { + subBuilder.MergeFrom(QueryActiveAlarms); + } + input.ReadMessage(subBuilder); + QueryActiveAlarms = subBuilder; + break; + } case 802: { global::MxGateway.Contracts.Proto.SessionStateReply subBuilder = new global::MxGateway.Contracts.Proto.SessionStateReply(); if (payloadCase_ == PayloadOneofCase.SessionState) { @@ -12668,7 +13986,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[37]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[41]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -12866,7 +14184,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[38]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[42]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -13064,7 +14382,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[39]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[43]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -13262,7 +14580,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[40]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[44]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -13460,7 +14778,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[41]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[45]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -13667,7 +14985,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[42]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[46]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -13874,7 +15192,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[43]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[47]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14072,7 +15390,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[44]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[48]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14270,7 +15588,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[45]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[49]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14616,7 +15934,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[46]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[50]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14803,7 +16121,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[47]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[51]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -15001,7 +16319,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[48]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[52]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -15310,7 +16628,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[49]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[53]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -15482,6 +16800,405 @@ namespace MxGateway.Contracts.Proto { } + /// + /// Reply payload for AcknowledgeAlarmCommand. Surfaces AVEVA's native + /// AlarmAckByGUID return code; 0 means success. The MxCommandReply's + /// hresult field carries the same value and is preferred for protocol + /// consumers — this payload exists so the gateway-side + /// WorkerAlarmRpcDispatcher can echo native_status into + /// AcknowledgeAlarmReply.hresult without unpacking the outer envelope. + /// + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class AcknowledgeAlarmReplyPayload : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new AcknowledgeAlarmReplyPayload()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[54]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public AcknowledgeAlarmReplyPayload() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public AcknowledgeAlarmReplyPayload(AcknowledgeAlarmReplyPayload other) : this() { + nativeStatus_ = other.nativeStatus_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public AcknowledgeAlarmReplyPayload Clone() { + return new AcknowledgeAlarmReplyPayload(this); + } + + /// Field number for the "native_status" field. + public const int NativeStatusFieldNumber = 1; + private int nativeStatus_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int NativeStatus { + get { return nativeStatus_; } + set { + nativeStatus_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as AcknowledgeAlarmReplyPayload); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(AcknowledgeAlarmReplyPayload other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (NativeStatus != other.NativeStatus) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (NativeStatus != 0) hash ^= NativeStatus.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (NativeStatus != 0) { + output.WriteRawTag(8); + output.WriteInt32(NativeStatus); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (NativeStatus != 0) { + output.WriteRawTag(8); + output.WriteInt32(NativeStatus); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (NativeStatus != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(NativeStatus); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(AcknowledgeAlarmReplyPayload other) { + if (other == null) { + return; + } + if (other.NativeStatus != 0) { + NativeStatus = other.NativeStatus; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + NativeStatus = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + NativeStatus = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// Reply payload for QueryActiveAlarmsCommand. The worker walks + /// IMxAccessAlarmConsumer.SnapshotActiveAlarms and packs each record as + /// an ActiveAlarmSnapshot proto for the gateway-side ConditionRefresh + /// stream. + /// + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class QueryActiveAlarmsReplyPayload : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new QueryActiveAlarmsReplyPayload()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[55]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public QueryActiveAlarmsReplyPayload() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public QueryActiveAlarmsReplyPayload(QueryActiveAlarmsReplyPayload other) : this() { + snapshots_ = other.snapshots_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public QueryActiveAlarmsReplyPayload Clone() { + return new QueryActiveAlarmsReplyPayload(this); + } + + /// Field number for the "snapshots" field. + public const int SnapshotsFieldNumber = 1; + private static readonly pb::FieldCodec _repeated_snapshots_codec + = pb::FieldCodec.ForMessage(10, global::MxGateway.Contracts.Proto.ActiveAlarmSnapshot.Parser); + private readonly pbc::RepeatedField snapshots_ = new pbc::RepeatedField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField Snapshots { + get { return snapshots_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as QueryActiveAlarmsReplyPayload); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(QueryActiveAlarmsReplyPayload other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if(!snapshots_.Equals(other.snapshots_)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + hash ^= snapshots_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + snapshots_.WriteTo(output, _repeated_snapshots_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + snapshots_.WriteTo(ref output, _repeated_snapshots_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + size += snapshots_.CalculateSize(_repeated_snapshots_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(QueryActiveAlarmsReplyPayload other) { + if (other == null) { + return; + } + snapshots_.Add(other.snapshots_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + snapshots_.AddEntriesFrom(input, _repeated_snapshots_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + snapshots_.AddEntriesFrom(ref input, _repeated_snapshots_codec); + break; + } + } + } + } + #endif + + } + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] public sealed partial class MxEvent : pb::IMessage #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE @@ -15498,7 +17215,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[50]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[56]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -16473,7 +18190,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[51]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[57]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -16634,7 +18351,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[52]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[58]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -16795,7 +18512,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[53]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[59]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -16956,7 +18673,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[54]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[60]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -17289,7 +19006,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[55]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[61]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -18023,7 +19740,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[56]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[62]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -18713,7 +20430,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[57]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[63]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -19070,7 +20787,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[58]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[64]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -19493,7 +21210,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[59]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[65]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -19769,7 +21486,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[60]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[66]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -20189,7 +21906,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[61]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[67]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21046,7 +22763,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[62]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[68]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21834,7 +23551,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[63]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[69]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -22023,7 +23740,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[64]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[70]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -22212,7 +23929,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[65]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[71]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -22401,7 +24118,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[66]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[72]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -22590,7 +24307,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[67]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[73]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -22779,7 +24496,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[68]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[74]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -22966,7 +24683,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[69]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[75]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -23153,7 +24870,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[70]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[76]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -23340,7 +25057,7 @@ namespace MxGateway.Contracts.Proto { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public static pbr::MessageDescriptor Descriptor { - get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[71]; } + get { return global::MxGateway.Contracts.Proto.MxaccessGatewayReflection.Descriptor.MessageTypes[77]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] diff --git a/src/MxGateway.Contracts/Protos/mxaccess_gateway.proto b/src/MxGateway.Contracts/Protos/mxaccess_gateway.proto index b7ecf29..0bbf2ab 100644 --- a/src/MxGateway.Contracts/Protos/mxaccess_gateway.proto +++ b/src/MxGateway.Contracts/Protos/mxaccess_gateway.proto @@ -88,6 +88,10 @@ message MxCommand { UnAdviseItemBulkCommand un_advise_item_bulk = 31; SubscribeBulkCommand subscribe_bulk = 32; UnsubscribeBulkCommand unsubscribe_bulk = 33; + SubscribeAlarmsCommand subscribe_alarms = 34; + UnsubscribeAlarmsCommand unsubscribe_alarms = 35; + AcknowledgeAlarmCommand acknowledge_alarm_command = 36; + QueryActiveAlarmsCommand query_active_alarms_command = 37; PingCommand ping = 100; GetSessionStateCommand get_session_state = 101; GetWorkerInfoCommand get_worker_info = 102; @@ -122,6 +126,10 @@ enum MxCommandKind { MX_COMMAND_KIND_UN_ADVISE_ITEM_BULK = 22; MX_COMMAND_KIND_SUBSCRIBE_BULK = 23; MX_COMMAND_KIND_UNSUBSCRIBE_BULK = 24; + MX_COMMAND_KIND_SUBSCRIBE_ALARMS = 25; + MX_COMMAND_KIND_UNSUBSCRIBE_ALARMS = 26; + MX_COMMAND_KIND_ACKNOWLEDGE_ALARM = 27; + MX_COMMAND_KIND_QUERY_ACTIVE_ALARMS = 28; MX_COMMAND_KIND_PING = 100; MX_COMMAND_KIND_GET_SESSION_STATE = 101; MX_COMMAND_KIND_GET_WORKER_INFO = 102; @@ -263,6 +271,42 @@ message SubscribeBulkCommand { repeated string tag_addresses = 2; } +// Subscribe the worker's alarm consumer to an AVEVA alarm provider. +// Subscription expression follows the canonical +// `\\\Galaxy!` format (literal "Galaxy" provider). The +// worker spins up a wnwrapConsumer-backed subscription on its STA on +// first call; subsequent calls are an error (use UnsubscribeAlarms then +// SubscribeAlarms to reconfigure). +message SubscribeAlarmsCommand { + string subscription_expression = 1; +} + +// Tear down the worker's alarm consumer. No-op if no subscription is +// currently active. +message UnsubscribeAlarmsCommand { +} + +// Acknowledge a single alarm by its GUID. Operator identity fields are +// recorded atomically with the ack transition in the alarm-history log. +// The reply's hresult / native_status surfaces AVEVA's +// AlarmAckByGUID return code. +message AcknowledgeAlarmCommand { + // Canonical 8-4-4-4-12 GUID string (e.g. "BCC47053-9542-4D65-BDAA-BCDEA6A32A73"). + string alarm_guid = 1; + string comment = 2; + string operator_user = 3; + string operator_node = 4; + string operator_domain = 5; + string operator_full_name = 6; +} + +// Snapshot the currently-active alarm set. Optional filter prefix scopes +// the snapshot to alarms whose alarm_full_reference starts with the +// supplied string (matches QueryActiveAlarmsRequest.alarm_filter_prefix). +message QueryActiveAlarmsCommand { + string alarm_filter_prefix = 1; +} + message UnsubscribeBulkCommand { int32 server_handle = 1; repeated int32 item_handles = 2; @@ -314,6 +358,8 @@ message MxCommandReply { BulkSubscribeReply un_advise_item_bulk = 31; BulkSubscribeReply subscribe_bulk = 32; BulkSubscribeReply unsubscribe_bulk = 33; + AcknowledgeAlarmReplyPayload acknowledge_alarm = 34; + QueryActiveAlarmsReplyPayload query_active_alarms = 35; SessionStateReply session_state = 100; WorkerInfoReply worker_info = 101; DrainEventsReply drain_events = 102; @@ -379,6 +425,24 @@ message DrainEventsReply { repeated MxEvent events = 1; } +// Reply payload for AcknowledgeAlarmCommand. Surfaces AVEVA's native +// AlarmAckByGUID return code; 0 means success. The MxCommandReply's +// hresult field carries the same value and is preferred for protocol +// consumers — this payload exists so the gateway-side +// WorkerAlarmRpcDispatcher can echo native_status into +// AcknowledgeAlarmReply.hresult without unpacking the outer envelope. +message AcknowledgeAlarmReplyPayload { + int32 native_status = 1; +} + +// Reply payload for QueryActiveAlarmsCommand. The worker walks +// IMxAccessAlarmConsumer.SnapshotActiveAlarms and packs each record as +// an ActiveAlarmSnapshot proto for the gateway-side ConditionRefresh +// stream. +message QueryActiveAlarmsReplyPayload { + repeated ActiveAlarmSnapshot snapshots = 1; +} + message MxEvent { MxEventFamily family = 1; string session_id = 2; diff --git a/src/MxGateway.Worker.Tests/MxAccess/AlarmCommandExecutorTests.cs b/src/MxGateway.Worker.Tests/MxAccess/AlarmCommandExecutorTests.cs new file mode 100644 index 0000000..c04dd3e --- /dev/null +++ b/src/MxGateway.Worker.Tests/MxAccess/AlarmCommandExecutorTests.cs @@ -0,0 +1,384 @@ +using System; +using System.Collections.Generic; +using MxGateway.Contracts.Proto; +using MxGateway.Worker.MxAccess; +using MxGateway.Worker.Sta; + +namespace MxGateway.Worker.Tests.MxAccess; + +/// +/// Verifies that the four new alarm values +/// route through to a fake +/// and that the resulting +/// carries the expected payload. +/// +/// The data-side is constructed via a +/// no-op factory because the executor only touches it for non-alarm +/// command kinds — alarm dispatch never reaches the data session. +/// +public sealed class AlarmCommandExecutorTests +{ + private const string SessionId = "S"; + private const string CorrelationId = "C"; + + [Fact] + public void SubscribeAlarms_routes_to_handler_and_returns_ok() + { + FakeAlarmHandler handler = new FakeAlarmHandler(); + MxAccessCommandExecutor executor = NewExecutor(handler); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.SubscribeAlarms, + SubscribeAlarms = new SubscribeAlarmsCommand + { + SubscriptionExpression = @"\\HOST\Galaxy!Area", + }, + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.Ok, reply.ProtocolStatus.Code); + Assert.Equal(@"\\HOST\Galaxy!Area", handler.LastSubscription); + Assert.Equal(SessionId, handler.LastSessionId); + } + + [Fact] + public void SubscribeAlarms_without_handler_returns_invalid_request() + { + MxAccessCommandExecutor executor = NewExecutor(alarmHandler: null); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.SubscribeAlarms, + SubscribeAlarms = new SubscribeAlarmsCommand + { + SubscriptionExpression = @"\\HOST\Galaxy!Area", + }, + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.InvalidRequest, reply.ProtocolStatus.Code); + } + + [Fact] + public void SubscribeAlarms_with_empty_expression_returns_invalid_request() + { + MxAccessCommandExecutor executor = NewExecutor(new FakeAlarmHandler()); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.SubscribeAlarms, + SubscribeAlarms = new SubscribeAlarmsCommand + { + SubscriptionExpression = " ", + }, + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.InvalidRequest, reply.ProtocolStatus.Code); + } + + [Fact] + public void AcknowledgeAlarm_routes_native_status_into_hresult_and_payload() + { + FakeAlarmHandler handler = new FakeAlarmHandler { AcknowledgeReturn = 0 }; + MxAccessCommandExecutor executor = NewExecutor(handler); + Guid g = Guid.NewGuid(); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.AcknowledgeAlarm, + AcknowledgeAlarmCommand = new AcknowledgeAlarmCommand + { + AlarmGuid = g.ToString(), + Comment = "ack", + OperatorUser = "alice", + OperatorNode = "WS", + OperatorDomain = "CORP", + OperatorFullName = "Alice S", + }, + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.Ok, reply.ProtocolStatus.Code); + Assert.Equal(0, reply.Hresult); + Assert.NotNull(reply.AcknowledgeAlarm); + Assert.Equal(0, reply.AcknowledgeAlarm.NativeStatus); + Assert.Equal(g, handler.LastAckGuid); + Assert.Equal("alice", handler.LastAckOperatorName); + } + + [Fact] + public void AcknowledgeAlarm_with_invalid_guid_returns_invalid_request() + { + MxAccessCommandExecutor executor = NewExecutor(new FakeAlarmHandler()); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.AcknowledgeAlarm, + AcknowledgeAlarmCommand = new AcknowledgeAlarmCommand + { + AlarmGuid = "not-a-guid", + }, + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.InvalidRequest, reply.ProtocolStatus.Code); + } + + [Fact] + public void AcknowledgeAlarm_with_nonzero_native_status_carries_diagnostic() + { + FakeAlarmHandler handler = new FakeAlarmHandler { AcknowledgeReturn = -123 }; + MxAccessCommandExecutor executor = NewExecutor(handler); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.AcknowledgeAlarm, + AcknowledgeAlarmCommand = new AcknowledgeAlarmCommand + { + AlarmGuid = Guid.NewGuid().ToString(), + }, + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(-123, reply.Hresult); + Assert.Contains("-123", reply.DiagnosticMessage); + } + + [Fact] + public void QueryActiveAlarms_returns_payload_with_snapshots() + { + FakeAlarmHandler handler = new FakeAlarmHandler + { + QueryResult = new[] + { + new ActiveAlarmSnapshot { AlarmFullReference = "Galaxy!A.T1" }, + new ActiveAlarmSnapshot { AlarmFullReference = "Galaxy!A.T2" }, + }, + }; + MxAccessCommandExecutor executor = NewExecutor(handler); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.QueryActiveAlarms, + QueryActiveAlarmsCommand = new QueryActiveAlarmsCommand + { + AlarmFilterPrefix = "Galaxy!A", + }, + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.Ok, reply.ProtocolStatus.Code); + Assert.NotNull(reply.QueryActiveAlarms); + Assert.Equal(2, reply.QueryActiveAlarms.Snapshots.Count); + Assert.Equal("Galaxy!A", handler.LastFilterPrefix); + } + + [Fact] + public void UnsubscribeAlarms_routes_to_handler() + { + FakeAlarmHandler handler = new FakeAlarmHandler(); + MxAccessCommandExecutor executor = NewExecutor(handler); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.UnsubscribeAlarms, + UnsubscribeAlarms = new UnsubscribeAlarmsCommand(), + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.Ok, reply.ProtocolStatus.Code); + Assert.True(handler.UnsubscribeCalled); + } + + [Fact] + public void UnsubscribeAlarms_without_handler_is_ok_noop() + { + MxAccessCommandExecutor executor = NewExecutor(alarmHandler: null); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.UnsubscribeAlarms, + UnsubscribeAlarms = new UnsubscribeAlarmsCommand(), + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.Ok, reply.ProtocolStatus.Code); + } + + [Fact] + public void Acknowledge_handler_throw_returns_mxaccess_failure() + { + FakeAlarmHandler handler = new FakeAlarmHandler { AcknowledgeThrow = true }; + MxAccessCommandExecutor executor = NewExecutor(handler); + + StaCommand command = new StaCommand( + SessionId, CorrelationId, + new MxCommand + { + Kind = MxCommandKind.AcknowledgeAlarm, + AcknowledgeAlarmCommand = new AcknowledgeAlarmCommand + { + AlarmGuid = Guid.NewGuid().ToString(), + }, + }); + + MxCommandReply reply = executor.Execute(command); + + Assert.Equal(ProtocolStatusCode.MxaccessFailure, reply.ProtocolStatus.Code); + Assert.Contains("simulated", reply.DiagnosticMessage); + } + + private static MxAccessCommandExecutor NewExecutor(IAlarmCommandHandler? alarmHandler) + { + // Construct an executor with a no-op data session — we only exercise + // the alarm switch arms, which never touch the data session. + return new MxAccessCommandExecutor( + session: NoopMxAccessSession.Create(), + variantConverter: new MxGateway.Worker.Conversion.VariantConverter(), + alarmCommandHandler: alarmHandler); + } + + /// + /// Reflection-based helper to construct an MxAccessSession without + /// a real COM object. Only the alarm-side code paths are exercised + /// in this test class, so the session reference is never + /// dereferenced. + /// + private static class NoopMxAccessSession + { + public static MxAccessSession Create() + { + // Walk to the private constructor via reflection — the public + // factory MxAccessSession.Create(...) requires a real COM object. + System.Reflection.ConstructorInfo? ctor = typeof(MxAccessSession) + .GetConstructor( + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, + binder: null, + types: new[] + { + typeof(object), + typeof(IMxAccessServer), + typeof(IMxAccessEventSink), + typeof(MxAccessHandleRegistry), + typeof(int), + }, + modifiers: null); + if (ctor is null) + { + throw new InvalidOperationException( + "MxAccessSession private ctor signature changed; update the test seam."); + } + return (MxAccessSession)ctor.Invoke(new object[] + { + new object(), + new NullMxAccessServer(), + new NullEventSink(), + new MxAccessHandleRegistry(), + System.Environment.CurrentManagedThreadId, + }); + } + } + + private sealed class NullMxAccessServer : IMxAccessServer + { + public int Register(string clientName) => 0; + public void Unregister(int serverHandle) { } + public int AddItem(int serverHandle, string itemDefinition) => 0; + public int AddItem2(int serverHandle, string itemDefinition, string itemContext) => 0; + public void RemoveItem(int serverHandle, int itemHandle) { } + public void Advise(int serverHandle, int itemHandle) { } + public void UnAdvise(int serverHandle, int itemHandle) { } + public void AdviseSupervisory(int serverHandle, int itemHandle) { } + public int AddBufferedItem(int serverHandle, string itemDefinition, string itemContext) => 0; + public void SetBufferedUpdateInterval(int serverHandle, int updateIntervalMilliseconds) { } + public void Suspend(int serverHandle, int itemHandle) { } + public void Activate(int serverHandle, int itemHandle) { } + public void Write(int serverHandle, int itemHandle, object value, int userId) { } + public void Write2(int serverHandle, int itemHandle, object value, object timestampValue, int userId) { } + public void WriteSecured(int serverHandle, int itemHandle, int currentUserId, int verifierUserId, object value) { } + public void WriteSecured2(int serverHandle, int itemHandle, int currentUserId, int verifierUserId, object value, object timestampValue) { } + public int AuthenticateUser(string userName, string password) => 0; + public int ArchestrAUserToId(string userName) => 0; + } + + private sealed class NullEventSink : IMxAccessEventSink + { + public void Attach(object mxAccessComObject, string sessionId) { } + public void Detach() { } + } + + private sealed class FakeAlarmHandler : IAlarmCommandHandler + { + public string? LastSubscription { get; private set; } + public string? LastSessionId { get; private set; } + public bool UnsubscribeCalled { get; private set; } + public Guid LastAckGuid { get; private set; } + public string? LastAckOperatorName { get; private set; } + public int AcknowledgeReturn { get; set; } + public bool AcknowledgeThrow { get; set; } + public IReadOnlyList QueryResult { get; set; } = + Array.Empty(); + public string? LastFilterPrefix { get; private set; } + + public void Subscribe(string subscription, string sessionId) + { + LastSubscription = subscription; + LastSessionId = sessionId; + } + + public void Unsubscribe() + { + UnsubscribeCalled = true; + } + + public int Acknowledge( + Guid alarmGuid, string comment, string operatorUser, + string operatorNode, string operatorDomain, string operatorFullName) + { + LastAckGuid = alarmGuid; + LastAckOperatorName = operatorUser; + if (AcknowledgeThrow) + { + throw new InvalidOperationException("simulated alarm-handler failure"); + } + return AcknowledgeReturn; + } + + public IReadOnlyList QueryActive(string? alarmFilterPrefix) + { + LastFilterPrefix = alarmFilterPrefix; + return QueryResult; + } + + public void Dispose() { } + } +} diff --git a/src/MxGateway.Worker.Tests/MxAccess/AlarmCommandHandlerTests.cs b/src/MxGateway.Worker.Tests/MxAccess/AlarmCommandHandlerTests.cs new file mode 100644 index 0000000..10e34a0 --- /dev/null +++ b/src/MxGateway.Worker.Tests/MxAccess/AlarmCommandHandlerTests.cs @@ -0,0 +1,232 @@ +using System; +using System.Collections.Generic; +using MxGateway.Contracts.Proto; +using MxGateway.Worker.MxAccess; + +namespace MxGateway.Worker.Tests.MxAccess; + +/// +/// Unit tests for the per-session alarm command router. Uses a fake +/// consumer factory so the lazy-construction lifecycle on +/// SubscribeAlarms is exercised without touching wnwrap COM. +/// +public sealed class AlarmCommandHandlerTests +{ + [Fact] + public void Subscribe_creates_consumer_and_calls_subscribe() + { + FakeConsumer consumer = new FakeConsumer(); + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => consumer); + + handler.Subscribe(@"\\HOST\Galaxy!Area", "session-1"); + + Assert.True(handler.IsSubscribed); + Assert.Equal(@"\\HOST\Galaxy!Area", consumer.LastSubscription); + } + + [Fact] + public void Second_subscribe_without_unsubscribe_throws() + { + FakeConsumer consumer = new FakeConsumer(); + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => consumer); + + handler.Subscribe(@"\\HOST\Galaxy!A", "s1"); + Assert.Throws( + () => handler.Subscribe(@"\\HOST\Galaxy!B", "s1")); + } + + [Fact] + public void Subscribe_disposes_consumer_when_underlying_subscribe_throws() + { + FakeConsumer consumer = new FakeConsumer { ThrowOnSubscribe = true }; + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => consumer); + + Assert.Throws( + () => handler.Subscribe(@"\\HOST\Galaxy!A", "s1")); + Assert.False(handler.IsSubscribed); + Assert.True(consumer.Disposed); + } + + [Fact] + public void Unsubscribe_disposes_consumer_and_clears_state() + { + FakeConsumer consumer = new FakeConsumer(); + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => consumer); + handler.Subscribe(@"\\HOST\Galaxy!A", "s1"); + + handler.Unsubscribe(); + + Assert.False(handler.IsSubscribed); + Assert.True(consumer.Disposed); + } + + [Fact] + public void Unsubscribe_without_prior_subscribe_is_noop() + { + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => new FakeConsumer()); + handler.Unsubscribe(); // Should not throw. + Assert.False(handler.IsSubscribed); + } + + [Fact] + public void Acknowledge_forwards_to_consumer_with_full_operator_identity() + { + FakeConsumer consumer = new FakeConsumer { AcknowledgeReturn = 0 }; + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => consumer); + handler.Subscribe(@"\\HOST\Galaxy!A", "s1"); + + Guid g = Guid.NewGuid(); + int rc = handler.Acknowledge(g, "c", "u", "n", "d", "F"); + + Assert.Equal(0, rc); + Assert.Equal(g, consumer.LastAckGuid); + Assert.Equal("u", consumer.LastAckOperatorName); + } + + [Fact] + public void Acknowledge_before_subscribe_throws_invalid_op() + { + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => new FakeConsumer()); + + Assert.Throws( + () => handler.Acknowledge(Guid.Empty, "", "", "", "", "")); + } + + [Fact] + public void QueryActive_returns_mapped_proto_snapshots() + { + FakeConsumer consumer = new FakeConsumer + { + SnapshotResult = new[] + { + new MxAlarmSnapshotRecord + { + AlarmGuid = Guid.NewGuid(), + ProviderName = "Galaxy", + Group = "TestArea", + TagName = "Tag1", + Type = "DSC", + Priority = 500, + State = MxAlarmStateKind.UnackAlm, + }, + }, + }; + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => consumer); + handler.Subscribe(@"\\HOST\Galaxy!A", "s1"); + + IReadOnlyList snapshots = handler.QueryActive(null); + + Assert.Single(snapshots); + Assert.Equal("Galaxy!TestArea.Tag1", snapshots[0].AlarmFullReference); + Assert.Equal(AlarmConditionState.Active, snapshots[0].CurrentState); + } + + [Fact] + public void QueryActive_filters_by_prefix() + { + FakeConsumer consumer = new FakeConsumer + { + SnapshotResult = new[] + { + NewRecord("Galaxy", "AreaA", "Tag1"), + NewRecord("Galaxy", "AreaB", "Tag2"), + }, + }; + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => consumer); + handler.Subscribe(@"\\HOST\Galaxy!A", "s1"); + + IReadOnlyList filtered = handler.QueryActive("Galaxy!AreaA"); + + Assert.Single(filtered); + Assert.Equal("Galaxy!AreaA.Tag1", filtered[0].AlarmFullReference); + } + + [Fact] + public void Dispose_unsubscribes_and_disposes_consumer() + { + FakeConsumer consumer = new FakeConsumer(); + AlarmCommandHandler handler = new AlarmCommandHandler( + new MxAccessEventQueue(), + () => consumer); + handler.Subscribe(@"\\HOST\Galaxy!A", "s1"); + + handler.Dispose(); + + Assert.True(consumer.Disposed); + Assert.Throws( + () => handler.Subscribe("x", "y")); + } + + private static MxAlarmSnapshotRecord NewRecord(string provider, string group, string tag) + { + return new MxAlarmSnapshotRecord + { + AlarmGuid = Guid.NewGuid(), + ProviderName = provider, + Group = group, + TagName = tag, + Type = "DSC", + Priority = 500, + State = MxAlarmStateKind.UnackAlm, + }; + } + + private sealed class FakeConsumer : IMxAccessAlarmConsumer + { +#pragma warning disable CS0067 // Event never invoked — fake; AlarmCommandHandler tests don't drive transitions. + public event EventHandler? AlarmTransitionEmitted; +#pragma warning restore CS0067 + + public string? LastSubscription { get; private set; } + public Guid LastAckGuid { get; private set; } + public string? LastAckOperatorName { get; private set; } + public int AcknowledgeReturn { get; set; } + public IReadOnlyList SnapshotResult { get; set; } = + Array.Empty(); + public bool ThrowOnSubscribe { get; set; } + public bool Disposed { get; private set; } + + public void Subscribe(string subscription) + { + LastSubscription = subscription; + if (ThrowOnSubscribe) + { + throw new InvalidOperationException("simulated wnwrap subscribe failure"); + } + } + + public int AcknowledgeByGuid( + Guid alarmGuid, string ackComment, string ackOperatorName, + string ackOperatorNode, string ackOperatorDomain, string ackOperatorFullName) + { + LastAckGuid = alarmGuid; + LastAckOperatorName = ackOperatorName; + return AcknowledgeReturn; + } + + public IReadOnlyList SnapshotActiveAlarms() => SnapshotResult; + + public void Dispose() + { + Disposed = true; + } + } +} diff --git a/src/MxGateway.Worker/MxAccess/AlarmCommandHandler.cs b/src/MxGateway.Worker/MxAccess/AlarmCommandHandler.cs new file mode 100644 index 0000000..1ac5744 --- /dev/null +++ b/src/MxGateway.Worker/MxAccess/AlarmCommandHandler.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using MxGateway.Contracts.Proto; + +namespace MxGateway.Worker.MxAccess; + +/// +/// Per-session owner of the worker's alarm-side state. Lazy-creates an +/// (with a wnwrap-backed +/// by default) on the first +/// call, then routes +/// / / +/// through the same instance for the +/// session's lifetime. +/// +/// +/// +/// Construction is dependency-injectable: the consumer factory +/// (default () => new WnWrapAlarmConsumer()) lets tests +/// substitute a fake without touching AVEVA COM. The event queue +/// is supplied by the owning so +/// the alarm-side proto events land on the same queue the worker +/// already drains for IPC dispatch. +/// +/// +/// Threading: invoked from +/// which runs on the STA. The wnwrap consumer's polling timer +/// fires on a thread-pool thread; the only cross-thread surface +/// is the 's event handler, which +/// hand-offs into the thread-safe . +/// +/// +public sealed class AlarmCommandHandler : IAlarmCommandHandler +{ + private readonly MxAccessEventQueue eventQueue; + private readonly Func consumerFactory; + private readonly object syncRoot = new object(); + private AlarmDispatcher? dispatcher; + private bool disposed; + + public AlarmCommandHandler(MxAccessEventQueue eventQueue) + : this(eventQueue, () => new WnWrapAlarmConsumer()) + { + } + + /// Test seam — inject a custom consumer factory. + public AlarmCommandHandler( + MxAccessEventQueue eventQueue, + Func consumerFactory) + { + this.eventQueue = eventQueue ?? throw new ArgumentNullException(nameof(eventQueue)); + this.consumerFactory = consumerFactory ?? throw new ArgumentNullException(nameof(consumerFactory)); + } + + public bool IsSubscribed + { + get { lock (syncRoot) return dispatcher is not null; } + } + + /// + public void Subscribe(string subscription, string sessionId) + { + if (disposed) throw new ObjectDisposedException(nameof(AlarmCommandHandler)); + if (subscription is null) throw new ArgumentNullException(nameof(subscription)); + + lock (syncRoot) + { + if (dispatcher is not null) + { + throw new InvalidOperationException( + "AlarmCommandHandler already has an active subscription; " + + "call Unsubscribe before issuing another SubscribeAlarms command."); + } + IMxAccessAlarmConsumer consumer = consumerFactory() + ?? throw new InvalidOperationException("Alarm consumer factory returned null."); + MxAccessAlarmEventSink sink = new MxAccessAlarmEventSink( + eventQueue, new MxAccessEventMapper()); + dispatcher = new AlarmDispatcher(consumer, sink, sessionId ?? string.Empty); + try + { + dispatcher.Subscribe(subscription); + } + catch + { + try { dispatcher.Dispose(); } catch { /* swallow */ } + dispatcher = null; + throw; + } + } + } + + /// + public void Unsubscribe() + { + AlarmDispatcher? toDispose; + lock (syncRoot) + { + toDispose = dispatcher; + dispatcher = null; + } + toDispose?.Dispose(); + } + + /// + public int Acknowledge( + Guid alarmGuid, + string comment, + string operatorUser, + string operatorNode, + string operatorDomain, + string operatorFullName) + { + AlarmDispatcher? d = GetDispatcherOrThrow(); + return d.Acknowledge( + alarmGuid, + comment ?? string.Empty, + operatorUser ?? string.Empty, + operatorNode ?? string.Empty, + operatorDomain ?? string.Empty, + operatorFullName ?? string.Empty); + } + + /// + public IReadOnlyList QueryActive(string? alarmFilterPrefix) + { + AlarmDispatcher? d = GetDispatcherOrThrow(); + IReadOnlyList all = d.SnapshotActiveAlarms(); + if (string.IsNullOrEmpty(alarmFilterPrefix)) return all; + List filtered = new List(all.Count); + foreach (ActiveAlarmSnapshot snap in all) + { + if (snap.AlarmFullReference.StartsWith(alarmFilterPrefix!, StringComparison.Ordinal)) + { + filtered.Add(snap); + } + } + return filtered; + } + + private AlarmDispatcher GetDispatcherOrThrow() + { + if (disposed) throw new ObjectDisposedException(nameof(AlarmCommandHandler)); + AlarmDispatcher? d; + lock (syncRoot) d = dispatcher; + if (d is null) + { + throw new InvalidOperationException( + "AlarmCommandHandler has no active subscription; " + + "call SubscribeAlarms before issuing alarm-related commands."); + } + return d; + } + + /// + public void Dispose() + { + if (disposed) return; + disposed = true; + Unsubscribe(); + } +} + +/// +/// Per-session interface routing the worker's alarm IPC commands — +/// SubscribeAlarmsCommand, AcknowledgeAlarmCommand, +/// QueryActiveAlarmsCommand, UnsubscribeAlarmsCommand — +/// to the underlying . Production binding +/// is ; tests substitute a fake. +/// +public interface IAlarmCommandHandler : IDisposable +{ + /// Begin a subscription against the supplied AVEVA alarm-provider expression. + void Subscribe(string subscription, string sessionId); + + /// Tear down the active subscription. No-op if not subscribed. + void Unsubscribe(); + + /// Acknowledge a single alarm by GUID. Returns AVEVA's native status (0 = success). + int Acknowledge( + Guid alarmGuid, + string comment, + string operatorUser, + string operatorNode, + string operatorDomain, + string operatorFullName); + + /// + /// Snapshot the currently-active alarm set, optionally scoped to a + /// prefix matched against AlarmFullReference. + /// + IReadOnlyList QueryActive(string? alarmFilterPrefix); +} diff --git a/src/MxGateway.Worker/MxAccess/MxAccessCommandExecutor.cs b/src/MxGateway.Worker/MxAccess/MxAccessCommandExecutor.cs index 0ddb00a..bc37d7e 100644 --- a/src/MxGateway.Worker/MxAccess/MxAccessCommandExecutor.cs +++ b/src/MxGateway.Worker/MxAccess/MxAccessCommandExecutor.cs @@ -13,13 +13,14 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor { private readonly MxAccessSession session; private readonly VariantConverter variantConverter; + private readonly IAlarmCommandHandler? alarmCommandHandler; /// /// Initializes a command executor with an MXAccess session. /// /// MXAccess session on the STA thread. public MxAccessCommandExecutor(MxAccessSession session) - : this(session, new VariantConverter()) + : this(session, new VariantConverter(), alarmCommandHandler: null) { } @@ -31,9 +32,24 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor public MxAccessCommandExecutor( MxAccessSession session, VariantConverter variantConverter) + : this(session, variantConverter, alarmCommandHandler: null) + { + } + + /// + /// Initializes a command executor with an MXAccess session, variant + /// converter, and an alarm command handler. The alarm handler is + /// optional — when null, alarm-side commands return an + /// "alarm consumer not configured" diagnostic. + /// + public MxAccessCommandExecutor( + MxAccessSession session, + VariantConverter variantConverter, + IAlarmCommandHandler? alarmCommandHandler) { this.session = session ?? throw new ArgumentNullException(nameof(session)); this.variantConverter = variantConverter ?? throw new ArgumentNullException(nameof(variantConverter)); + this.alarmCommandHandler = alarmCommandHandler; } /// @@ -64,6 +80,10 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor MxCommandKind.UnAdviseItemBulk => ExecuteUnAdviseItemBulk(command), MxCommandKind.SubscribeBulk => ExecuteSubscribeBulk(command), MxCommandKind.UnsubscribeBulk => ExecuteUnsubscribeBulk(command), + MxCommandKind.SubscribeAlarms => ExecuteSubscribeAlarms(command), + MxCommandKind.UnsubscribeAlarms => ExecuteUnsubscribeAlarms(command), + MxCommandKind.AcknowledgeAlarm => ExecuteAcknowledgeAlarm(command), + MxCommandKind.QueryActiveAlarms => ExecuteQueryActiveAlarms(command), _ => CreateInvalidRequestReply(command, $"Unsupported MXAccess command kind {command.Kind}."), }; } @@ -280,6 +300,153 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor session.UnsubscribeBulk(unsubscribeBulkCommand.ServerHandle, unsubscribeBulkCommand.ItemHandles)); } + private MxCommandReply ExecuteSubscribeAlarms(StaCommand command) + { + if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.SubscribeAlarms) + { + return CreateInvalidRequestReply(command, "SubscribeAlarms command payload is required."); + } + if (alarmCommandHandler is null) + { + return CreateInvalidRequestReply( + command, + "SubscribeAlarms requires an alarm command handler; the worker was constructed without one."); + } + + string subscription = command.Command.SubscribeAlarms.SubscriptionExpression ?? string.Empty; + if (string.IsNullOrWhiteSpace(subscription)) + { + return CreateInvalidRequestReply(command, "SubscribeAlarms.subscription_expression is required."); + } + + try + { + alarmCommandHandler.Subscribe(subscription, command.SessionId); + return CreateOkReply(command); + } + catch (Exception ex) + { + return CreateAlarmFailureReply(command, ex); + } + } + + private MxCommandReply ExecuteUnsubscribeAlarms(StaCommand command) + { + if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.UnsubscribeAlarms) + { + return CreateInvalidRequestReply(command, "UnsubscribeAlarms command payload is required."); + } + if (alarmCommandHandler is null) + { + // No handler configured — Unsubscribe is a no-op in that case; + // it can't be in a subscribed state to begin with. + return CreateOkReply(command); + } + + try + { + alarmCommandHandler.Unsubscribe(); + return CreateOkReply(command); + } + catch (Exception ex) + { + return CreateAlarmFailureReply(command, ex); + } + } + + private MxCommandReply ExecuteAcknowledgeAlarm(StaCommand command) + { + if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.AcknowledgeAlarmCommand) + { + return CreateInvalidRequestReply(command, "AcknowledgeAlarm command payload is required."); + } + if (alarmCommandHandler is null) + { + return CreateInvalidRequestReply( + command, + "AcknowledgeAlarm requires an alarm command handler; the worker was constructed without one."); + } + + AcknowledgeAlarmCommand payload = command.Command.AcknowledgeAlarmCommand; + if (!Guid.TryParse(payload.AlarmGuid, out Guid alarmGuid)) + { + return CreateInvalidRequestReply( + command, + $"AcknowledgeAlarm.alarm_guid is not a valid canonical GUID: '{payload.AlarmGuid}'."); + } + + try + { + int rc = alarmCommandHandler.Acknowledge( + alarmGuid, + payload.Comment, + payload.OperatorUser, + payload.OperatorNode, + payload.OperatorDomain, + payload.OperatorFullName); + MxCommandReply reply = CreateOkReply(command); + reply.Hresult = rc; + reply.AcknowledgeAlarm = new AcknowledgeAlarmReplyPayload + { + NativeStatus = rc, + }; + if (rc != 0) + { + reply.DiagnosticMessage = $"AVEVA AlarmAckByGUID returned non-zero status {rc}."; + } + return reply; + } + catch (Exception ex) + { + return CreateAlarmFailureReply(command, ex); + } + } + + private MxCommandReply ExecuteQueryActiveAlarms(StaCommand command) + { + if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.QueryActiveAlarmsCommand) + { + return CreateInvalidRequestReply(command, "QueryActiveAlarms command payload is required."); + } + if (alarmCommandHandler is null) + { + return CreateInvalidRequestReply( + command, + "QueryActiveAlarms requires an alarm command handler; the worker was constructed without one."); + } + + try + { + IReadOnlyList snapshots = alarmCommandHandler.QueryActive( + command.Command.QueryActiveAlarmsCommand.AlarmFilterPrefix); + QueryActiveAlarmsReplyPayload payload = new QueryActiveAlarmsReplyPayload(); + payload.Snapshots.AddRange(snapshots); + MxCommandReply reply = CreateOkReply(command); + reply.QueryActiveAlarms = payload; + return reply; + } + catch (Exception ex) + { + return CreateAlarmFailureReply(command, ex); + } + } + + private static MxCommandReply CreateAlarmFailureReply(StaCommand command, Exception exception) + { + return new MxCommandReply + { + SessionId = command.SessionId, + CorrelationId = command.CorrelationId, + Kind = command.Kind, + ProtocolStatus = new ProtocolStatus + { + Code = ProtocolStatusCode.MxaccessFailure, + Message = exception.Message, + }, + DiagnosticMessage = $"{exception.GetType().FullName}: {exception.Message}", + }; + } + private static MxCommandReply CreateOkReply(StaCommand command) { return new MxCommandReply diff --git a/src/MxGateway.Worker/MxAccess/MxAccessStaSession.cs b/src/MxGateway.Worker/MxAccess/MxAccessStaSession.cs index 4dbf56e..4b223a9 100644 --- a/src/MxGateway.Worker/MxAccess/MxAccessStaSession.cs +++ b/src/MxGateway.Worker/MxAccess/MxAccessStaSession.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using MxGateway.Contracts.Proto; +using MxGateway.Worker.Conversion; using MxGateway.Worker.Sta; namespace MxGateway.Worker.MxAccess; @@ -14,8 +15,10 @@ public sealed class MxAccessStaSession : IWorkerRuntimeSession private readonly IMxAccessEventSink eventSink; private readonly MxAccessEventQueue eventQueue; private readonly StaRuntime staRuntime; + private readonly Func? alarmCommandHandlerFactory; private StaCommandDispatcher? commandDispatcher; private MxAccessSession? session; + private IAlarmCommandHandler? alarmCommandHandler; private bool disposed; /// @@ -69,11 +72,29 @@ public sealed class MxAccessStaSession : IWorkerRuntimeSession IMxAccessComObjectFactory factory, IMxAccessEventSink eventSink, MxAccessEventQueue eventQueue) + : this(staRuntime, factory, eventSink, eventQueue, alarmCommandHandlerFactory: null) + { + } + + /// + /// Initializes a new instance of with all + /// dependencies including an alarm-command handler factory. The factory is + /// invoked on the STA thread during ; + /// pass null to opt out of alarm-side commands (the worker rejects + /// them with an "alarm consumer not configured" diagnostic). + /// + public MxAccessStaSession( + StaRuntime staRuntime, + IMxAccessComObjectFactory factory, + IMxAccessEventSink eventSink, + MxAccessEventQueue eventQueue, + Func? alarmCommandHandlerFactory) { this.staRuntime = staRuntime ?? throw new ArgumentNullException(nameof(staRuntime)); this.factory = factory ?? throw new ArgumentNullException(nameof(factory)); this.eventSink = eventSink ?? throw new ArgumentNullException(nameof(eventSink)); this.eventQueue = eventQueue ?? throw new ArgumentNullException(nameof(eventQueue)); + this.alarmCommandHandlerFactory = alarmCommandHandlerFactory; } /// @@ -117,9 +138,16 @@ public sealed class MxAccessStaSession : IWorkerRuntimeSession } session = MxAccessSession.Create(factory, eventSink, sessionId); + if (alarmCommandHandlerFactory is not null) + { + alarmCommandHandler = alarmCommandHandlerFactory(eventQueue); + } commandDispatcher = new StaCommandDispatcher( staRuntime, - new MxAccessCommandExecutor(session)); + new MxAccessCommandExecutor( + session, + new VariantConverter(), + alarmCommandHandler)); return session.CreateWorkerReady(workerProcessId); }, @@ -279,6 +307,27 @@ public sealed class MxAccessStaSession : IWorkerRuntimeSession commandDispatcher?.RequestShutdown(); + // Stop the alarm consumer's polling timer and tear down the + // dispatcher BEFORE the data-side cleanup begins. The alarm + // consumer holds a wnwrap COM RCW that needs the STA pump to + // unwind cleanly; doing it here gives it the opportunity while + // the STA is still alive. + IAlarmCommandHandler? alarmHandlerToDispose = alarmCommandHandler; + alarmCommandHandler = null; + if (alarmHandlerToDispose is not null) + { + try + { + await staRuntime.InvokeAsync( + () => alarmHandlerToDispose.Dispose(), + cancellationToken).ConfigureAwait(false); + } + catch + { + // Swallow — alarm cleanup must not block data shutdown. + } + } + Stopwatch stopwatch = Stopwatch.StartNew(); MxAccessShutdownResult result; if (session is null) @@ -333,6 +382,19 @@ public sealed class MxAccessStaSession : IWorkerRuntimeSession RequestShutdown(); + IAlarmCommandHandler? alarmHandlerToDispose = alarmCommandHandler; + alarmCommandHandler = null; + if (alarmHandlerToDispose is not null) + { + try + { + staRuntime.InvokeAsync(() => alarmHandlerToDispose.Dispose()) + .Wait(TimeSpan.FromSeconds(2)); + } + catch (AggregateException) { } + catch (ObjectDisposedException) { } + } + if (session is not null) { try