Implement LmxOpcUa server — all 6 phases complete

Full OPC UA server on .NET Framework 4.8 (x86) exposing AVEVA System
Platform Galaxy tags via MXAccess. Mirrors Galaxy object hierarchy as
OPC UA address space, translating contained-name browse paths to
tag-name runtime references.

Components implemented:
- Configuration: AppConfiguration with 4 sections, validator
- Domain: ConnectionState, Quality, Vtq, MxDataTypeMapper, error codes
- MxAccess: StaComThread, MxAccessClient (partial classes), MxProxyAdapter
  using strongly-typed ArchestrA.MxAccess COM interop
- Galaxy Repository: SQL queries (hierarchy, attributes, change detection),
  ChangeDetectionService with auto-rebuild on deploy
- OPC UA Server: LmxNodeManager (CustomNodeManager2), LmxOpcUaServer,
  OpcUaServerHost with programmatic config, SecurityPolicy None
- Status Dashboard: HTTP server with HTML/JSON/health endpoints
- Integration: Full 14-step startup, graceful shutdown, component wiring

175 tests (174 unit + 1 integration), all passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-03-25 05:55:27 -04:00
commit a7576ffb38
283 changed files with 16493 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
-- View: internal_all_alarms_view
CREATE VIEW [dbo].[internal_all_alarms_view]
AS
select (CASE
WHEN p.extension_type = N'badvaluealarmextension'
THEN g.tag_name + N'.' + p.primitive_name + N'.Bad'
ELSE
g.tag_name + N'.' + p.pri
GO

View File

@@ -0,0 +1,10 @@
-- View: internal_all_view_app_view
-- this view becomes an indexed view and is used to increase
-- the performance of internal_mark_view_app_for_redeploy
--
-- contains gobject_ids of all view apps
CREATE view dbo.internal_all_view_app_view with schemabinding as
select TOP 100
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_automation_object_model_hierarchy_view
/*
***********************************************************************************************************************
***
*** object name: internal_automation_object_Model_hierarchy_view
*** description: view is use
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_automation_object_model_hierarchy_view2
/*
***********************************************************************************************************************
***
*** object name: internal_automation_object_Model_hierarchy_view2
*** description: view is
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_automation_object_visual_element_hierarchy_view
/*
***********************************************************************************************************************
***
*** object name: internal_automation_object_visual_element_hierarchy_view
*** description: vi
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_automation_object_visual_element_hierarchy_view_includetemplates
/*
***********************************************************************************************************************
***
*** object name: internal_automation_object_visual_element_hierarchy_view
*** description: vi
GO

View File

@@ -0,0 +1,14 @@
-- View: internal_checked_in_unbound_relative_visual_element_reference_view
create view
dbo.internal_checked_in_unbound_relative_visual_element_reference_view
with schemabinding
as
select
ver.gobject_id,
ver.package_id,
ver.mx_primitive_id,
ver.visual_element_reference_index,
ver.checked_in_unbou
GO

View File

@@ -0,0 +1,14 @@
-- View: internal_checked_out_unbound_relative_visual_element_reference_view
create view
dbo.internal_checked_out_unbound_relative_visual_element_reference_view
with schemabinding
as
select
ver.gobject_id,
ver.package_id,
ver.mx_primitive_id,
ver.visual_element_reference_index,
ver.checked_out_unb
GO

View File

@@ -0,0 +1,13 @@
-- View: internal_common_obj
create view dbo.internal_common_obj as
SELECT
gobj.gobject_id AS gobject_id,
gobj.tag_name AS tag_name,
td.category_id AS category_id,
tset.toolset_name AS toolset_name,
gobj.is_template AS is_template,
pg.status_id AS status,
gob
GO

View File

@@ -0,0 +1,15 @@
-- View: internal_control_view
create view dbo.internal_control_view
with schemabinding
as
select
ci.entity_id,
ci.control_name as name,
g.tag_name + '.' + ci.control_name as full_name,
g.gobject_id as parent_id,
g.tag_name as parent_name,
ci.control_id,
ci.control
GO

View File

@@ -0,0 +1,8 @@
-- View: internal_get_GRMblob_preview_user_view
/****** Object: View [dbo].[[internal_get_GRMblob_preview_user_view]]
This purpose of this view to get GRM Definition blob for the list of all visual elements in the galaxy.
It uses the latest checked-out package for preview and consider's the
GO

View File

@@ -0,0 +1,10 @@
-- View: internal_get_TemplateToolBox_Allelements_view
CREATE view [dbo].[internal_get_TemplateToolBox_Allelements_view]
AS
SELECT Entities.* FROM
(
SELECT
-parent_folder_id as 'parent_id', -- this '-' is required to identify the folder as parent in browisng service while generating the SQ
GO

View File

@@ -0,0 +1,15 @@
-- View: internal_get_TemplateToolBox_folders_view
CREATE view [dbo].[internal_get_TemplateToolBox_folders_view]
AS
SELECT folder_id,
folder_name,
parent_folder_id,
depth,
has_objects,
has_folders,
timestamp_of_last_change
FROM folder
Where folder_typ
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_get_asset_graphics_preview_user_view
/****** Object: View [dbo].[internal_asset_graphics_preview_user_view]
This purpose of this view to get Asset graphics in the galaxy.
It uses the latest checked-out package for preview and consider's the users context.
******/
GO

View File

@@ -0,0 +1,12 @@
-- View: internal_get_attribute_definition_with_validation
CREATE VIEW [dbo].[internal_get_attribute_definition_with_validation]
AS
SELECT
ad.*,
pd.primitive_name,
CASE
WHEN pd.primitive_name = 'ScalingExtension' AND ad.mx_attribute_id IN (101, 102, 103, 104, 105, 106, 107, 108) THEN 1
WHEN pd.primit
GO

View File

@@ -0,0 +1,12 @@
-- View: internal_get_device_scangroups_view
create view [dbo].[internal_get_device_scangroups_view]
as
select
convert(int, p.mx_primitive_id) as entity_id,
p.primitive_name as name, g.gobject_id as parent_id
from gobject g
inner join [dbo].primitive_instance p
on p.gobject_id = g.gob
GO

View File

@@ -0,0 +1,15 @@
-- View: internal_get_external_content_media_types_view
create view dbo.internal_get_external_content_media_types_view
with schemabinding
as
select
mt.entity_id,
mt.media_type,
g.tag_name as parent_name,
ci.control_id,
mt.uri_property_name,
mt.media_type_property_name,
mt
GO

View File

@@ -0,0 +1,14 @@
-- View: internal_get_gtb_Allelements_view
CREATE view [dbo].[internal_get_gtb_Allelements_view]
as
SELECT Entities.* FROM
(
SELECT
-parent_folder_id as 'parent_id',
folder_name as name,
'Folder' as type,
-folder_id as 'entity_id',
GO

View File

@@ -0,0 +1,14 @@
-- View: internal_get_gtb_elements_view
create view [dbo].[internal_get_gtb_elements_view]
as
SELECT
vev.gobject_id,
cd.last_modified,
tv.timestamp_of_last_change,
vev.user_guid,
vev.visual_element_name,
vev.thumbnail,
vev.visual_element_de
GO

View File

@@ -0,0 +1,13 @@
-- View: internal_get_gtb_folders_view
create view dbo.internal_get_gtb_folders_view
as
SELECT folder_id,
folder_name,
parent_folder_id,
depth,
has_objects,
case when f.has_folders = 1 or (Select count(*) from gobject g
inner join folder_gobject_link
GO

View File

@@ -0,0 +1,11 @@
-- View: internal_get_gtb_visual_element_references_deployment_view
create view [dbo].[internal_get_gtb_visual_element_references_deployment_view]
as
WITH linkedSymbol (visual_element_id, visual_element_bind_status, gobject_id, package_id, mx_primitive_id)
AS
(
select vev.visual_element_id,ver
GO

View File

@@ -0,0 +1,11 @@
-- View: internal_get_gtb_visual_element_references_preview_view
/****** Object: View [dbo].[internal_get_gtb_visual_element_references_preview_view]
This purpose of this view is to get Symbol VERL in the galaxy.
******/
create view [dbo].[internal_get_gtb_visual_element_references_preview_view]
as
WITH li
GO

View File

@@ -0,0 +1,11 @@
-- View: internal_get_gtb_visual_element_references_view
create view [dbo].[internal_get_gtb_visual_element_references_view]
as
WITH linkedSymbol (visual_element_id, visual_element_bind_status, gobject_id, package_id, mx_primitive_id)
AS
(
select vev.visual_element_id,ver.visual_ele
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_get_object_wizard_symbol_override_mapping_preview_view
/*
***********************************************************************************************************************
***
*** object name: internal_get_object_wizard_symbol_override_mapping_preview_view
*** description:
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_get_object_wizard_symbol_override_mapping_view
/*
***********************************************************************************************************************
***
*** object name: internal_get_object_wizard_symbol_override_mapping_view
*** description: vie
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_get_object_wizard_symbol_override_preview_view
/*
***********************************************************************************************************************
***
*** object name: internal_get_object_wizard_symbol_override_preview_view
*** description: vie
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_get_object_wizard_symbol_override_view
/*
***********************************************************************************************************************
***
*** object name: internal_get_object_wizard_symbol_override_view
*** description: view is use
GO

View File

@@ -0,0 +1,8 @@
-- View: internal_get_visual_element_primitives_deployment_view
/****** Object: View [dbo].[internal_get_visual_element_primitives_deployment_view]
This purpose of this view to get GRM Definition blob for the list of all visual elements in the galaxy.
It uses the latest checked-in package for deployment
GO

View File

@@ -0,0 +1,11 @@
-- View: internal_get_visual_element_primitives_view
CREATE VIEW dbo.internal_get_visual_element_primitives_view
AS
WITH parentfoldersprefixed
AS (SELECT gobject_id,
contained_by_gobject_id,
Cast(tag_name AS NVARCHAR(250)) AS fullName
FROM
GO

View File

@@ -0,0 +1,12 @@
-- View: internal_gtb_symbols_hierarchy_view
/****** Object: View [dbo].[internal_gtb_symbols_hierarchy_view]
This purpose of this view to get the hierarchy for the GTB graphics in the galaxy.
******/
CREATE view [dbo].[internal_gtb_symbols_hierarchy_view]
as
-- Query to get GTB symbo
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_linked_visual_element_definition_per_user_view
/*
***********************************************************************************************************************
***
*** object name: internal_linked_visual_element_definition_per_user_view
*** description: vie
GO

View File

@@ -0,0 +1,13 @@
-- View: internal_list_automation_objects_view
create view [dbo].[internal_list_automation_objects_view]
AS
select distinct g.gobject_id as 'entity_id',
g.tag_name as 'name',
'object' as type,
'' as description,
up.user_guid,
CASE WHEN g.checked_out_by_user_guid = up.user_guid T
GO

View File

@@ -0,0 +1,18 @@
-- View: internal_list_model_objects_view
CREATE view dbo.internal_list_model_objects_view
AS
with ParentFoldersPrefixed as
(
select gobject_id, contained_by_gobject_id,cast(tag_name as nvarchar(250)) as fullName
from gobject
where contained_by_gobject_id = 0
union a
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_list_objects_view
/**************************************************/
/*Object Name : internal_list_objects_view */
/*Object Type : View. */
/*Purpose : To provide a generic view used by the different list objects stored procedure*/
/*Used By : CDI
GO

View File

@@ -0,0 +1,16 @@
-- View: internal_list_unassigned_objects_view
create view dbo.internal_list_unassigned_objects_view
AS
with ParentFoldersPrefixed as
(
select gobject_id, contained_by_gobject_id
from gobject
where contained_by_gobject_id = 0
union all
select c.gobject_id, c.contained_by_
GO

View File

@@ -0,0 +1,7 @@
-- View: internal_localized_alarm_messages
CREATE VIEW dbo.internal_localized_alarm_messages
AS
--select g.tag_name + '.' + p.primitive_name 'Name', amd.default_message, amd.indexable_default_message, amd.phrase_id, amt.translated_message, amt.locale_id, am.gobject_id, am.package_id, am.mx_primi
GO

View File

@@ -0,0 +1,12 @@
-- View: internal_model_hierarchy_asset_view
/****** Object: View [dbo].[internal_model_hierarchy_asset_view]
This purpose of this view to get the Model hierarchy for the objects in the galaxy.
******/
Create view [dbo].[internal_model_hierarchy_asset_view]
as
select g.gobject_id,
GO

View File

@@ -0,0 +1,16 @@
-- View: internal_package_status_view
/*
This view is used by the WWCDI:QueryObject.h
*/
create view dbo.internal_package_status_view
as
select
g.gobject_id,
p.package_id,
CASE WHEN (p.status_id = 0 and p.reference_status_id = 0) THEN
CASE WHEN ver_warning_view.has_wa
GO

View File

@@ -0,0 +1,12 @@
-- View: internal_proxy_obj
create view dbo.internal_proxy_obj
as
SELECT
-- These are the data used in the proxy object
gobject.gobject_id AS gobject_id,
gobject.tag_name AS tag_name,
gobject.contained_name AS contained_name,
gobject.hierarchical_name AS hierarch
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_reference_primitive_attribute
/**********************************************************************/
/*Object Name : internal_reference_primitive_attribute */
/*Object Type : View. */
/*Purpose : To provide reference and cross reference information */
/*
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_required_support_features
/**************************************************/
/*Object Name : internal_required_support_features */
/*Object Type : View. */
/*Purpose : To provide required_feature and supported feature of all the instances*/
/*Used By : CDI
GO

View File

@@ -0,0 +1,13 @@
-- View: internal_runtime_attributes
--
-- This view is used to supply the GalaxyTagDictionary with tagnames
-- for the InTouch tag browser.
--
create view dbo.internal_runtime_attributes
as
select
case when primitive_instance.primitive_name = '' then
gobject.tag_name +
GO

View File

@@ -0,0 +1,12 @@
-- View: internal_visible_packages_per_user_view
-- This view returns package versions visible to each
-- user.
--
-- It is designed to be added to joins to select packages for
-- a given user.
--
-- For example, to get the visual element versions to use for 'Administrator'
-- user given by @user_
GO

View File

@@ -0,0 +1,13 @@
-- View: internal_visual_element_description_all_packages_view
create view dbo.internal_visual_element_description_all_packages_view
as
select
vev.gobject_id,
vev.visual_element_id,
ve.visual_element_type,
ve.visual_element_category,
case when pri.primitive_name <> ''
GO

View File

@@ -0,0 +1,9 @@
-- View: internal_visual_element_description_per_user_view
/*
***********************************************************************************************************************
***
*** object name: internal_visual_element_description_per_user_view
*** description: view is u
GO

View File

@@ -0,0 +1,13 @@
-- View: internal_visual_element_description_view
create view dbo.internal_visual_element_description_view
with schemabinding
as
select
vev.gobject_id,
vev.visual_element_id,
ve.visual_element_type,
ve.visual_element_category,
case when pri.primitive_name
GO

View File

@@ -0,0 +1,8 @@
-- View: internal_visual_element_primitives_preview_user_view
/****** Object: View [dbo].[internal_visual_element_primitives_preview_user_view]
This purpose of this view to get GRM Definition blob for the list of all visual elements in the galaxy.
It uses the latest checked-out package for preview and co
GO

View File

@@ -0,0 +1,12 @@
-- View: internal_visual_element_reference_per_user_view
create view dbo.internal_visual_element_reference_per_user_view
as
select distinct
ver.gobject_id,
ver.package_id,
ver.mx_primitive_id,
ver.visual_element_bind_status,
ver.visual_element_reference_index,
GO

View File

@@ -0,0 +1,13 @@
-- View: internal_visual_element_reference_view
create view dbo.internal_visual_element_reference_view
as
select distinct
ver.gobject_id,
ver.package_id,
ver.mx_primitive_id,
ver.visual_element_bind_status,
ver.visual_element_reference_index,
ch
GO

View File

@@ -0,0 +1,15 @@
-- View: internal_visual_element_reference_warning_status_view
create view dbo.internal_visual_element_reference_warning_status_view
as
select
distinct
g.gobject_id,
p.package_id,
case when (isnull(ver.gobject_id,0)> 0) then 1
else 0
end as has_warning
from package p with(nolock)
inner join gobject g w
GO

View File

@@ -0,0 +1,15 @@
-- View: internal_visual_element_timestamp_per_user_view
create view dbo.internal_visual_element_timestamp_per_user_view
as
select
g.gobject_id,
vev.package_id,
vev.mx_primitive_id,
vev.visual_element_id,
vet.change_type,
vet.timestamp_of_last_change,
up.user_guid,
pri.property_b
GO

View File

@@ -0,0 +1,7 @@
-- View: public_gobject_definition
create view dbo.public_gobject_definition as
SELECT gobject.tag_name, gobject.contained_name, primitive_definition.primitive_name, attribute_definition.attribute_name, attribute_definition.mx_attribute_id, attribute_definition.has_config_set_handler
GO