diff --git a/.github/workflows/buildandtest.yml b/.github/workflows/buildandtest.yml index f7c5132a0..41032b056 100644 --- a/.github/workflows/buildandtest.yml +++ b/.github/workflows/buildandtest.yml @@ -38,7 +38,7 @@ jobs: TESTRESULTS: "TestResults-${{matrix.csproj}}-${{matrix.os}}-${{matrix.framework}}-${{matrix.configuration}}" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index fe35d1000..51b352c3d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 06189f7fc..965ebf63c 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -34,7 +34,7 @@ jobs: id-token: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -57,13 +57,13 @@ jobs: # https://github.com/docker/build-push-action - name: Setup Docker buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 # Login against a Docker registry except on PR # https://github.com/docker/login-action - name: Log into registry ${{ env.REGISTRY }} if: github.event_name != 'pull_request' - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -93,18 +93,18 @@ jobs: # https://github.com/docker/metadata-action - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: ${{ env.IMAGE_REPOSITORY }} - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 # Build and push Docker image with Buildx (don't push on PR) # https://github.com/docker/build-push-action - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . build-args: | diff --git a/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.cs b/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.cs index f630083bf..30a6f1c9b 100644 --- a/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.cs +++ b/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.cs @@ -73,7 +73,7 @@ public bool ShowDialog(UserNameIdentityToken token) if (token.Password != null && token.Password.Length > 0) { - PasswordTB.Text = new UTF8Encoding().GetString(token.Password); + PasswordTB.Text = Encoding.UTF8.GetString(token.Password); } } @@ -86,7 +86,7 @@ public bool ShowDialog(UserNameIdentityToken token) if (!String.IsNullOrEmpty(PasswordTB.Text)) { - token.Password = new UTF8Encoding().GetBytes(PasswordTB.Text); + token.Password = Encoding.UTF8.GetBytes(PasswordTB.Text); } else { diff --git a/Applications/ConsoleReferenceClient/ClientSamples.cs b/Applications/ConsoleReferenceClient/ClientSamples.cs index 8c8efc8a0..4aee8c0a7 100644 --- a/Applications/ConsoleReferenceClient/ClientSamples.cs +++ b/Applications/ConsoleReferenceClient/ClientSamples.cs @@ -376,7 +376,7 @@ public void SubscribeToDataChanges(ISession session, uint minLifeTime) /// Adds the root node to the result. /// Filters nodes from namespace 0 from the result. /// The list of nodes on the server. - public IList FetchAllNodesNodeCache( + public async Task> FetchAllNodesNodeCacheAsync( IUAClient uaClient, NodeId startingNode, bool fetchTree = false, @@ -398,13 +398,13 @@ public IList FetchAllNodesNodeCache( { // clear NodeCache to fetch all nodes from server uaClient.Session.NodeCache.Clear(); - FetchReferenceIdTypes(uaClient.Session); + await FetchReferenceIdTypesAsync(uaClient.Session).ConfigureAwait(false); } // add root node if (addRootNode) { - var rootNode = uaClient.Session.NodeCache.Find(startingNode); + var rootNode = await uaClient.Session.NodeCache.FindAsync(startingNode).ConfigureAwait(false); nodeDictionary[rootNode.NodeId] = rootNode; } @@ -419,11 +419,11 @@ public IList FetchAllNodesNodeCache( searchDepth++; Utils.LogInfo("{0}: Find {1} references after {2}ms", searchDepth, nodesToBrowse.Count, stopwatch.ElapsedMilliseconds); - IList response = uaClient.Session.NodeCache.FindReferences( + IList response = await uaClient.Session.NodeCache.FindReferencesAsync( nodesToBrowse, references, false, - true); + true).ConfigureAwait(false); var nextNodesToBrowse = new ExpandedNodeIdCollection(); int duplicates = 0; @@ -466,7 +466,7 @@ public IList FetchAllNodesNodeCache( } else { - nodeDictionary[node.NodeId] = node; ; + nodeDictionary[node.NodeId] = node; } } else @@ -511,10 +511,11 @@ public IList FetchAllNodesNodeCache( /// The UAClient with a session to use. /// The node where the browse operation starts. /// An optional BrowseDescription to use. - public ReferenceDescriptionCollection BrowseFullAddressSpace( + public async Task BrowseFullAddressSpaceAsync( IUAClient uaClient, NodeId startingNode = null, - BrowseDescription browseDescription = null) + BrowseDescription browseDescription = null, + CancellationToken ct = default) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); @@ -563,9 +564,10 @@ public ReferenceDescriptionCollection BrowseFullAddressSpace( repeatBrowse = false; try { - _ = uaClient.Session.Browse(null, null, - kMaxReferencesPerNode, browseCollection, - out browseResultCollection, out diagnosticsInfoCollection); + var browseResponse = await uaClient.Session.BrowseAsync(null, null, + kMaxReferencesPerNode, browseCollection, ct).ConfigureAwait(false); + browseResultCollection = browseResponse.Results; + diagnosticsInfoCollection = browseResponse.DiagnosticInfos; ClientBase.ValidateResponse(browseResultCollection, browseCollection); ClientBase.ValidateDiagnosticInfos(diagnosticsInfoCollection, browseCollection); @@ -629,8 +631,9 @@ public ReferenceDescriptionCollection BrowseFullAddressSpace( } Utils.LogInfo("BrowseNext {0} continuation points.", continuationPoints.Count); - _ = uaClient.Session.BrowseNext(null, false, continuationPoints, - out var browseNextResultCollection, out diagnosticsInfoCollection); + var browseNextResult = await uaClient.Session.BrowseNextAsync(null, false, continuationPoints, ct).ConfigureAwait(false); + var browseNextResultCollection = browseNextResult.Results; + diagnosticsInfoCollection = browseNextResult.DiagnosticInfos; ClientBase.ValidateResponse(browseNextResultCollection, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticsInfoCollection, continuationPoints); allBrowseResults.AddRange(browseNextResultCollection); @@ -696,7 +699,7 @@ public ReferenceDescriptionCollection BrowseFullAddressSpace( /// Outputs elapsed time information for perf testing and lists all /// types that were successfully added to the session encodeable type factory. /// - public async Task LoadTypeSystem(ISession session) + public async Task LoadTypeSystemAsync(ISession session) { m_output.WriteLine("Load the server type system."); @@ -742,7 +745,7 @@ public async Task LoadTypeSystem(ISession session) /// The NodeCache needs this information to function properly with subtypes of hierarchical calls. /// /// The session to use - void FetchReferenceIdTypes(ISession session) + Task FetchReferenceIdTypesAsync(ISession session) { // fetch the reference types first, otherwise browse for e.g. hierarchical references with subtypes won't work var bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; @@ -750,7 +753,7 @@ void FetchReferenceIdTypes(ISession session) var referenceTypes = typeof(ReferenceTypeIds) .GetFields(bindingFlags) .Select(field => NodeId.ToExpandedNodeId((NodeId)field.GetValue(null), namespaceUris)); - session.FetchTypeTree(new ExpandedNodeIdCollection(referenceTypes)); + return session.FetchTypeTreeAsync(new ExpandedNodeIdCollection(referenceTypes)); } #endregion @@ -897,7 +900,7 @@ public async Task SubscribeAllValuesAsync( StartNodeId = item.NodeId, AttributeId = Attributes.Value, SamplingInterval = samplingInterval, - DisplayName = item.DisplayName.Text ?? item.BrowseName.Name, + DisplayName = item.DisplayName?.Text ?? item.BrowseName.Name, QueueSize = queueSize, DiscardOldest = true, MonitoringMode = MonitoringMode.Reporting, @@ -907,7 +910,7 @@ public async Task SubscribeAllValuesAsync( } // Create the monitored items on Server side - subscription.ApplyChanges(); + await subscription.ApplyChangesAsync().ConfigureAwait(false); m_output.WriteLine("MonitoredItems {0} created for SubscriptionId = {1}.", subscription.MonitoredItemCount, subscription.Id); } catch (Exception ex) diff --git a/Applications/ConsoleReferenceClient/Program.cs b/Applications/ConsoleReferenceClient/Program.cs index e586a373f..16450caf6 100644 --- a/Applications/ConsoleReferenceClient/Program.cs +++ b/Applications/ConsoleReferenceClient/Program.cs @@ -129,8 +129,7 @@ public static async Task Main(string[] args) // Define the UA Client application ApplicationInstance.MessageDlg = new ApplicationMessageDlg(output); CertificatePasswordProvider PasswordProvider = new CertificatePasswordProvider(password); - ApplicationInstance application = new ApplicationInstance - { + ApplicationInstance application = new ApplicationInstance { ApplicationName = applicationName, ApplicationType = ApplicationType.Client, ConfigSectionName = configSectionName, @@ -220,7 +219,7 @@ public static async Task Main(string[] args) var samples = new ClientSamples(output, ClientBase.ValidateResponse, quitEvent, verbose); if (loadTypes) { - await samples.LoadTypeSystem(uaClient.Session).ConfigureAwait(false); + await samples.LoadTypeSystemAsync(uaClient.Session).ConfigureAwait(false); } if (browseall || fetchall || jsonvalues) @@ -230,7 +229,7 @@ public static async Task Main(string[] args) if (browseall) { referenceDescriptions = - samples.BrowseFullAddressSpace(uaClient, Objects.RootFolder); + await samples.BrowseFullAddressSpaceAsync(uaClient, Objects.RootFolder).ConfigureAwait(false); variableIds = new NodeIdCollection(referenceDescriptions .Where(r => r.NodeClass == NodeClass.Variable && r.TypeDefinition.NamespaceIndex != 0) .Select(r => ExpandedNodeId.ToNodeId(r.NodeId, uaClient.Session.NamespaceUris))); @@ -239,8 +238,7 @@ public static async Task Main(string[] args) IList allNodes = null; if (fetchall) { - allNodes = samples.FetchAllNodesNodeCache( - uaClient, Objects.RootFolder, true, true, false); + allNodes = await samples.FetchAllNodesNodeCacheAsync(uaClient, Objects.RootFolder, true, true, false).ConfigureAwait(false); variableIds = new NodeIdCollection(allNodes .Where(r => r.NodeClass == NodeClass.Variable && r is VariableNode && ((VariableNode)r).DataType.NamespaceIndex != 0) .Select(r => ExpandedNodeId.ToNodeId(r.NodeId, uaClient.Session.NamespaceUris))); @@ -248,7 +246,7 @@ public static async Task Main(string[] args) if (jsonvalues && variableIds != null) { - await samples.ReadAllValuesAsync(uaClient, variableIds).ConfigureAwait(false); + var (allValues, results) = await samples.ReadAllValuesAsync(uaClient, variableIds).ConfigureAwait(false); } if (subscribe && (browseall || fetchall)) diff --git a/Applications/Quickstarts.Servers/Boiler/Boiler.NodeSet2.xml b/Applications/Quickstarts.Servers/Boiler/Boiler.NodeSet2.xml index f5e210b37..8e764d624 100644 --- a/Applications/Quickstarts.Servers/Boiler/Boiler.NodeSet2.xml +++ b/Applications/Quickstarts.Servers/Boiler/Boiler.NodeSet2.xml @@ -1,10 +1,10 @@  - + http://opcfoundation.org/UA/Boiler/ - + diff --git a/Applications/Quickstarts.Servers/Boiler/Boiler.Types.xsd b/Applications/Quickstarts.Servers/Boiler/Boiler.Types.xsd index 4c321c10a..e2c6d129f 100644 --- a/Applications/Quickstarts.Servers/Boiler/Boiler.Types.xsd +++ b/Applications/Quickstarts.Servers/Boiler/Boiler.Types.xsd @@ -7,7 +7,7 @@ > - + diff --git a/Applications/Quickstarts.Servers/MemoryBuffer/MemoryBuffer.NodeSet2.xml b/Applications/Quickstarts.Servers/MemoryBuffer/MemoryBuffer.NodeSet2.xml index 92343e315..537c3a2a1 100644 --- a/Applications/Quickstarts.Servers/MemoryBuffer/MemoryBuffer.NodeSet2.xml +++ b/Applications/Quickstarts.Servers/MemoryBuffer/MemoryBuffer.NodeSet2.xml @@ -1,10 +1,10 @@  - + http://samples.org/UA/MemoryBuffer - + diff --git a/Applications/Quickstarts.Servers/MemoryBuffer/MemoryBuffer.Types.xsd b/Applications/Quickstarts.Servers/MemoryBuffer/MemoryBuffer.Types.xsd index 599f40e5c..58dd18637 100644 --- a/Applications/Quickstarts.Servers/MemoryBuffer/MemoryBuffer.Types.xsd +++ b/Applications/Quickstarts.Servers/MemoryBuffer/MemoryBuffer.Types.xsd @@ -7,7 +7,7 @@ > - + diff --git a/Applications/Quickstarts.Servers/TestData/ArrayValueObjectState.cs b/Applications/Quickstarts.Servers/TestData/ArrayValueObjectState.cs index 872d27566..18df5a97a 100644 --- a/Applications/Quickstarts.Servers/TestData/ArrayValueObjectState.cs +++ b/Applications/Quickstarts.Servers/TestData/ArrayValueObjectState.cs @@ -74,6 +74,9 @@ protected override void OnAfterCreate(ISystemContext context, NodeState node) InitializeVariable(context, IntegerValue, TestData.Variables.ArrayValueObjectType_IntegerValue); InitializeVariable(context, UIntegerValue, TestData.Variables.ArrayValueObjectType_UIntegerValue); InitializeVariable(context, VectorValue, TestData.Variables.ArrayValueObjectType_VectorValue); + InitializeVariable(context, VectorUnionValue, TestData.Variables.ArrayValueObjectType_VectorUnionValue); + InitializeVariable(context, VectorWithOptionalFieldsValue, TestData.Variables.ArrayValueObjectType_VectorWithOptionalFieldsValue); + InitializeVariable(context, MultipleVectorsValue, TestData.Variables.ArrayValueObjectType_MultipleVectorsValue); } #endregion @@ -123,6 +126,9 @@ protected override ServiceResult OnGenerateValues( GenerateValue(system, IntegerValue); GenerateValue(system, UIntegerValue); GenerateValue(system, VectorValue); + GenerateValue(system, VectorUnionValue); + GenerateValue(system, VectorWithOptionalFieldsValue); + GenerateValue(system, MultipleVectorsValue); return base.OnGenerateValues(context, method, objectId, count); } diff --git a/Applications/Quickstarts.Servers/TestData/ScalarValueObjectState.cs b/Applications/Quickstarts.Servers/TestData/ScalarValueObjectState.cs index b444abae2..f8aa7127a 100644 --- a/Applications/Quickstarts.Servers/TestData/ScalarValueObjectState.cs +++ b/Applications/Quickstarts.Servers/TestData/ScalarValueObjectState.cs @@ -74,6 +74,9 @@ protected override void OnAfterCreate(ISystemContext context, NodeState node) InitializeVariable(context, IntegerValue, TestData.Variables.ScalarValueObjectType_IntegerValue); InitializeVariable(context, UIntegerValue, TestData.Variables.ScalarValueObjectType_UIntegerValue); InitializeVariable(context, VectorValue, TestData.Variables.ScalarValueObjectType_VectorValue); + InitializeVariable(context, VectorUnionValue, TestData.Variables.ScalarValueObjectType_VectorUnionValue); + InitializeVariable(context, VectorWithOptionalFieldsValue, TestData.Variables.ScalarValueObjectType_VectorWithOptionalFieldsValue); + InitializeVariable(context, MultipleVectorsValue, TestData.Variables.ScalarValueObjectType_MultipleVectorsValue); } #endregion @@ -123,6 +126,9 @@ protected override ServiceResult OnGenerateValues( GenerateValue(system, IntegerValue); GenerateValue(system, UIntegerValue); GenerateValue(system, VectorValue); + GenerateValue(system, VectorUnionValue); + GenerateValue(system, VectorWithOptionalFieldsValue); + GenerateValue(system, MultipleVectorsValue); return base.OnGenerateValues(context, method, objectId, count); } diff --git a/Applications/Quickstarts.Servers/TestData/TestData.Classes.cs b/Applications/Quickstarts.Servers/TestData/TestData.Classes.cs index 038c82f0c..65452619b 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.Classes.cs +++ b/Applications/Quickstarts.Servers/TestData/TestData.Classes.cs @@ -4606,7 +4606,7 @@ protected override void InitializeOptionalChildren(ISystemContext context) #region Initialization String private const string InitializationString = "AQAAABgAAABodHRwOi8vdGVzdC5vcmcvVUEvRGF0YS//////BGCAAgEAAAABAB0AAABTY2FsYXJWYWx1" + - "ZU9iamVjdFR5cGVJbnN0YW5jZQEBXAQBAVwEXAQAAAEAAAAAJAABAWAEHwAAADVgiQoCAAAAAQAQAAAA" + + "ZU9iamVjdFR5cGVJbnN0YW5jZQEBXAQBAVwEXAQAAAEAAAAAJAABAWAEIgAAADVgiQoCAAAAAQAQAAAA" + "U2ltdWxhdGlvbkFjdGl2ZQEBXQQDAAAAAEcAAABJZiB0cnVlIHRoZSBzZXJ2ZXIgd2lsbCBwcm9kdWNl" + "IG5ldyB2YWx1ZXMgZm9yIGVhY2ggbW9uaXRvcmVkIHZhcmlhYmxlLgAuAERdBAAAAAH/////AQH/////" + "AAAAAARhggoEAAAAAQAOAAAAR2VuZXJhdGVWYWx1ZXMBAV4EAC8BAfkDXgQAAAEB/////wEAAAAXYKkK" + @@ -4673,7 +4673,10 @@ protected override void InitializeOptionalChildren(ISystemContext context) "Z2VyVmFsdWUBAbUEAC8AP7UEAAAAHP////8BAf////8AAAAAFWCJCgIAAAABAAsAAABWZWN0b3JWYWx1" + "ZQEBtgQALwEBYQe2BAAAAQFgB/////8BAf////8DAAAAFWCJCgIAAAABAAEAAABYAQG3BAAuAES3BAAA" + "AAv/////AQH/////AAAAABVgiQoCAAAAAQABAAAAWQEBuAQALgBEuAQAAAAL/////wEB/////wAAAAAV" + - "YIkKAgAAAAEAAQAAAFoBAbkEAC4ARLkEAAAAC/////8BAf////8AAAAA"; + "YIkKAgAAAAEAAQAAAFoBAbkEAC4ARLkEAAAAC/////8BAf////8AAAAAFWCJCgIAAAABABAAAABWZWN0" + + "b3JVbmlvblZhbHVlAQH+DQAvAD/+DQAAAQEADv////8BAf////8AAAAAFWCJCgIAAAABAB0AAABWZWN0" + + "b3JXaXRoT3B0aW9uYWxGaWVsZHNWYWx1ZQEB/w0ALwA//w0AAAEBAQ7/////AQH/////AAAAABVgiQoC" + + "AAAAAQAUAAAATXVsdGlwbGVWZWN0b3JzVmFsdWUBAR4OAC8APx4OAAABAR8O/////wEB/////wAAAAA="; #endregion #endif #endregion @@ -5210,6 +5213,63 @@ public VectorVariableState VectorValue m_vectorValue = value; } } + + /// + public BaseDataVariableState VectorUnionValue + { + get + { + return m_vectorUnionValue; + } + + set + { + if (!Object.ReferenceEquals(m_vectorUnionValue, value)) + { + ChangeMasks |= NodeStateChangeMasks.Children; + } + + m_vectorUnionValue = value; + } + } + + /// + public BaseDataVariableState VectorWithOptionalFieldsValue + { + get + { + return m_vectorWithOptionalFieldsValue; + } + + set + { + if (!Object.ReferenceEquals(m_vectorWithOptionalFieldsValue, value)) + { + ChangeMasks |= NodeStateChangeMasks.Children; + } + + m_vectorWithOptionalFieldsValue = value; + } + } + + /// + public BaseDataVariableState MultipleVectorsValue + { + get + { + return m_multipleVectorsValue; + } + + set + { + if (!Object.ReferenceEquals(m_multipleVectorsValue, value)) + { + ChangeMasks |= NodeStateChangeMasks.Children; + } + + m_multipleVectorsValue = value; + } + } #endregion #region Overridden Methods @@ -5358,6 +5418,21 @@ public override void GetChildren( children.Add(m_vectorValue); } + if (m_vectorUnionValue != null) + { + children.Add(m_vectorUnionValue); + } + + if (m_vectorWithOptionalFieldsValue != null) + { + children.Add(m_vectorWithOptionalFieldsValue); + } + + if (m_multipleVectorsValue != null) + { + children.Add(m_multipleVectorsValue); + } + base.GetChildren(context, children); } @@ -5964,6 +6039,69 @@ protected override BaseInstanceState FindChild( instance = VectorValue; break; } + + case TestData.BrowseNames.VectorUnionValue: + { + if (createOrReplace) + { + if (VectorUnionValue == null) + { + if (replacement == null) + { + VectorUnionValue = new BaseDataVariableState(this); + } + else + { + VectorUnionValue = (BaseDataVariableState)replacement; + } + } + } + + instance = VectorUnionValue; + break; + } + + case TestData.BrowseNames.VectorWithOptionalFieldsValue: + { + if (createOrReplace) + { + if (VectorWithOptionalFieldsValue == null) + { + if (replacement == null) + { + VectorWithOptionalFieldsValue = new BaseDataVariableState(this); + } + else + { + VectorWithOptionalFieldsValue = (BaseDataVariableState)replacement; + } + } + } + + instance = VectorWithOptionalFieldsValue; + break; + } + + case TestData.BrowseNames.MultipleVectorsValue: + { + if (createOrReplace) + { + if (MultipleVectorsValue == null) + { + if (replacement == null) + { + MultipleVectorsValue = new BaseDataVariableState(this); + } + else + { + MultipleVectorsValue = (BaseDataVariableState)replacement; + } + } + } + + instance = MultipleVectorsValue; + break; + } } if (instance != null) @@ -6004,6 +6142,9 @@ protected override BaseInstanceState FindChild( private BaseDataVariableState m_integerValue; private BaseDataVariableState m_uIntegerValue; private VectorVariableState m_vectorValue; + private BaseDataVariableState m_vectorUnionValue; + private BaseDataVariableState m_vectorWithOptionalFieldsValue; + private BaseDataVariableState m_multipleVectorsValue; #endregion } #endif @@ -7543,7 +7684,7 @@ protected override void InitializeOptionalChildren(ISystemContext context) #region Initialization String private const string InitializationString = "AQAAABgAAABodHRwOi8vdGVzdC5vcmcvVUEvRGF0YS//////BGCAAgEAAAABABwAAABBcnJheVZhbHVl" + - "T2JqZWN0VHlwZUluc3RhbmNlAQGwBQEBsAWwBQAAAQAAAAAkAAEBtAUfAAAANWCJCgIAAAABABAAAABT" + + "T2JqZWN0VHlwZUluc3RhbmNlAQGwBQEBsAWwBQAAAQAAAAAkAAEBtAUiAAAANWCJCgIAAAABABAAAABT" + "aW11bGF0aW9uQWN0aXZlAQGxBQMAAAAARwAAAElmIHRydWUgdGhlIHNlcnZlciB3aWxsIHByb2R1Y2Ug" + "bmV3IHZhbHVlcyBmb3IgZWFjaCBtb25pdG9yZWQgdmFyaWFibGUuAC4ARLEFAAAAAf////8BAf////8A" + "AAAABGGCCgQAAAABAA4AAABHZW5lcmF0ZVZhbHVlcwEBsgUALwEB+QOyBQAAAQH/////AQAAABdgqQoC" + @@ -7612,7 +7753,10 @@ protected override void InitializeOptionalChildren(ISystemContext context) "//8AAAAAF2CJCgIAAAABAAwAAABJbnRlZ2VyVmFsdWUBAQgGAC8APwgGAAAAGwEAAAABAAAAAAAAAAEB" + "/////wAAAAAXYIkKAgAAAAEADQAAAFVJbnRlZ2VyVmFsdWUBAQkGAC8APwkGAAAAHAEAAAABAAAAAAAA" + "AAEB/////wAAAAAXYIkKAgAAAAEACwAAAFZlY3RvclZhbHVlAQEKBgAvAD8KBgAAAQFgBwEAAAABAAAA" + - "AAAAAAEB/////wAAAAA="; + "AAAAAAEB/////wAAAAAXYIkKAgAAAAEAEAAAAFZlY3RvclVuaW9uVmFsdWUBARgOAC8APxgOAAABAQAO" + + "AQAAAAEAAAAAAAAAAQH/////AAAAABdgiQoCAAAAAQAdAAAAVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRz" + + "VmFsdWUBARkOAC8APxkOAAABAQEOAQAAAAEAAAAAAAAAAQH/////AAAAABdgiQoCAAAAAQAUAAAATXVs" + + "dGlwbGVWZWN0b3JzVmFsdWUBASsOAC8APysOAAABAR8OAQAAAAEAAAAAAAAAAQH/////AAAAAA=="; #endregion #endif #endregion @@ -8149,6 +8293,63 @@ public BaseDataVariableState VectorValue m_vectorValue = value; } } + + /// + public BaseDataVariableState VectorUnionValue + { + get + { + return m_vectorUnionValue; + } + + set + { + if (!Object.ReferenceEquals(m_vectorUnionValue, value)) + { + ChangeMasks |= NodeStateChangeMasks.Children; + } + + m_vectorUnionValue = value; + } + } + + /// + public BaseDataVariableState VectorWithOptionalFieldsValue + { + get + { + return m_vectorWithOptionalFieldsValue; + } + + set + { + if (!Object.ReferenceEquals(m_vectorWithOptionalFieldsValue, value)) + { + ChangeMasks |= NodeStateChangeMasks.Children; + } + + m_vectorWithOptionalFieldsValue = value; + } + } + + /// + public BaseDataVariableState MultipleVectorsValue + { + get + { + return m_multipleVectorsValue; + } + + set + { + if (!Object.ReferenceEquals(m_multipleVectorsValue, value)) + { + ChangeMasks |= NodeStateChangeMasks.Children; + } + + m_multipleVectorsValue = value; + } + } #endregion #region Overridden Methods @@ -8297,6 +8498,21 @@ public override void GetChildren( children.Add(m_vectorValue); } + if (m_vectorUnionValue != null) + { + children.Add(m_vectorUnionValue); + } + + if (m_vectorWithOptionalFieldsValue != null) + { + children.Add(m_vectorWithOptionalFieldsValue); + } + + if (m_multipleVectorsValue != null) + { + children.Add(m_multipleVectorsValue); + } + base.GetChildren(context, children); } @@ -8903,6 +9119,69 @@ protected override BaseInstanceState FindChild( instance = VectorValue; break; } + + case TestData.BrowseNames.VectorUnionValue: + { + if (createOrReplace) + { + if (VectorUnionValue == null) + { + if (replacement == null) + { + VectorUnionValue = new BaseDataVariableState(this); + } + else + { + VectorUnionValue = (BaseDataVariableState)replacement; + } + } + } + + instance = VectorUnionValue; + break; + } + + case TestData.BrowseNames.VectorWithOptionalFieldsValue: + { + if (createOrReplace) + { + if (VectorWithOptionalFieldsValue == null) + { + if (replacement == null) + { + VectorWithOptionalFieldsValue = new BaseDataVariableState(this); + } + else + { + VectorWithOptionalFieldsValue = (BaseDataVariableState)replacement; + } + } + } + + instance = VectorWithOptionalFieldsValue; + break; + } + + case TestData.BrowseNames.MultipleVectorsValue: + { + if (createOrReplace) + { + if (MultipleVectorsValue == null) + { + if (replacement == null) + { + MultipleVectorsValue = new BaseDataVariableState(this); + } + else + { + MultipleVectorsValue = (BaseDataVariableState)replacement; + } + } + } + + instance = MultipleVectorsValue; + break; + } } if (instance != null) @@ -8943,6 +9222,9 @@ protected override BaseInstanceState FindChild( private BaseDataVariableState m_integerValue; private BaseDataVariableState m_uIntegerValue; private BaseDataVariableState m_vectorValue; + private BaseDataVariableState m_vectorUnionValue; + private BaseDataVariableState m_vectorWithOptionalFieldsValue; + private BaseDataVariableState m_multipleVectorsValue; #endregion } #endif diff --git a/Applications/Quickstarts.Servers/TestData/TestData.Constants.cs b/Applications/Quickstarts.Servers/TestData/TestData.Constants.cs index 5ba3c9047..e65251d33 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.Constants.cs +++ b/Applications/Quickstarts.Servers/TestData/TestData.Constants.cs @@ -124,6 +124,15 @@ public static partial class DataTypes /// public const uint Vector = 1888; + /// + public const uint VectorUnion = 3584; + + /// + public const uint VectorWithOptionalFields = 3585; + + /// + public const uint MultipleVectors = 3615; + /// public const uint WorkOrderStatusType = 1893; @@ -644,6 +653,15 @@ public static partial class Objects /// public const uint Vector_Encoding_DefaultBinary = 3515; + /// + public const uint VectorUnion_Encoding_DefaultBinary = 3590; + + /// + public const uint VectorWithOptionalFields_Encoding_DefaultBinary = 3591; + + /// + public const uint MultipleVectors_Encoding_DefaultBinary = 3618; + /// public const uint WorkOrderStatusType_Encoding_DefaultBinary = 3516; @@ -665,6 +683,15 @@ public static partial class Objects /// public const uint Vector_Encoding_DefaultXml = 3547; + /// + public const uint VectorUnion_Encoding_DefaultXml = 3598; + + /// + public const uint VectorWithOptionalFields_Encoding_DefaultXml = 3599; + + /// + public const uint MultipleVectors_Encoding_DefaultXml = 3622; + /// public const uint WorkOrderStatusType_Encoding_DefaultXml = 3548; @@ -686,6 +713,15 @@ public static partial class Objects /// public const uint Vector_Encoding_DefaultJson = 3579; + /// + public const uint VectorUnion_Encoding_DefaultJson = 3606; + + /// + public const uint VectorWithOptionalFields_Encoding_DefaultJson = 3607; + + /// + public const uint MultipleVectors_Encoding_DefaultJson = 3626; + /// public const uint WorkOrderStatusType_Encoding_DefaultJson = 3580; @@ -1098,6 +1134,15 @@ public static partial class Variables /// public const uint ScalarValueObjectType_VectorValue_Z = 1209; + /// + public const uint ScalarValueObjectType_VectorUnionValue = 3582; + + /// + public const uint ScalarValueObjectType_VectorWithOptionalFieldsValue = 3583; + + /// + public const uint ScalarValueObjectType_MultipleVectorsValue = 3614; + /// public const uint StructureValueObjectType_GenerateValues_InputArguments = 1213; @@ -1617,6 +1662,15 @@ public static partial class Variables /// public const uint ArrayValueObjectType_VectorValue = 1546; + /// + public const uint ArrayValueObjectType_VectorUnionValue = 3608; + + /// + public const uint ArrayValueObjectType_VectorWithOptionalFieldsValue = 3609; + + /// + public const uint ArrayValueObjectType_MultipleVectorsValue = 3627; + /// public const uint AnalogArrayValueObjectType_GenerateValues_InputArguments = 1550; @@ -2364,6 +2418,15 @@ public static partial class Variables /// public const uint Data_Static_Scalar_VectorValue_Z = 2069; + /// + public const uint Data_Static_Scalar_VectorUnionValue = 3586; + + /// + public const uint Data_Static_Scalar_VectorWithOptionalFieldsValue = 3587; + + /// + public const uint Data_Static_Scalar_MultipleVectorsValue = 3616; + /// public const uint Data_Static_Structure_SimulationActive = 2071; @@ -2724,6 +2787,15 @@ public static partial class Variables /// public const uint Data_Static_Array_VectorValue = 2255; + /// + public const uint Data_Static_Array_VectorUnionValue = 3610; + + /// + public const uint Data_Static_Array_VectorWithOptionalFieldsValue = 3611; + + /// + public const uint Data_Static_Array_MultipleVectorsValue = 3628; + /// public const uint Data_Static_UserScalar_SimulationActive = 2257; @@ -3615,6 +3687,15 @@ public static partial class Variables /// public const uint Data_Dynamic_Scalar_VectorValue_Z = 2833; + /// + public const uint Data_Dynamic_Scalar_VectorUnionValue = 3588; + + /// + public const uint Data_Dynamic_Scalar_VectorWithOptionalFieldsValue = 3589; + + /// + public const uint Data_Dynamic_Scalar_MultipleVectorsValue = 3617; + /// public const uint Data_Dynamic_Structure_SimulationActive = 2835; @@ -3975,6 +4056,15 @@ public static partial class Variables /// public const uint Data_Dynamic_Array_VectorValue = 3019; + /// + public const uint Data_Dynamic_Array_VectorUnionValue = 3612; + + /// + public const uint Data_Dynamic_Array_VectorWithOptionalFieldsValue = 3613; + + /// + public const uint Data_Dynamic_Array_MultipleVectorsValue = 3629; + /// public const uint Data_Dynamic_UserScalar_SimulationActive = 3021; @@ -4719,6 +4809,15 @@ public static partial class Variables /// public const uint TestData_BinarySchema_Vector = 3534; + /// + public const uint TestData_BinarySchema_VectorUnion = 3592; + + /// + public const uint TestData_BinarySchema_VectorWithOptionalFields = 3595; + + /// + public const uint TestData_BinarySchema_MultipleVectors = 3619; + /// public const uint TestData_BinarySchema_WorkOrderStatusType = 3537; @@ -4749,6 +4848,15 @@ public static partial class Variables /// public const uint TestData_XmlSchema_Vector = 3566; + /// + public const uint TestData_XmlSchema_VectorUnion = 3600; + + /// + public const uint TestData_XmlSchema_VectorWithOptionalFields = 3603; + + /// + public const uint TestData_XmlSchema_MultipleVectors = 3623; + /// public const uint TestData_XmlSchema_WorkOrderStatusType = 3569; @@ -4858,6 +4966,15 @@ public static partial class DataTypeIds /// public static readonly ExpandedNodeId Vector = new ExpandedNodeId(TestData.DataTypes.Vector, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId VectorUnion = new ExpandedNodeId(TestData.DataTypes.VectorUnion, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId VectorWithOptionalFields = new ExpandedNodeId(TestData.DataTypes.VectorWithOptionalFields, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId MultipleVectors = new ExpandedNodeId(TestData.DataTypes.MultipleVectors, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId WorkOrderStatusType = new ExpandedNodeId(TestData.DataTypes.WorkOrderStatusType, TestData.Namespaces.TestData); @@ -5378,6 +5495,15 @@ public static partial class ObjectIds /// public static readonly ExpandedNodeId Vector_Encoding_DefaultBinary = new ExpandedNodeId(TestData.Objects.Vector_Encoding_DefaultBinary, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId VectorUnion_Encoding_DefaultBinary = new ExpandedNodeId(TestData.Objects.VectorUnion_Encoding_DefaultBinary, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId VectorWithOptionalFields_Encoding_DefaultBinary = new ExpandedNodeId(TestData.Objects.VectorWithOptionalFields_Encoding_DefaultBinary, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId MultipleVectors_Encoding_DefaultBinary = new ExpandedNodeId(TestData.Objects.MultipleVectors_Encoding_DefaultBinary, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId WorkOrderStatusType_Encoding_DefaultBinary = new ExpandedNodeId(TestData.Objects.WorkOrderStatusType_Encoding_DefaultBinary, TestData.Namespaces.TestData); @@ -5399,6 +5525,15 @@ public static partial class ObjectIds /// public static readonly ExpandedNodeId Vector_Encoding_DefaultXml = new ExpandedNodeId(TestData.Objects.Vector_Encoding_DefaultXml, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId VectorUnion_Encoding_DefaultXml = new ExpandedNodeId(TestData.Objects.VectorUnion_Encoding_DefaultXml, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId VectorWithOptionalFields_Encoding_DefaultXml = new ExpandedNodeId(TestData.Objects.VectorWithOptionalFields_Encoding_DefaultXml, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId MultipleVectors_Encoding_DefaultXml = new ExpandedNodeId(TestData.Objects.MultipleVectors_Encoding_DefaultXml, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId WorkOrderStatusType_Encoding_DefaultXml = new ExpandedNodeId(TestData.Objects.WorkOrderStatusType_Encoding_DefaultXml, TestData.Namespaces.TestData); @@ -5420,6 +5555,15 @@ public static partial class ObjectIds /// public static readonly ExpandedNodeId Vector_Encoding_DefaultJson = new ExpandedNodeId(TestData.Objects.Vector_Encoding_DefaultJson, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId VectorUnion_Encoding_DefaultJson = new ExpandedNodeId(TestData.Objects.VectorUnion_Encoding_DefaultJson, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId VectorWithOptionalFields_Encoding_DefaultJson = new ExpandedNodeId(TestData.Objects.VectorWithOptionalFields_Encoding_DefaultJson, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId MultipleVectors_Encoding_DefaultJson = new ExpandedNodeId(TestData.Objects.MultipleVectors_Encoding_DefaultJson, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId WorkOrderStatusType_Encoding_DefaultJson = new ExpandedNodeId(TestData.Objects.WorkOrderStatusType_Encoding_DefaultJson, TestData.Namespaces.TestData); @@ -5832,6 +5976,15 @@ public static partial class VariableIds /// public static readonly ExpandedNodeId ScalarValueObjectType_VectorValue_Z = new ExpandedNodeId(TestData.Variables.ScalarValueObjectType_VectorValue_Z, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId ScalarValueObjectType_VectorUnionValue = new ExpandedNodeId(TestData.Variables.ScalarValueObjectType_VectorUnionValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId ScalarValueObjectType_VectorWithOptionalFieldsValue = new ExpandedNodeId(TestData.Variables.ScalarValueObjectType_VectorWithOptionalFieldsValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId ScalarValueObjectType_MultipleVectorsValue = new ExpandedNodeId(TestData.Variables.ScalarValueObjectType_MultipleVectorsValue, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId StructureValueObjectType_GenerateValues_InputArguments = new ExpandedNodeId(TestData.Variables.StructureValueObjectType_GenerateValues_InputArguments, TestData.Namespaces.TestData); @@ -6351,6 +6504,15 @@ public static partial class VariableIds /// public static readonly ExpandedNodeId ArrayValueObjectType_VectorValue = new ExpandedNodeId(TestData.Variables.ArrayValueObjectType_VectorValue, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId ArrayValueObjectType_VectorUnionValue = new ExpandedNodeId(TestData.Variables.ArrayValueObjectType_VectorUnionValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId ArrayValueObjectType_VectorWithOptionalFieldsValue = new ExpandedNodeId(TestData.Variables.ArrayValueObjectType_VectorWithOptionalFieldsValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId ArrayValueObjectType_MultipleVectorsValue = new ExpandedNodeId(TestData.Variables.ArrayValueObjectType_MultipleVectorsValue, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId AnalogArrayValueObjectType_GenerateValues_InputArguments = new ExpandedNodeId(TestData.Variables.AnalogArrayValueObjectType_GenerateValues_InputArguments, TestData.Namespaces.TestData); @@ -7098,6 +7260,15 @@ public static partial class VariableIds /// public static readonly ExpandedNodeId Data_Static_Scalar_VectorValue_Z = new ExpandedNodeId(TestData.Variables.Data_Static_Scalar_VectorValue_Z, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId Data_Static_Scalar_VectorUnionValue = new ExpandedNodeId(TestData.Variables.Data_Static_Scalar_VectorUnionValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId Data_Static_Scalar_VectorWithOptionalFieldsValue = new ExpandedNodeId(TestData.Variables.Data_Static_Scalar_VectorWithOptionalFieldsValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId Data_Static_Scalar_MultipleVectorsValue = new ExpandedNodeId(TestData.Variables.Data_Static_Scalar_MultipleVectorsValue, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId Data_Static_Structure_SimulationActive = new ExpandedNodeId(TestData.Variables.Data_Static_Structure_SimulationActive, TestData.Namespaces.TestData); @@ -7458,6 +7629,15 @@ public static partial class VariableIds /// public static readonly ExpandedNodeId Data_Static_Array_VectorValue = new ExpandedNodeId(TestData.Variables.Data_Static_Array_VectorValue, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId Data_Static_Array_VectorUnionValue = new ExpandedNodeId(TestData.Variables.Data_Static_Array_VectorUnionValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId Data_Static_Array_VectorWithOptionalFieldsValue = new ExpandedNodeId(TestData.Variables.Data_Static_Array_VectorWithOptionalFieldsValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId Data_Static_Array_MultipleVectorsValue = new ExpandedNodeId(TestData.Variables.Data_Static_Array_MultipleVectorsValue, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId Data_Static_UserScalar_SimulationActive = new ExpandedNodeId(TestData.Variables.Data_Static_UserScalar_SimulationActive, TestData.Namespaces.TestData); @@ -8349,6 +8529,15 @@ public static partial class VariableIds /// public static readonly ExpandedNodeId Data_Dynamic_Scalar_VectorValue_Z = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Scalar_VectorValue_Z, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId Data_Dynamic_Scalar_VectorUnionValue = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Scalar_VectorUnionValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId Data_Dynamic_Scalar_VectorWithOptionalFieldsValue = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Scalar_VectorWithOptionalFieldsValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId Data_Dynamic_Scalar_MultipleVectorsValue = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Scalar_MultipleVectorsValue, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId Data_Dynamic_Structure_SimulationActive = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Structure_SimulationActive, TestData.Namespaces.TestData); @@ -8709,6 +8898,15 @@ public static partial class VariableIds /// public static readonly ExpandedNodeId Data_Dynamic_Array_VectorValue = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Array_VectorValue, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId Data_Dynamic_Array_VectorUnionValue = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Array_VectorUnionValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId Data_Dynamic_Array_VectorWithOptionalFieldsValue = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Array_VectorWithOptionalFieldsValue, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId Data_Dynamic_Array_MultipleVectorsValue = new ExpandedNodeId(TestData.Variables.Data_Dynamic_Array_MultipleVectorsValue, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId Data_Dynamic_UserScalar_SimulationActive = new ExpandedNodeId(TestData.Variables.Data_Dynamic_UserScalar_SimulationActive, TestData.Namespaces.TestData); @@ -9453,6 +9651,15 @@ public static partial class VariableIds /// public static readonly ExpandedNodeId TestData_BinarySchema_Vector = new ExpandedNodeId(TestData.Variables.TestData_BinarySchema_Vector, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId TestData_BinarySchema_VectorUnion = new ExpandedNodeId(TestData.Variables.TestData_BinarySchema_VectorUnion, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId TestData_BinarySchema_VectorWithOptionalFields = new ExpandedNodeId(TestData.Variables.TestData_BinarySchema_VectorWithOptionalFields, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId TestData_BinarySchema_MultipleVectors = new ExpandedNodeId(TestData.Variables.TestData_BinarySchema_MultipleVectors, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId TestData_BinarySchema_WorkOrderStatusType = new ExpandedNodeId(TestData.Variables.TestData_BinarySchema_WorkOrderStatusType, TestData.Namespaces.TestData); @@ -9483,6 +9690,15 @@ public static partial class VariableIds /// public static readonly ExpandedNodeId TestData_XmlSchema_Vector = new ExpandedNodeId(TestData.Variables.TestData_XmlSchema_Vector, TestData.Namespaces.TestData); + /// + public static readonly ExpandedNodeId TestData_XmlSchema_VectorUnion = new ExpandedNodeId(TestData.Variables.TestData_XmlSchema_VectorUnion, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId TestData_XmlSchema_VectorWithOptionalFields = new ExpandedNodeId(TestData.Variables.TestData_XmlSchema_VectorWithOptionalFields, TestData.Namespaces.TestData); + + /// + public static readonly ExpandedNodeId TestData_XmlSchema_MultipleVectors = new ExpandedNodeId(TestData.Variables.TestData_XmlSchema_MultipleVectors, TestData.Namespaces.TestData); + /// public static readonly ExpandedNodeId TestData_XmlSchema_WorkOrderStatusType = new ExpandedNodeId(TestData.Variables.TestData_XmlSchema_WorkOrderStatusType, TestData.Namespaces.TestData); @@ -9636,6 +9852,12 @@ public static partial class BrowseNames /// public const string MonitoredNodeCount = "MonitoredNodeCount"; + /// + public const string MultipleVectors = "MultipleVectors"; + + /// + public const string MultipleVectorsValue = "MultipleVectorsValue"; + /// public const string NewValueCount = "NewValueCount"; @@ -9774,12 +9996,24 @@ public static partial class BrowseNames /// public const string VectorStructure = "VectorStructure"; + /// + public const string VectorUnion = "VectorUnion"; + + /// + public const string VectorUnionValue = "VectorUnionValue"; + /// public const string VectorValue = "VectorValue"; /// public const string VectorVariableType = "VectorVariableType"; + /// + public const string VectorWithOptionalFields = "VectorWithOptionalFields"; + + /// + public const string VectorWithOptionalFieldsValue = "VectorWithOptionalFieldsValue"; + /// public const string WorkOrderStatusType = "WorkOrderStatusType"; diff --git a/Applications/Quickstarts.Servers/TestData/TestData.DataTypes.cs b/Applications/Quickstarts.Servers/TestData/TestData.DataTypes.cs index f842cf32f..add5c653a 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.DataTypes.cs +++ b/Applications/Quickstarts.Servers/TestData/TestData.DataTypes.cs @@ -2863,6 +2863,809 @@ public object Clone() #endif #endregion + #region VectorUnion Class + #if (!OPCUA_EXCLUDE_VectorUnion) + /// + /// + public enum VectorUnionFields : uint + { + /// + None = 0, + /// + X = 1, + /// + Y = 2, + /// + Z = 3 + } + + /// + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Opc.Ua.ModelCompiler", "1.0.0.0")] + [DataContract(Namespace = TestData.Namespaces.TestData)] + public partial class VectorUnion : IEncodeable, IJsonEncodeable + { + #region Constructors + /// + public VectorUnion() + { + Initialize(); + } + + [OnDeserializing] + private void Initialize(StreamingContext context) + { + Initialize(); + } + + private void Initialize() + { + SwitchField = VectorUnionFields.None; + m_x = (double)0; + m_y = (double)0; + m_z = (double)0; + } + #endregion + + #region Public Properties + // + [DataMember(Name = "SwitchField", IsRequired = true, Order = 0)] + public VectorUnionFields SwitchField { get; set; } + + /// + [DataMember(Name = "X", IsRequired = false, Order = 1)] + public double X + { + get { return m_x; } + set { m_x = value; } + } + + /// + [DataMember(Name = "Y", IsRequired = false, Order = 2)] + public double Y + { + get { return m_y; } + set { m_y = value; } + } + + /// + [DataMember(Name = "Z", IsRequired = false, Order = 3)] + public double Z + { + get { return m_z; } + set { m_z = value; } + } + #endregion + + #region IEncodeable Members + /// + public virtual ExpandedNodeId TypeId => DataTypeIds.VectorUnion; + + /// + public virtual ExpandedNodeId BinaryEncodingId => ObjectIds.VectorUnion_Encoding_DefaultBinary; + + /// + public virtual ExpandedNodeId XmlEncodingId => ObjectIds.VectorUnion_Encoding_DefaultXml; + + /// + public virtual ExpandedNodeId JsonEncodingId => ObjectIds.VectorUnion_Encoding_DefaultJson; + + /// + public virtual void Encode(IEncoder encoder) + { + encoder.PushNamespace(TestData.Namespaces.TestData); + encoder.WriteUInt32(nameof(SwitchField), (uint)SwitchField); + + switch (SwitchField) + { + default: { break; } + case VectorUnionFields.X: { encoder.WriteDouble("X", X); break; } + case VectorUnionFields.Y: { encoder.WriteDouble("Y", Y); break; } + case VectorUnionFields.Z: { encoder.WriteDouble("Z", Z); break; } + } + + encoder.PopNamespace(); + } + + /// + public virtual void Decode(IDecoder decoder) + { + decoder.PushNamespace(TestData.Namespaces.TestData); + + SwitchField = (VectorUnionFields)decoder.ReadUInt32(nameof(SwitchField)); + + switch (SwitchField) + { + default: { break; } + case VectorUnionFields.X: { X = decoder.ReadDouble("X"); break; } + case VectorUnionFields.Y: { Y = decoder.ReadDouble("Y"); break; } + case VectorUnionFields.Z: { Z = decoder.ReadDouble("Z"); break; } + } + + decoder.PopNamespace(); + } + + /// + public virtual bool IsEqual(IEncodeable encodeable) + { + if (Object.ReferenceEquals(this, encodeable)) + { + return true; + } + + VectorUnion value = encodeable as VectorUnion; + + if (value == null) + { + return false; + } + + if (value.SwitchField != this.SwitchField) return false; + + switch (SwitchField) + { + default: { break; } + case VectorUnionFields.X: { if (!Utils.IsEqual(m_x, value.m_x)) return false; break; } + case VectorUnionFields.Y: { if (!Utils.IsEqual(m_y, value.m_y)) return false; break; } + case VectorUnionFields.Z: { if (!Utils.IsEqual(m_z, value.m_z)) return false; break; } + } + + return true; + } + + /// + public virtual object Clone() + { + return (VectorUnion)this.MemberwiseClone(); + } + + /// + public new object MemberwiseClone() + { + VectorUnion clone = (VectorUnion)base.MemberwiseClone(); + + clone.SwitchField = this.SwitchField; + + switch (SwitchField) + { + default: { break; } + case VectorUnionFields.X: { clone.m_x = (double)Utils.Clone(this.m_x); break; } + case VectorUnionFields.Y: { clone.m_y = (double)Utils.Clone(this.m_y); break; } + case VectorUnionFields.Z: { clone.m_z = (double)Utils.Clone(this.m_z); break; } + } + + return clone; + } + #endregion + + #region Private Fields + private double m_x; + private double m_y; + private double m_z; + #endregion + } + + #region VectorUnionCollection Class + /// + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Opc.Ua.ModelCompiler", "1.0.0.0")] + [CollectionDataContract(Name = "ListOfVectorUnion", Namespace = TestData.Namespaces.TestData, ItemName = "VectorUnion")] + public partial class VectorUnionCollection : List, ICloneable + { + #region Constructors + /// + public VectorUnionCollection() {} + + /// + public VectorUnionCollection(int capacity) : base(capacity) {} + + /// + public VectorUnionCollection(IEnumerable collection) : base(collection) {} + #endregion + + #region Static Operators + /// + public static implicit operator VectorUnionCollection(VectorUnion[] values) + { + if (values != null) + { + return new VectorUnionCollection(values); + } + + return new VectorUnionCollection(); + } + + /// + public static explicit operator VectorUnion[](VectorUnionCollection values) + { + if (values != null) + { + return values.ToArray(); + } + + return null; + } + #endregion + + #region ICloneable Methods + /// + public object Clone() + { + return (VectorUnionCollection)this.MemberwiseClone(); + } + #endregion + + /// + public new object MemberwiseClone() + { + VectorUnionCollection clone = new VectorUnionCollection(this.Count); + + for (int ii = 0; ii < this.Count; ii++) + { + clone.Add((VectorUnion)Utils.Clone(this[ii])); + } + + return clone; + } + } + #endregion + #endif + #endregion + + #region VectorWithOptionalFields Class + #if (!OPCUA_EXCLUDE_VectorWithOptionalFields) + /// + /// + + public enum VectorWithOptionalFieldsFields : uint + { + None = 0, + /// + X = 0x1, + /// + Y = 0x2, + /// + Z = 0x4 + } + + /// + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Opc.Ua.ModelCompiler", "1.0.0.0")] + [DataContract(Namespace = TestData.Namespaces.TestData)] + public partial class VectorWithOptionalFields : IEncodeable, IJsonEncodeable + { + #region Constructors + /// + public VectorWithOptionalFields() + { + Initialize(); + } + + [OnDeserializing] + private void Initialize(StreamingContext context) + { + Initialize(); + } + + private void Initialize() + { + EncodingMask = VectorWithOptionalFieldsFields.None; + m_x = (double)0; + m_y = (double)0; + m_z = (double)0; + } + #endregion + + #region Public Properties + // + [DataMember(Name = "EncodingMask", IsRequired = true, Order = 0)] + public VectorWithOptionalFieldsFields EncodingMask { get; set; } + + /// + [DataMember(Name = "X", IsRequired = false, Order = 1)] + public double X + { + get { return m_x; } + set { m_x = value; } + } + + /// + [DataMember(Name = "Y", IsRequired = false, Order = 2)] + public double Y + { + get { return m_y; } + set { m_y = value; } + } + + /// + [DataMember(Name = "Z", IsRequired = false, Order = 3)] + public double Z + { + get { return m_z; } + set { m_z = value; } + } + #endregion + + #region IEncodeable Members + /// + public virtual ExpandedNodeId TypeId => DataTypeIds.VectorWithOptionalFields; + + /// + public virtual ExpandedNodeId BinaryEncodingId => ObjectIds.VectorWithOptionalFields_Encoding_DefaultBinary; + + /// + public virtual ExpandedNodeId XmlEncodingId => ObjectIds.VectorWithOptionalFields_Encoding_DefaultXml; + + /// + public virtual ExpandedNodeId JsonEncodingId => ObjectIds.VectorWithOptionalFields_Encoding_DefaultJson; + + /// + public virtual void Encode(IEncoder encoder) + { + encoder.PushNamespace(TestData.Namespaces.TestData); + encoder.WriteUInt32(nameof(EncodingMask), (uint)EncodingMask); + + if ((EncodingMask & VectorWithOptionalFieldsFields.X) != 0) encoder.WriteDouble("X", X); + if ((EncodingMask & VectorWithOptionalFieldsFields.Y) != 0) encoder.WriteDouble("Y", Y); + if ((EncodingMask & VectorWithOptionalFieldsFields.Z) != 0) encoder.WriteDouble("Z", Z); + + encoder.PopNamespace(); + } + + /// + public virtual void Decode(IDecoder decoder) + { + decoder.PushNamespace(TestData.Namespaces.TestData); + + EncodingMask = (VectorWithOptionalFieldsFields)decoder.ReadUInt32(nameof(EncodingMask)); + + if ((EncodingMask & VectorWithOptionalFieldsFields.X) != 0) X = decoder.ReadDouble("X"); + if ((EncodingMask & VectorWithOptionalFieldsFields.Y) != 0) Y = decoder.ReadDouble("Y"); + if ((EncodingMask & VectorWithOptionalFieldsFields.Z) != 0) Z = decoder.ReadDouble("Z"); + + decoder.PopNamespace(); + } + + /// + public virtual bool IsEqual(IEncodeable encodeable) + { + if (Object.ReferenceEquals(this, encodeable)) + { + return true; + } + + VectorWithOptionalFields value = encodeable as VectorWithOptionalFields; + + if (value == null) + { + return false; + } + + if (value.EncodingMask != this.EncodingMask) return false; + + if ((EncodingMask & VectorWithOptionalFieldsFields.X) != 0) if (!Utils.IsEqual(m_x, value.m_x)) return false; + if ((EncodingMask & VectorWithOptionalFieldsFields.Y) != 0) if (!Utils.IsEqual(m_y, value.m_y)) return false; + if ((EncodingMask & VectorWithOptionalFieldsFields.Z) != 0) if (!Utils.IsEqual(m_z, value.m_z)) return false; + + return true; + } + + /// + public virtual object Clone() + { + return (VectorWithOptionalFields)this.MemberwiseClone(); + } + + /// + public new object MemberwiseClone() + { + VectorWithOptionalFields clone = (VectorWithOptionalFields)base.MemberwiseClone(); + + clone.EncodingMask = this.EncodingMask; + + if ((EncodingMask & VectorWithOptionalFieldsFields.X) != 0) clone.m_x = (double)Utils.Clone(this.m_x); + if ((EncodingMask & VectorWithOptionalFieldsFields.Y) != 0) clone.m_y = (double)Utils.Clone(this.m_y); + if ((EncodingMask & VectorWithOptionalFieldsFields.Z) != 0) clone.m_z = (double)Utils.Clone(this.m_z); + + return clone; + } + #endregion + + #region Private Fields + private double m_x; + private double m_y; + private double m_z; + #endregion + } + + #region VectorWithOptionalFieldsCollection Class + /// + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Opc.Ua.ModelCompiler", "1.0.0.0")] + [CollectionDataContract(Name = "ListOfVectorWithOptionalFields", Namespace = TestData.Namespaces.TestData, ItemName = "VectorWithOptionalFields")] + public partial class VectorWithOptionalFieldsCollection : List, ICloneable + { + #region Constructors + /// + public VectorWithOptionalFieldsCollection() {} + + /// + public VectorWithOptionalFieldsCollection(int capacity) : base(capacity) {} + + /// + public VectorWithOptionalFieldsCollection(IEnumerable collection) : base(collection) {} + #endregion + + #region Static Operators + /// + public static implicit operator VectorWithOptionalFieldsCollection(VectorWithOptionalFields[] values) + { + if (values != null) + { + return new VectorWithOptionalFieldsCollection(values); + } + + return new VectorWithOptionalFieldsCollection(); + } + + /// + public static explicit operator VectorWithOptionalFields[](VectorWithOptionalFieldsCollection values) + { + if (values != null) + { + return values.ToArray(); + } + + return null; + } + #endregion + + #region ICloneable Methods + /// + public object Clone() + { + return (VectorWithOptionalFieldsCollection)this.MemberwiseClone(); + } + #endregion + + /// + public new object MemberwiseClone() + { + VectorWithOptionalFieldsCollection clone = new VectorWithOptionalFieldsCollection(this.Count); + + for (int ii = 0; ii < this.Count; ii++) + { + clone.Add((VectorWithOptionalFields)Utils.Clone(this[ii])); + } + + return clone; + } + } + #endregion + #endif + #endregion + + #region MultipleVectors Class + #if (!OPCUA_EXCLUDE_MultipleVectors) + /// + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Opc.Ua.ModelCompiler", "1.0.0.0")] + [DataContract(Namespace = TestData.Namespaces.TestData)] + public partial class MultipleVectors : IEncodeable, IJsonEncodeable + { + #region Constructors + /// + public MultipleVectors() + { + Initialize(); + } + + [OnDeserializing] + private void Initialize(StreamingContext context) + { + Initialize(); + } + + private void Initialize() + { + m_vector = new Vector(); + m_vectorUnion = new VectorUnion(); + m_vectorWithOptionalFields = new VectorWithOptionalFields(); + m_vectorArray = new VectorCollection(); + m_vectorUnionArray = new VectorUnionCollection(); + m_vectorWithOptionalFieldsArray = new VectorWithOptionalFieldsCollection(); + } + #endregion + + #region Public Properties + /// + [DataMember(Name = "Vector", IsRequired = false, Order = 1)] + public Vector Vector + { + get + { + return m_vector; + } + + set + { + m_vector = value; + + if (value == null) + { + m_vector = new Vector(); + } + } + } + + /// + [DataMember(Name = "VectorUnion", IsRequired = false, Order = 2)] + public VectorUnion VectorUnion + { + get + { + return m_vectorUnion; + } + + set + { + m_vectorUnion = value; + + if (value == null) + { + m_vectorUnion = new VectorUnion(); + } + } + } + + /// + [DataMember(Name = "VectorWithOptionalFields", IsRequired = false, Order = 3)] + public VectorWithOptionalFields VectorWithOptionalFields + { + get + { + return m_vectorWithOptionalFields; + } + + set + { + m_vectorWithOptionalFields = value; + + if (value == null) + { + m_vectorWithOptionalFields = new VectorWithOptionalFields(); + } + } + } + + /// + [DataMember(Name = "VectorArray", IsRequired = false, Order = 4)] + public VectorCollection VectorArray + { + get + { + return m_vectorArray; + } + + set + { + m_vectorArray = value; + + if (value == null) + { + m_vectorArray = new VectorCollection(); + } + } + } + + /// + [DataMember(Name = "VectorUnionArray", IsRequired = false, Order = 5)] + public VectorUnionCollection VectorUnionArray + { + get + { + return m_vectorUnionArray; + } + + set + { + m_vectorUnionArray = value; + + if (value == null) + { + m_vectorUnionArray = new VectorUnionCollection(); + } + } + } + + /// + [DataMember(Name = "VectorWithOptionalFieldsArray", IsRequired = false, Order = 6)] + public VectorWithOptionalFieldsCollection VectorWithOptionalFieldsArray + { + get + { + return m_vectorWithOptionalFieldsArray; + } + + set + { + m_vectorWithOptionalFieldsArray = value; + + if (value == null) + { + m_vectorWithOptionalFieldsArray = new VectorWithOptionalFieldsCollection(); + } + } + } + #endregion + + #region IEncodeable Members + /// + public virtual ExpandedNodeId TypeId => DataTypeIds.MultipleVectors; + + /// + public virtual ExpandedNodeId BinaryEncodingId => ObjectIds.MultipleVectors_Encoding_DefaultBinary; + + /// + public virtual ExpandedNodeId XmlEncodingId => ObjectIds.MultipleVectors_Encoding_DefaultXml; + + /// + public virtual ExpandedNodeId JsonEncodingId => ObjectIds.MultipleVectors_Encoding_DefaultJson; + + /// + public virtual void Encode(IEncoder encoder) + { + encoder.PushNamespace(TestData.Namespaces.TestData); + + encoder.WriteEncodeable("Vector", Vector, typeof(Vector)); + encoder.WriteEncodeable("VectorUnion", VectorUnion, typeof(VectorUnion)); + encoder.WriteEncodeable("VectorWithOptionalFields", VectorWithOptionalFields, typeof(VectorWithOptionalFields)); + encoder.WriteEncodeableArray("VectorArray", VectorArray.ToArray(), typeof(Vector)); + encoder.WriteEncodeableArray("VectorUnionArray", VectorUnionArray.ToArray(), typeof(VectorUnion)); + encoder.WriteEncodeableArray("VectorWithOptionalFieldsArray", VectorWithOptionalFieldsArray.ToArray(), typeof(VectorWithOptionalFields)); + + encoder.PopNamespace(); + } + + /// + public virtual void Decode(IDecoder decoder) + { + decoder.PushNamespace(TestData.Namespaces.TestData); + + Vector = (Vector)decoder.ReadEncodeable("Vector", typeof(Vector)); + VectorUnion = (VectorUnion)decoder.ReadEncodeable("VectorUnion", typeof(VectorUnion)); + VectorWithOptionalFields = (VectorWithOptionalFields)decoder.ReadEncodeable("VectorWithOptionalFields", typeof(VectorWithOptionalFields)); + VectorArray = (VectorCollection)decoder.ReadEncodeableArray("VectorArray", typeof(Vector)); + VectorUnionArray = (VectorUnionCollection)decoder.ReadEncodeableArray("VectorUnionArray", typeof(VectorUnion)); + VectorWithOptionalFieldsArray = (VectorWithOptionalFieldsCollection)decoder.ReadEncodeableArray("VectorWithOptionalFieldsArray", typeof(VectorWithOptionalFields)); + + decoder.PopNamespace(); + } + + /// + public virtual bool IsEqual(IEncodeable encodeable) + { + if (Object.ReferenceEquals(this, encodeable)) + { + return true; + } + + MultipleVectors value = encodeable as MultipleVectors; + + if (value == null) + { + return false; + } + + if (!Utils.IsEqual(m_vector, value.m_vector)) return false; + if (!Utils.IsEqual(m_vectorUnion, value.m_vectorUnion)) return false; + if (!Utils.IsEqual(m_vectorWithOptionalFields, value.m_vectorWithOptionalFields)) return false; + if (!Utils.IsEqual(m_vectorArray, value.m_vectorArray)) return false; + if (!Utils.IsEqual(m_vectorUnionArray, value.m_vectorUnionArray)) return false; + if (!Utils.IsEqual(m_vectorWithOptionalFieldsArray, value.m_vectorWithOptionalFieldsArray)) return false; + + return true; + } + + /// + public virtual object Clone() + { + return (MultipleVectors)this.MemberwiseClone(); + } + + /// + public new object MemberwiseClone() + { + MultipleVectors clone = (MultipleVectors)base.MemberwiseClone(); + + clone.m_vector = (Vector)Utils.Clone(this.m_vector); + clone.m_vectorUnion = (VectorUnion)Utils.Clone(this.m_vectorUnion); + clone.m_vectorWithOptionalFields = (VectorWithOptionalFields)Utils.Clone(this.m_vectorWithOptionalFields); + clone.m_vectorArray = (VectorCollection)Utils.Clone(this.m_vectorArray); + clone.m_vectorUnionArray = (VectorUnionCollection)Utils.Clone(this.m_vectorUnionArray); + clone.m_vectorWithOptionalFieldsArray = (VectorWithOptionalFieldsCollection)Utils.Clone(this.m_vectorWithOptionalFieldsArray); + + return clone; + } + #endregion + + #region Private Fields + private Vector m_vector; + private VectorUnion m_vectorUnion; + private VectorWithOptionalFields m_vectorWithOptionalFields; + private VectorCollection m_vectorArray; + private VectorUnionCollection m_vectorUnionArray; + private VectorWithOptionalFieldsCollection m_vectorWithOptionalFieldsArray; + #endregion + } + + #region MultipleVectorsCollection Class + /// + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Opc.Ua.ModelCompiler", "1.0.0.0")] + [CollectionDataContract(Name = "ListOfMultipleVectors", Namespace = TestData.Namespaces.TestData, ItemName = "MultipleVectors")] + public partial class MultipleVectorsCollection : List, ICloneable + { + #region Constructors + /// + public MultipleVectorsCollection() {} + + /// + public MultipleVectorsCollection(int capacity) : base(capacity) {} + + /// + public MultipleVectorsCollection(IEnumerable collection) : base(collection) {} + #endregion + + #region Static Operators + /// + public static implicit operator MultipleVectorsCollection(MultipleVectors[] values) + { + if (values != null) + { + return new MultipleVectorsCollection(values); + } + + return new MultipleVectorsCollection(); + } + + /// + public static explicit operator MultipleVectors[](MultipleVectorsCollection values) + { + if (values != null) + { + return values.ToArray(); + } + + return null; + } + #endregion + + #region ICloneable Methods + /// + public object Clone() + { + return (MultipleVectorsCollection)this.MemberwiseClone(); + } + #endregion + + /// + public new object MemberwiseClone() + { + MultipleVectorsCollection clone = new MultipleVectorsCollection(this.Count); + + for (int ii = 0; ii < this.Count; ii++) + { + clone.Add((MultipleVectors)Utils.Clone(this[ii])); + } + + return clone; + } + } + #endregion + #endif + #endregion + #region WorkOrderStatusType Class #if (!OPCUA_EXCLUDE_WorkOrderStatusType) /// diff --git a/Applications/Quickstarts.Servers/TestData/TestData.NodeIds.csv b/Applications/Quickstarts.Servers/TestData/TestData.NodeIds.csv index 0f3adf628..64b174251 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.NodeIds.csv +++ b/Applications/Quickstarts.Servers/TestData/TestData.NodeIds.csv @@ -1292,3 +1292,39 @@ UserArrayValueDataType_Encoding_DefaultJson,3578,Object Vector_Encoding_DefaultJson,3579,Object WorkOrderStatusType_Encoding_DefaultJson,3580,Object WorkOrderType_Encoding_DefaultJson,3581,Object +ScalarValueObjectType_VectorUnionValue,3582,Variable +ScalarValueObjectType_VectorWithOptionalFieldsValue,3583,Variable +VectorUnion,3584,DataType +VectorWithOptionalFields,3585,DataType +Data_Static_Scalar_VectorUnionValue,3586,Variable +Data_Static_Scalar_VectorWithOptionalFieldsValue,3587,Variable +Data_Dynamic_Scalar_VectorUnionValue,3588,Variable +Data_Dynamic_Scalar_VectorWithOptionalFieldsValue,3589,Variable +VectorUnion_Encoding_DefaultBinary,3590,Object +VectorWithOptionalFields_Encoding_DefaultBinary,3591,Object +TestData_BinarySchema_VectorUnion,3592,Variable +TestData_BinarySchema_VectorWithOptionalFields,3595,Variable +VectorUnion_Encoding_DefaultXml,3598,Object +VectorWithOptionalFields_Encoding_DefaultXml,3599,Object +TestData_XmlSchema_VectorUnion,3600,Variable +TestData_XmlSchema_VectorWithOptionalFields,3603,Variable +VectorUnion_Encoding_DefaultJson,3606,Object +VectorWithOptionalFields_Encoding_DefaultJson,3607,Object +ArrayValueObjectType_VectorUnionValue,3608,Variable +ArrayValueObjectType_VectorWithOptionalFieldsValue,3609,Variable +Data_Static_Array_VectorUnionValue,3610,Variable +Data_Static_Array_VectorWithOptionalFieldsValue,3611,Variable +Data_Dynamic_Array_VectorUnionValue,3612,Variable +Data_Dynamic_Array_VectorWithOptionalFieldsValue,3613,Variable +ScalarValueObjectType_MultipleVectorsValue,3614,Variable +MultipleVectors,3615,DataType +Data_Static_Scalar_MultipleVectorsValue,3616,Variable +Data_Dynamic_Scalar_MultipleVectorsValue,3617,Variable +MultipleVectors_Encoding_DefaultBinary,3618,Object +TestData_BinarySchema_MultipleVectors,3619,Variable +MultipleVectors_Encoding_DefaultXml,3622,Object +TestData_XmlSchema_MultipleVectors,3623,Variable +MultipleVectors_Encoding_DefaultJson,3626,Object +ArrayValueObjectType_MultipleVectorsValue,3627,Variable +Data_Static_Array_MultipleVectorsValue,3628,Variable +Data_Dynamic_Array_MultipleVectorsValue,3629,Variable diff --git a/Applications/Quickstarts.Servers/TestData/TestData.NodeSet.xml b/Applications/Quickstarts.Servers/TestData/TestData.NodeSet.xml index fae32aed9..ffaadd61a 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.NodeSet.xml +++ b/Applications/Quickstarts.Servers/TestData/TestData.NodeSet.xml @@ -5167,6 +5167,33 @@ ns=1;i=1206 + + + i=47 + + false + + ns=1;i=3582 + + + + + i=47 + + false + + ns=1;i=3583 + + + + + i=47 + + false + + ns=1;i=3614 + + false @@ -11840,6 +11867,33 @@ ns=1;i=1546 + + + i=47 + + false + + ns=1;i=3608 + + + + + i=47 + + false + + ns=1;i=3609 + + + + + i=47 + + false + + ns=1;i=3627 + + false @@ -25935,6 +25989,33 @@ ns=1;i=2066 + + + i=47 + + false + + ns=1;i=3586 + + + + + i=47 + + false + + ns=1;i=3587 + + + + + i=47 + + false + + ns=1;i=3616 + + 0 @@ -34568,6 +34649,33 @@ ns=1;i=2255 + + + i=47 + + false + + ns=1;i=3610 + + + + + i=47 + + false + + ns=1;i=3611 + + + + + i=47 + + false + + ns=1;i=3628 + + 0 @@ -58945,6 +59053,33 @@ ns=1;i=2830 + + + i=47 + + false + + ns=1;i=3588 + + + + + i=47 + + false + + ns=1;i=3589 + + + + + i=47 + + false + + ns=1;i=3617 + + 0 @@ -67578,6 +67713,33 @@ ns=1;i=3019 + + + i=47 + + false + + ns=1;i=3612 + + + + + i=47 + + false + + ns=1;i=3613 + + + + + i=47 + + false + + ns=1;i=3629 + + 0 @@ -89042,6 +89204,33 @@ ns=1;i=3534 + + + i=47 + + false + + ns=1;i=3592 + + + + + i=47 + + false + + ns=1;i=3595 + + + + + i=47 + + false + + ns=1;i=3619 + + i=47 @@ -89302,20 +89491,44 @@ IE5hbWU9IlZlY3RvciIgQmFzZVR5cGU9InVhOkV4dGVuc2lvbk9iamVjdCI+DQogICAgPG9wYzpG aWVsZCBOYW1lPSJYIiBUeXBlTmFtZT0ib3BjOkRvdWJsZSIgLz4NCiAgICA8b3BjOkZpZWxkIE5h bWU9IlkiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iWiIg VHlwZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQogIDxv -cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgQmFzZVR5cGU9InVh -OkV4dGVuc2lvbk9iamVjdCI+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJBY3RvciIgVHlwZU5hbWU9 -Im9wYzpTdHJpbmciIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJUaW1lc3RhbXAiIFR5cGVOYW1l -PSJvcGM6RGF0ZVRpbWUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJDb21tZW50IiBUeXBlTmFt -ZT0idWE6TG9jYWxpemVkVGV4dCIgLz4NCiAgPC9vcGM6U3RydWN0dXJlZFR5cGU+DQoNCiAgPG9w -YzpTdHJ1Y3R1cmVkVHlwZSBOYW1lPSJXb3JrT3JkZXJUeXBlIiBCYXNlVHlwZT0idWE6RXh0ZW5z -aW9uT2JqZWN0Ij4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IklEIiBUeXBlTmFtZT0ib3BjOkd1aWQi -IC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJBc3NldElEIiBUeXBlTmFtZT0ib3BjOlN0cmluZyIg -Lz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlN0YXJ0VGltZSIgVHlwZU5hbWU9Im9wYzpEYXRlVGlt -ZSIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9Ik5vT2ZTdGF0dXNDb21tZW50cyIgVHlwZU5hbWU9 -Im9wYzpJbnQzMiIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlN0YXR1c0NvbW1lbnRzIiBUeXBl -TmFtZT0idG5zOldvcmtPcmRlclN0YXR1c1R5cGUiIExlbmd0aEZpZWxkPSJOb09mU3RhdHVzQ29t -bWVudHMiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQo8L29wYzpUeXBlRGljdGlvbmFy -eT4= +cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iVmVjdG9yVW5pb24iIEJhc2VUeXBlPSJ1YTpVbmlvbiI+ +DQogICAgPG9wYzpGaWVsZCBOYW1lPSJYIiBUeXBlTmFtZT0ib3BjOkRvdWJsZSIgLz4NCiAgICA8 +b3BjOkZpZWxkIE5hbWU9IlkiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6Rmll +bGQgTmFtZT0iWiIgVHlwZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRU +eXBlPg0KDQogIDxvcGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmll +bGRzIiBCYXNlVHlwZT0idWE6RXh0ZW5zaW9uT2JqZWN0Ij4NCiAgICA8b3BjOkZpZWxkIE5hbWU9 +IlgiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iWSIgVHlw +ZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJaIiBUeXBlTmFtZT0i +b3BjOkRvdWJsZSIgLz4NCiAgPC9vcGM6U3RydWN0dXJlZFR5cGU+DQoNCiAgPG9wYzpTdHJ1Y3R1 +cmVkVHlwZSBOYW1lPSJNdWx0aXBsZVZlY3RvcnMiIEJhc2VUeXBlPSJ1YTpFeHRlbnNpb25PYmpl +Y3QiPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yIiBUeXBlTmFtZT0idG5zOlZlY3RvciIg +Lz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlZlY3RvclVuaW9uIiBUeXBlTmFtZT0idG5zOlZlY3Rv +clVuaW9uIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRz +IiBUeXBlTmFtZT0idG5zOlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyIgLz4NCiAgICA8b3BjOkZp +ZWxkIE5hbWU9Ik5vT2ZWZWN0b3JBcnJheSIgVHlwZU5hbWU9Im9wYzpJbnQzMiIgLz4NCiAgICA8 +b3BjOkZpZWxkIE5hbWU9IlZlY3RvckFycmF5IiBUeXBlTmFtZT0idG5zOlZlY3RvciIgTGVuZ3Ro +RmllbGQ9Ik5vT2ZWZWN0b3JBcnJheSIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9Ik5vT2ZWZWN0 +b3JVbmlvbkFycmF5IiBUeXBlTmFtZT0ib3BjOkludDMyIiAvPg0KICAgIDxvcGM6RmllbGQgTmFt +ZT0iVmVjdG9yVW5pb25BcnJheSIgVHlwZU5hbWU9InRuczpWZWN0b3JVbmlvbiIgTGVuZ3RoRmll +bGQ9Ik5vT2ZWZWN0b3JVbmlvbkFycmF5IiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iTm9PZlZl +Y3RvcldpdGhPcHRpb25hbEZpZWxkc0FycmF5IiBUeXBlTmFtZT0ib3BjOkludDMyIiAvPg0KICAg +IDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzQXJyYXkiIFR5cGVOYW1l +PSJ0bnM6VmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzIiBMZW5ndGhGaWVsZD0iTm9PZlZlY3Rvcldp +dGhPcHRpb25hbEZpZWxkc0FycmF5IiAvPg0KICA8L29wYzpTdHJ1Y3R1cmVkVHlwZT4NCg0KICA8 +b3BjOlN0cnVjdHVyZWRUeXBlIE5hbWU9IldvcmtPcmRlclN0YXR1c1R5cGUiIEJhc2VUeXBlPSJ1 +YTpFeHRlbnNpb25PYmplY3QiPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQWN0b3IiIFR5cGVOYW1l +PSJvcGM6U3RyaW5nIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVGltZXN0YW1wIiBUeXBlTmFt +ZT0ib3BjOkRhdGVUaW1lIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQ29tbWVudCIgVHlwZU5h +bWU9InVhOkxvY2FsaXplZFRleHQiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQogIDxv +cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iV29ya09yZGVyVHlwZSIgQmFzZVR5cGU9InVhOkV4dGVu +c2lvbk9iamVjdCI+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJJRCIgVHlwZU5hbWU9Im9wYzpHdWlk +IiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQXNzZXRJRCIgVHlwZU5hbWU9Im9wYzpTdHJpbmci +IC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJTdGFydFRpbWUiIFR5cGVOYW1lPSJvcGM6RGF0ZVRp +bWUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJOb09mU3RhdHVzQ29tbWVudHMiIFR5cGVOYW1l +PSJvcGM6SW50MzIiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJTdGF0dXNDb21tZW50cyIgVHlw +ZU5hbWU9InRuczpXb3JrT3JkZXJTdGF0dXNUeXBlIiBMZW5ndGhGaWVsZD0iTm9PZlN0YXR1c0Nv +bW1lbnRzIiAvPg0KICA8L29wYzpTdHJ1Y3R1cmVkVHlwZT4NCg0KPC9vcGM6VHlwZURpY3Rpb25h +cnk+ @@ -90275,6 +90488,33 @@ eT4= ns=1;i=3566 + + + i=47 + + false + + ns=1;i=3600 + + + + + i=47 + + false + + ns=1;i=3603 + + + + + i=47 + + false + + ns=1;i=3623 + + i=47 @@ -90302,7 +90542,7 @@ c2QiDQogIHhtbG5zOnRucz0iaHR0cDovL3Rlc3Qub3JnL1VBL0RhdGEvIg0KICB0YXJnZXROYW1l c3BhY2U9Imh0dHA6Ly90ZXN0Lm9yZy9VQS9EYXRhLyINCiAgZWxlbWVudEZvcm1EZWZhdWx0PSJx dWFsaWZpZWQiDQo+DQogIDx4czphbm5vdGF0aW9uPg0KICAgIDx4czphcHBpbmZvPg0KICAgICAg PHVhOk1vZGVsIE1vZGVsVXJpPSJodHRwOi8vdGVzdC5vcmcvVUEvRGF0YS8iIFZlcnNpb249IjEu -MC4wIiBQdWJsaWNhdGlvbkRhdGU9IjIwMjMtMDYtMDZUMDY6MzM6NTEuNTc2OTYyOVoiIC8+DQog +MC4wIiBQdWJsaWNhdGlvbkRhdGU9IjIwMjMtMTAtMDlUMDg6NTE6MjQuNTIzNzA4OFoiIC8+DQog ICAgPC94czphcHBpbmZvPg0KICA8L3hzOmFubm90YXRpb24+DQogIA0KICA8eHM6aW1wb3J0IG5h bWVzcGFjZT0iaHR0cDovL29wY2ZvdW5kYXRpb24ub3JnL1VBLzIwMDgvMDIvVHlwZXMueHNkIiAv Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJTY2FsYXJTdHJ1Y3R1cmVEYXRhVHlwZSI+DQog @@ -90541,35 +90781,82 @@ YW1lPSJWZWN0b3IiIHR5cGU9InRuczpWZWN0b3IiIG1pbk9jY3Vycz0iMCIgbWF4T2NjdXJzPSJ1 bmJvdW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6 Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZlZlY3RvciIgdHlwZT0idG5z Okxpc3RPZlZlY3RvciIgbmlsbGFibGU9InRydWUiPjwveHM6ZWxlbWVudD4NCg0KICA8eHM6Y29t -cGxleFR5cGUgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0K -ICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQWN0b3IiIHR5cGU9InhzOnN0cmluZyIgbWluT2NjdXJz -PSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlRpbWVzdGFt -cCIgdHlwZT0ieHM6ZGF0ZVRpbWUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4czplbGVtZW50 -IG5hbWU9IkNvbW1lbnQiIHR5cGU9InVhOkxvY2FsaXplZFRleHQiIG1pbk9jY3Vycz0iMCIgbmls -bGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4VHlwZT4N -CiAgPHhzOmVsZW1lbnQgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgdHlwZT0idG5zOldvcmtP -cmRlclN0YXR1c1R5cGUiIC8+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RPZldvcmtP -cmRlclN0YXR1c1R5cGUiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4czplbGVtZW50IG5h -bWU9IldvcmtPcmRlclN0YXR1c1R5cGUiIHR5cGU9InRuczpXb3JrT3JkZXJTdGF0dXNUeXBlIiBt -aW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAg -ICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1l -PSJMaXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiB0eXBlPSJ0bnM6TGlzdE9mV29ya09yZGVyU3Rh -dHVzVHlwZSIgbmlsbGFibGU9InRydWUiPjwveHM6ZWxlbWVudD4NCg0KICA8eHM6Y29tcGxleFR5 -cGUgbmFtZT0iV29ya09yZGVyVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVs -ZW1lbnQgbmFtZT0iSUQiIHR5cGU9InVhOkd1aWQiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4 -czplbGVtZW50IG5hbWU9IkFzc2V0SUQiIHR5cGU9InhzOnN0cmluZyIgbWluT2NjdXJzPSIwIiBu -aWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlN0YXJ0VGltZSIgdHlw -ZT0ieHM6ZGF0ZVRpbWUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9 -IlN0YXR1c0NvbW1lbnRzIiB0eXBlPSJ0bnM6TGlzdE9mV29ya09yZGVyU3RhdHVzVHlwZSIgbWlu -T2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hz -OmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3JkZXJUeXBlIiB0eXBlPSJ0 -bnM6V29ya09yZGVyVHlwZSIgLz4NCg0KICA8eHM6Y29tcGxleFR5cGUgbmFtZT0iTGlzdE9mV29y -a09yZGVyVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0i -V29ya09yZGVyVHlwZSIgdHlwZT0idG5zOldvcmtPcmRlclR5cGUiIG1pbk9jY3Vycz0iMCIgbWF4 -T2NjdXJzPSJ1bmJvdW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+ -DQogIDwveHM6Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZldvcmtPcmRl -clR5cGUiIHR5cGU9InRuczpMaXN0T2ZXb3JrT3JkZXJUeXBlIiBuaWxsYWJsZT0idHJ1ZSI+PC94 -czplbGVtZW50Pg0KDQo8L3hzOnNjaGVtYT4= +cGxleFR5cGUgbmFtZT0iVmVjdG9yVW5pb24iPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4 +czplbGVtZW50IG5hbWU9IlN3aXRjaEZpZWxkIiB0eXBlPSJ4czp1bnNpZ25lZEludCIgbWluT2Nj +dXJzPSIwIiAvPg0KICAgICAgPHhzOmNob2ljZT4NCiAgICAgICAgPHhzOmVsZW1lbnQgbmFtZT0i +WCIgdHlwZT0ieHM6ZG91YmxlIiBtaW5PY2N1cnM9IjAiIC8+DQogICAgICAgIDx4czplbGVtZW50 +IG5hbWU9IlkiIHR5cGU9InhzOmRvdWJsZSIgbWluT2NjdXJzPSIwIiAvPg0KICAgICAgICA8eHM6 +ZWxlbWVudCBuYW1lPSJaIiB0eXBlPSJ4czpkb3VibGUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAg +IDwveHM6Y2hvaWNlPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29tcGxleFR5cGU+DQog +IDx4czplbGVtZW50IG5hbWU9IlZlY3RvclVuaW9uIiB0eXBlPSJ0bnM6VmVjdG9yVW5pb24iIC8+ +DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RPZlZlY3RvclVuaW9uIj4NCiAgICA8eHM6 +c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJWZWN0b3JVbmlvbiIgdHlwZT0idG5z +OlZlY3RvclVuaW9uIiBtaW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBuaWxsYWJs +ZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8 +eHM6ZWxlbWVudCBuYW1lPSJMaXN0T2ZWZWN0b3JVbmlvbiIgdHlwZT0idG5zOkxpc3RPZlZlY3Rv +clVuaW9uIiBuaWxsYWJsZT0idHJ1ZSI+PC94czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlw +ZSBuYW1lPSJWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAg +ICAgIDx4czplbGVtZW50IG5hbWU9IlgiIHR5cGU9InhzOmRvdWJsZSIgbWluT2NjdXJzPSIwIiAv +Pg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iWSIgdHlwZT0ieHM6ZG91YmxlIiBtaW5PY2N1cnM9 +IjAiIC8+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJaIiB0eXBlPSJ4czpkb3VibGUiIG1pbk9j +Y3Vycz0iMCIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8 +eHM6ZWxlbWVudCBuYW1lPSJWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIHR5cGU9InRuczpWZWN0 +b3JXaXRoT3B0aW9uYWxGaWVsZHMiIC8+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RP +ZlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzIiB0eXBlPSJ0bnM6VmVjdG9y +V2l0aE9wdGlvbmFsRmllbGRzIiBtaW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBu +aWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBl +Pg0KICA8eHM6ZWxlbWVudCBuYW1lPSJMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIHR5 +cGU9InRuczpMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIG5pbGxhYmxlPSJ0cnVlIj48 +L3hzOmVsZW1lbnQ+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ik11bHRpcGxlVmVjdG9ycyI+ +DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yIiB0eXBl +PSJ0bnM6VmVjdG9yIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iVmVjdG9yVW5pb24iIHR5cGU9InRuczpWZWN0b3JVbmlvbiIgbWluT2Nj +dXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlZlY3Rv +cldpdGhPcHRpb25hbEZpZWxkcyIgdHlwZT0idG5zOlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyIg +bWluT2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9 +IlZlY3RvckFycmF5IiB0eXBlPSJ0bnM6TGlzdE9mVmVjdG9yIiBtaW5PY2N1cnM9IjAiIG5pbGxh +YmxlPSJ0cnVlIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yVW5pb25BcnJheSIg +dHlwZT0idG5zOkxpc3RPZlZlY3RvclVuaW9uIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVl +IiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzQXJy +YXkiIHR5cGU9InRuczpMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIG1pbk9jY3Vycz0i +MCIgbmlsbGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4 +VHlwZT4NCiAgPHhzOmVsZW1lbnQgbmFtZT0iTXVsdGlwbGVWZWN0b3JzIiB0eXBlPSJ0bnM6TXVs +dGlwbGVWZWN0b3JzIiAvPg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJMaXN0T2ZNdWx0aXBs +ZVZlY3RvcnMiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9Ik11 +bHRpcGxlVmVjdG9ycyIgdHlwZT0idG5zOk11bHRpcGxlVmVjdG9ycyIgbWluT2NjdXJzPSIwIiBt +YXhPY2N1cnM9InVuYm91bmRlZCIgbmlsbGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5j +ZT4NCiAgPC94czpjb21wbGV4VHlwZT4NCiAgPHhzOmVsZW1lbnQgbmFtZT0iTGlzdE9mTXVsdGlw +bGVWZWN0b3JzIiB0eXBlPSJ0bnM6TGlzdE9mTXVsdGlwbGVWZWN0b3JzIiBuaWxsYWJsZT0idHJ1 +ZSI+PC94czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJXb3JrT3JkZXJTdGF0 +dXNUeXBlIj4NCiAgICA8eHM6c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJBY3Rv +ciIgdHlwZT0ieHM6c3RyaW5nIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAg +ICAgPHhzOmVsZW1lbnQgbmFtZT0iVGltZXN0YW1wIiB0eXBlPSJ4czpkYXRlVGltZSIgbWluT2Nj +dXJzPSIwIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQ29tbWVudCIgdHlwZT0idWE6TG9j +YWxpemVkVGV4dCIgbWluT2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNl +cXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3Jk +ZXJTdGF0dXNUeXBlIiB0eXBlPSJ0bnM6V29ya09yZGVyU3RhdHVzVHlwZSIgLz4NCg0KICA8eHM6 +Y29tcGxleFR5cGUgbmFtZT0iTGlzdE9mV29ya09yZGVyU3RhdHVzVHlwZSI+DQogICAgPHhzOnNl +cXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgdHlw +ZT0idG5zOldvcmtPcmRlclN0YXR1c1R5cGUiIG1pbk9jY3Vycz0iMCIgbWF4T2NjdXJzPSJ1bmJv +dW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29t +cGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZldvcmtPcmRlclN0YXR1c1R5cGUi +IHR5cGU9InRuczpMaXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiBuaWxsYWJsZT0idHJ1ZSI+PC94 +czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJXb3JrT3JkZXJUeXBlIj4NCiAg +ICA8eHM6c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJJRCIgdHlwZT0idWE6R3Vp +ZCIgbWluT2NjdXJzPSIwIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQXNzZXRJRCIgdHlw +ZT0ieHM6c3RyaW5nIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iU3RhcnRUaW1lIiB0eXBlPSJ4czpkYXRlVGltZSIgbWluT2NjdXJzPSIw +IiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iU3RhdHVzQ29tbWVudHMiIHR5cGU9InRuczpM +aXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAv +Pg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50 +IG5hbWU9IldvcmtPcmRlclR5cGUiIHR5cGU9InRuczpXb3JrT3JkZXJUeXBlIiAvPg0KDQogIDx4 +czpjb21wbGV4VHlwZSBuYW1lPSJMaXN0T2ZXb3JrT3JkZXJUeXBlIj4NCiAgICA8eHM6c2VxdWVu +Y2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3JkZXJUeXBlIiB0eXBlPSJ0bnM6V29y +a09yZGVyVHlwZSIgbWluT2NjdXJzPSIwIiBtYXhPY2N1cnM9InVuYm91bmRlZCIgbmlsbGFibGU9 +InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4VHlwZT4NCiAgPHhz +OmVsZW1lbnQgbmFtZT0iTGlzdE9mV29ya09yZGVyVHlwZSIgdHlwZT0idG5zOkxpc3RPZldvcmtP +cmRlclR5cGUiIG5pbGxhYmxlPSJ0cnVlIj48L3hzOmVsZW1lbnQ+DQoNCjwveHM6c2NoZW1hPg== @@ -91365,5 +91652,2000 @@ czplbGVtZW50Pg0KDQo8L3hzOnNjaGVtYT4= 0 + + + ns=1;i=3582 + + Variable_2 + + 1 + VectorUnionValue + + + + VectorUnionValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1116 + + + + + i=40 + + false + + i=63 + + + + + i=37 + + false + + i=78 + + + + + + + + + + ns=1;i=3584 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3583 + + Variable_2 + + 1 + VectorWithOptionalFieldsValue + + + + VectorWithOptionalFieldsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1116 + + + + + i=40 + + false + + i=63 + + + + + i=37 + + false + + i=78 + + + + + + + + + + ns=1;i=3585 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3584 + + DataType_64 + + 1 + VectorUnion + + + + VectorUnion + + + 0 + 0 + + + 0 + + + + i=45 + + true + + i=12756 + + + + + i=38 + + false + + ns=1;i=3590 + + + + + i=38 + + false + + ns=1;i=3598 + + + + + i=38 + + false + + ns=1;i=3606 + + + + false + + + + + ns=1;i=3585 + + DataType_64 + + 1 + VectorWithOptionalFields + + + + VectorWithOptionalFields + + + 0 + 0 + + + 0 + + + + i=45 + + true + + i=22 + + + + + i=38 + + false + + ns=1;i=3591 + + + + + i=38 + + false + + ns=1;i=3599 + + + + + i=38 + + false + + ns=1;i=3607 + + + + false + + + + + ns=1;i=3586 + + Variable_2 + + 1 + VectorUnionValue + + + + VectorUnionValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1976 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3584 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3587 + + Variable_2 + + 1 + VectorWithOptionalFieldsValue + + + + VectorWithOptionalFieldsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1976 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3585 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3588 + + Variable_2 + + 1 + VectorUnionValue + + + + VectorUnionValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2740 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3584 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3589 + + Variable_2 + + 1 + VectorWithOptionalFieldsValue + + + + VectorWithOptionalFieldsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2740 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3585 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3590 + + Object_1 + + 0 + Default Binary + + + + Default Binary + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3584 + + + + + i=39 + + false + + ns=1;i=3592 + + + + 0 + + + + ns=1;i=3591 + + Object_1 + + 0 + Default Binary + + + + Default Binary + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3585 + + + + + i=39 + + false + + ns=1;i=3595 + + + + 0 + + + + ns=1;i=3592 + + Variable_2 + + 1 + VectorUnion + + + + VectorUnion + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=3518 + + + + + i=40 + + false + + i=69 + + + + + + VectorUnion + + + + i=12 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3595 + + Variable_2 + + 1 + VectorWithOptionalFields + + + + VectorWithOptionalFields + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=3518 + + + + + i=40 + + false + + i=69 + + + + + + VectorWithOptionalFields + + + + i=12 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3598 + + Object_1 + + 0 + Default XML + + + + Default XML + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3584 + + + + + i=39 + + false + + ns=1;i=3600 + + + + 0 + + + + ns=1;i=3599 + + Object_1 + + 0 + Default XML + + + + Default XML + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3585 + + + + + i=39 + + false + + ns=1;i=3603 + + + + 0 + + + + ns=1;i=3600 + + Variable_2 + + 1 + VectorUnion + + + + VectorUnion + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=3550 + + + + + i=40 + + false + + i=69 + + + + + + //xs:element[@name='VectorUnion'] + + + + i=12 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3603 + + Variable_2 + + 1 + VectorWithOptionalFields + + + + VectorWithOptionalFields + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=3550 + + + + + i=40 + + false + + i=69 + + + + + + //xs:element[@name='VectorWithOptionalFields'] + + + + i=12 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3606 + + Object_1 + + 0 + Default JSON + + + + Default JSON + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3584 + + + + 0 + + + + ns=1;i=3607 + + Object_1 + + 0 + Default JSON + + + + Default JSON + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3585 + + + + 0 + + + + ns=1;i=3608 + + Variable_2 + + 1 + VectorUnionValue + + + + VectorUnionValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1456 + + + + + i=40 + + false + + i=63 + + + + + i=37 + + false + + i=78 + + + + + + + + + + ns=1;i=3584 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3609 + + Variable_2 + + 1 + VectorWithOptionalFieldsValue + + + + VectorWithOptionalFieldsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1456 + + + + + i=40 + + false + + i=63 + + + + + i=37 + + false + + i=78 + + + + + + + + + + ns=1;i=3585 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3610 + + Variable_2 + + 1 + VectorUnionValue + + + + VectorUnionValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2165 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3584 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3611 + + Variable_2 + + 1 + VectorWithOptionalFieldsValue + + + + VectorWithOptionalFieldsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2165 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3585 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3612 + + Variable_2 + + 1 + VectorUnionValue + + + + VectorUnionValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2929 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3584 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3613 + + Variable_2 + + 1 + VectorWithOptionalFieldsValue + + + + VectorWithOptionalFieldsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2929 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3585 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3614 + + Variable_2 + + 1 + MultipleVectorsValue + + + + MultipleVectorsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1116 + + + + + i=40 + + false + + i=63 + + + + + i=37 + + false + + i=78 + + + + + + + + + + ns=1;i=3615 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3615 + + DataType_64 + + 1 + MultipleVectors + + + + MultipleVectors + + + 0 + 0 + + + 0 + + + + i=45 + + true + + i=22 + + + + + i=38 + + false + + ns=1;i=3618 + + + + + i=38 + + false + + ns=1;i=3622 + + + + + i=38 + + false + + ns=1;i=3626 + + + + false + + + + + ns=1;i=3616 + + Variable_2 + + 1 + MultipleVectorsValue + + + + MultipleVectorsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1976 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3615 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3617 + + Variable_2 + + 1 + MultipleVectorsValue + + + + MultipleVectorsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2740 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3615 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3618 + + Object_1 + + 0 + Default Binary + + + + Default Binary + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3615 + + + + + i=39 + + false + + ns=1;i=3619 + + + + 0 + + + + ns=1;i=3619 + + Variable_2 + + 1 + MultipleVectors + + + + MultipleVectors + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=3518 + + + + + i=40 + + false + + i=69 + + + + + + MultipleVectors + + + + i=12 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3622 + + Object_1 + + 0 + Default XML + + + + Default XML + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3615 + + + + + i=39 + + false + + ns=1;i=3623 + + + + 0 + + + + ns=1;i=3623 + + Variable_2 + + 1 + MultipleVectors + + + + MultipleVectors + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=3550 + + + + + i=40 + + false + + i=69 + + + + + + //xs:element[@name='MultipleVectors'] + + + + i=12 + + -1 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3626 + + Object_1 + + 0 + Default JSON + + + + Default JSON + + + 0 + 0 + + + 0 + + + + i=40 + + false + + i=76 + + + + + i=38 + + true + + ns=1;i=3615 + + + + 0 + + + + ns=1;i=3627 + + Variable_2 + + 1 + MultipleVectorsValue + + + + MultipleVectorsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=1456 + + + + + i=40 + + false + + i=63 + + + + + i=37 + + false + + i=78 + + + + + + + + + + ns=1;i=3615 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3628 + + Variable_2 + + 1 + MultipleVectorsValue + + + + MultipleVectorsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2165 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3615 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + + + + ns=1;i=3629 + + Variable_2 + + 1 + MultipleVectorsValue + + + + MultipleVectorsValue + + + 0 + 0 + + + 0 + + + + i=47 + + true + + ns=1;i=2929 + + + + + i=40 + + false + + i=63 + + + + + + + + + + ns=1;i=3615 + + 1 + + 0 + + 1 + 1 + 0 + false + 0 + \ No newline at end of file diff --git a/Applications/Quickstarts.Servers/TestData/TestData.NodeSet2.xml b/Applications/Quickstarts.Servers/TestData/TestData.NodeSet2.xml index dca13f191..cf9e37126 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.NodeSet2.xml +++ b/Applications/Quickstarts.Servers/TestData/TestData.NodeSet2.xml @@ -1,10 +1,10 @@  - + http://test.org/UA/Data/ - + @@ -811,6 +811,9 @@ ns=1;i=1204 ns=1;i=1205 ns=1;i=1206 + ns=1;i=3582 + ns=1;i=3583 + ns=1;i=3614 ns=1;i=1015 @@ -1065,6 +1068,30 @@ ns=1;i=1206 + + VectorUnionValue + + i=63 + i=78 + ns=1;i=1116 + + + + VectorWithOptionalFieldsValue + + i=63 + i=78 + ns=1;i=1116 + + + + MultipleVectorsValue + + i=63 + i=78 + ns=1;i=1116 + + StructureValueObjectType @@ -1665,6 +1692,9 @@ ns=1;i=1544 ns=1;i=1545 ns=1;i=1546 + ns=1;i=3608 + ns=1;i=3609 + ns=1;i=3627 ns=1;i=1015 @@ -1892,6 +1922,30 @@ ns=1;i=1456 + + VectorUnionValue + + i=63 + i=78 + ns=1;i=1456 + + + + VectorWithOptionalFieldsValue + + i=63 + i=78 + ns=1;i=1456 + + + + MultipleVectorsValue + + i=63 + i=78 + ns=1;i=1456 + + AnalogArrayValueObjectType @@ -2776,6 +2830,42 @@ ns=1;i=1889 + + VectorUnion + + i=12756 + + + + + + + + + VectorWithOptionalFields + + i=22 + + + + + + + + + MultipleVectors + + i=22 + + + + + + + + + + WorkOrderStatusType @@ -6169,6 +6259,9 @@ ns=1;i=2064 ns=1;i=2065 ns=1;i=2066 + ns=1;i=3586 + ns=1;i=3587 + ns=1;i=3616 ns=1;i=1975 ns=1;i=1980 ns=1;i=1116 @@ -6770,6 +6863,27 @@ ns=1;i=2066 + + VectorUnionValue + + i=63 + ns=1;i=1976 + + + + VectorWithOptionalFieldsValue + + i=63 + ns=1;i=1976 + + + + MultipleVectorsValue + + i=63 + ns=1;i=1976 + + Structure @@ -7446,6 +7560,9 @@ ns=1;i=2253 ns=1;i=2254 ns=1;i=2255 + ns=1;i=3610 + ns=1;i=3611 + ns=1;i=3628 ns=1;i=1975 ns=1;i=2169 ns=1;i=1456 @@ -8023,6 +8140,27 @@ ns=1;i=2165 + + VectorUnionValue + + i=63 + ns=1;i=2165 + + + + VectorWithOptionalFieldsValue + + i=63 + ns=1;i=2165 + + + + MultipleVectorsValue + + i=63 + ns=1;i=2165 + + UserScalar @@ -13647,6 +13785,9 @@ ns=1;i=2828 ns=1;i=2829 ns=1;i=2830 + ns=1;i=3588 + ns=1;i=3589 + ns=1;i=3617 ns=1;i=2739 ns=1;i=2744 ns=1;i=1116 @@ -14251,6 +14392,27 @@ ns=1;i=2830 + + VectorUnionValue + + i=63 + ns=1;i=2740 + + + + VectorWithOptionalFieldsValue + + i=63 + ns=1;i=2740 + + + + MultipleVectorsValue + + i=63 + ns=1;i=2740 + + Structure @@ -14930,6 +15092,9 @@ ns=1;i=3017 ns=1;i=3018 ns=1;i=3019 + ns=1;i=3612 + ns=1;i=3613 + ns=1;i=3629 ns=1;i=2739 ns=1;i=2933 ns=1;i=1456 @@ -15510,6 +15675,27 @@ ns=1;i=2929 + + VectorUnionValue + + i=63 + ns=1;i=2929 + + + + VectorWithOptionalFieldsValue + + i=63 + ns=1;i=2929 + + + + MultipleVectorsValue + + i=63 + ns=1;i=2929 + + UserScalar @@ -18147,6 +18333,30 @@ i=76 + + Default Binary + + ns=1;i=3584 + ns=1;i=3592 + i=76 + + + + Default Binary + + ns=1;i=3585 + ns=1;i=3595 + i=76 + + + + Default Binary + + ns=1;i=3615 + ns=1;i=3619 + i=76 + + Default Binary @@ -18173,6 +18383,9 @@ ns=1;i=3528 ns=1;i=3531 ns=1;i=3534 + ns=1;i=3592 + ns=1;i=3595 + ns=1;i=3619 ns=1;i=3537 ns=1;i=3540 i=93 @@ -18418,20 +18631,44 @@ IE5hbWU9IlZlY3RvciIgQmFzZVR5cGU9InVhOkV4dGVuc2lvbk9iamVjdCI+DQogICAgPG9wYzpG aWVsZCBOYW1lPSJYIiBUeXBlTmFtZT0ib3BjOkRvdWJsZSIgLz4NCiAgICA8b3BjOkZpZWxkIE5h bWU9IlkiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iWiIg VHlwZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQogIDxv -cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgQmFzZVR5cGU9InVh -OkV4dGVuc2lvbk9iamVjdCI+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJBY3RvciIgVHlwZU5hbWU9 -Im9wYzpTdHJpbmciIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJUaW1lc3RhbXAiIFR5cGVOYW1l -PSJvcGM6RGF0ZVRpbWUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJDb21tZW50IiBUeXBlTmFt -ZT0idWE6TG9jYWxpemVkVGV4dCIgLz4NCiAgPC9vcGM6U3RydWN0dXJlZFR5cGU+DQoNCiAgPG9w -YzpTdHJ1Y3R1cmVkVHlwZSBOYW1lPSJXb3JrT3JkZXJUeXBlIiBCYXNlVHlwZT0idWE6RXh0ZW5z -aW9uT2JqZWN0Ij4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IklEIiBUeXBlTmFtZT0ib3BjOkd1aWQi -IC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJBc3NldElEIiBUeXBlTmFtZT0ib3BjOlN0cmluZyIg -Lz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlN0YXJ0VGltZSIgVHlwZU5hbWU9Im9wYzpEYXRlVGlt -ZSIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9Ik5vT2ZTdGF0dXNDb21tZW50cyIgVHlwZU5hbWU9 -Im9wYzpJbnQzMiIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlN0YXR1c0NvbW1lbnRzIiBUeXBl -TmFtZT0idG5zOldvcmtPcmRlclN0YXR1c1R5cGUiIExlbmd0aEZpZWxkPSJOb09mU3RhdHVzQ29t -bWVudHMiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQo8L29wYzpUeXBlRGljdGlvbmFy -eT4= +cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iVmVjdG9yVW5pb24iIEJhc2VUeXBlPSJ1YTpVbmlvbiI+ +DQogICAgPG9wYzpGaWVsZCBOYW1lPSJYIiBUeXBlTmFtZT0ib3BjOkRvdWJsZSIgLz4NCiAgICA8 +b3BjOkZpZWxkIE5hbWU9IlkiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6Rmll +bGQgTmFtZT0iWiIgVHlwZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRU +eXBlPg0KDQogIDxvcGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmll +bGRzIiBCYXNlVHlwZT0idWE6RXh0ZW5zaW9uT2JqZWN0Ij4NCiAgICA8b3BjOkZpZWxkIE5hbWU9 +IlgiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iWSIgVHlw +ZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJaIiBUeXBlTmFtZT0i +b3BjOkRvdWJsZSIgLz4NCiAgPC9vcGM6U3RydWN0dXJlZFR5cGU+DQoNCiAgPG9wYzpTdHJ1Y3R1 +cmVkVHlwZSBOYW1lPSJNdWx0aXBsZVZlY3RvcnMiIEJhc2VUeXBlPSJ1YTpFeHRlbnNpb25PYmpl +Y3QiPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yIiBUeXBlTmFtZT0idG5zOlZlY3RvciIg +Lz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlZlY3RvclVuaW9uIiBUeXBlTmFtZT0idG5zOlZlY3Rv +clVuaW9uIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRz +IiBUeXBlTmFtZT0idG5zOlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyIgLz4NCiAgICA8b3BjOkZp +ZWxkIE5hbWU9Ik5vT2ZWZWN0b3JBcnJheSIgVHlwZU5hbWU9Im9wYzpJbnQzMiIgLz4NCiAgICA8 +b3BjOkZpZWxkIE5hbWU9IlZlY3RvckFycmF5IiBUeXBlTmFtZT0idG5zOlZlY3RvciIgTGVuZ3Ro +RmllbGQ9Ik5vT2ZWZWN0b3JBcnJheSIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9Ik5vT2ZWZWN0 +b3JVbmlvbkFycmF5IiBUeXBlTmFtZT0ib3BjOkludDMyIiAvPg0KICAgIDxvcGM6RmllbGQgTmFt +ZT0iVmVjdG9yVW5pb25BcnJheSIgVHlwZU5hbWU9InRuczpWZWN0b3JVbmlvbiIgTGVuZ3RoRmll +bGQ9Ik5vT2ZWZWN0b3JVbmlvbkFycmF5IiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iTm9PZlZl +Y3RvcldpdGhPcHRpb25hbEZpZWxkc0FycmF5IiBUeXBlTmFtZT0ib3BjOkludDMyIiAvPg0KICAg +IDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzQXJyYXkiIFR5cGVOYW1l +PSJ0bnM6VmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzIiBMZW5ndGhGaWVsZD0iTm9PZlZlY3Rvcldp +dGhPcHRpb25hbEZpZWxkc0FycmF5IiAvPg0KICA8L29wYzpTdHJ1Y3R1cmVkVHlwZT4NCg0KICA8 +b3BjOlN0cnVjdHVyZWRUeXBlIE5hbWU9IldvcmtPcmRlclN0YXR1c1R5cGUiIEJhc2VUeXBlPSJ1 +YTpFeHRlbnNpb25PYmplY3QiPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQWN0b3IiIFR5cGVOYW1l +PSJvcGM6U3RyaW5nIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVGltZXN0YW1wIiBUeXBlTmFt +ZT0ib3BjOkRhdGVUaW1lIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQ29tbWVudCIgVHlwZU5h +bWU9InVhOkxvY2FsaXplZFRleHQiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQogIDxv +cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iV29ya09yZGVyVHlwZSIgQmFzZVR5cGU9InVhOkV4dGVu +c2lvbk9iamVjdCI+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJJRCIgVHlwZU5hbWU9Im9wYzpHdWlk +IiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQXNzZXRJRCIgVHlwZU5hbWU9Im9wYzpTdHJpbmci +IC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJTdGFydFRpbWUiIFR5cGVOYW1lPSJvcGM6RGF0ZVRp +bWUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJOb09mU3RhdHVzQ29tbWVudHMiIFR5cGVOYW1l +PSJvcGM6SW50MzIiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJTdGF0dXNDb21tZW50cyIgVHlw +ZU5hbWU9InRuczpXb3JrT3JkZXJTdGF0dXNUeXBlIiBMZW5ndGhGaWVsZD0iTm9PZlN0YXR1c0Nv +bW1lbnRzIiAvPg0KICA8L29wYzpTdHJ1Y3R1cmVkVHlwZT4NCg0KPC9vcGM6VHlwZURpY3Rpb25h +cnk+ @@ -18504,6 +18741,36 @@ eT4= Vector + + VectorUnion + + i=69 + ns=1;i=3518 + + + VectorUnion + + + + VectorWithOptionalFields + + i=69 + ns=1;i=3518 + + + VectorWithOptionalFields + + + + MultipleVectors + + i=69 + ns=1;i=3518 + + + MultipleVectors + + WorkOrderStatusType @@ -18564,6 +18831,30 @@ eT4= i=76 + + Default XML + + ns=1;i=3584 + ns=1;i=3600 + i=76 + + + + Default XML + + ns=1;i=3585 + ns=1;i=3603 + i=76 + + + + Default XML + + ns=1;i=3615 + ns=1;i=3623 + i=76 + + Default XML @@ -18590,6 +18881,9 @@ eT4= ns=1;i=3560 ns=1;i=3563 ns=1;i=3566 + ns=1;i=3600 + ns=1;i=3603 + ns=1;i=3623 ns=1;i=3569 ns=1;i=3572 i=92 @@ -18602,7 +18896,7 @@ c2QiDQogIHhtbG5zOnRucz0iaHR0cDovL3Rlc3Qub3JnL1VBL0RhdGEvIg0KICB0YXJnZXROYW1l c3BhY2U9Imh0dHA6Ly90ZXN0Lm9yZy9VQS9EYXRhLyINCiAgZWxlbWVudEZvcm1EZWZhdWx0PSJx dWFsaWZpZWQiDQo+DQogIDx4czphbm5vdGF0aW9uPg0KICAgIDx4czphcHBpbmZvPg0KICAgICAg PHVhOk1vZGVsIE1vZGVsVXJpPSJodHRwOi8vdGVzdC5vcmcvVUEvRGF0YS8iIFZlcnNpb249IjEu -MC4wIiBQdWJsaWNhdGlvbkRhdGU9IjIwMjMtMDYtMDZUMDY6MzM6NTEuNTc2OTYyOVoiIC8+DQog +MC4wIiBQdWJsaWNhdGlvbkRhdGU9IjIwMjMtMTAtMDlUMDg6NTE6MjQuNTIzNzA4OFoiIC8+DQog ICAgPC94czphcHBpbmZvPg0KICA8L3hzOmFubm90YXRpb24+DQogIA0KICA8eHM6aW1wb3J0IG5h bWVzcGFjZT0iaHR0cDovL29wY2ZvdW5kYXRpb24ub3JnL1VBLzIwMDgvMDIvVHlwZXMueHNkIiAv Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJTY2FsYXJTdHJ1Y3R1cmVEYXRhVHlwZSI+DQog @@ -18841,35 +19135,82 @@ YW1lPSJWZWN0b3IiIHR5cGU9InRuczpWZWN0b3IiIG1pbk9jY3Vycz0iMCIgbWF4T2NjdXJzPSJ1 bmJvdW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6 Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZlZlY3RvciIgdHlwZT0idG5z Okxpc3RPZlZlY3RvciIgbmlsbGFibGU9InRydWUiPjwveHM6ZWxlbWVudD4NCg0KICA8eHM6Y29t -cGxleFR5cGUgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0K -ICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQWN0b3IiIHR5cGU9InhzOnN0cmluZyIgbWluT2NjdXJz -PSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlRpbWVzdGFt -cCIgdHlwZT0ieHM6ZGF0ZVRpbWUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4czplbGVtZW50 -IG5hbWU9IkNvbW1lbnQiIHR5cGU9InVhOkxvY2FsaXplZFRleHQiIG1pbk9jY3Vycz0iMCIgbmls -bGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4VHlwZT4N -CiAgPHhzOmVsZW1lbnQgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgdHlwZT0idG5zOldvcmtP -cmRlclN0YXR1c1R5cGUiIC8+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RPZldvcmtP -cmRlclN0YXR1c1R5cGUiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4czplbGVtZW50IG5h -bWU9IldvcmtPcmRlclN0YXR1c1R5cGUiIHR5cGU9InRuczpXb3JrT3JkZXJTdGF0dXNUeXBlIiBt -aW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAg -ICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1l -PSJMaXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiB0eXBlPSJ0bnM6TGlzdE9mV29ya09yZGVyU3Rh -dHVzVHlwZSIgbmlsbGFibGU9InRydWUiPjwveHM6ZWxlbWVudD4NCg0KICA8eHM6Y29tcGxleFR5 -cGUgbmFtZT0iV29ya09yZGVyVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVs -ZW1lbnQgbmFtZT0iSUQiIHR5cGU9InVhOkd1aWQiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4 -czplbGVtZW50IG5hbWU9IkFzc2V0SUQiIHR5cGU9InhzOnN0cmluZyIgbWluT2NjdXJzPSIwIiBu -aWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlN0YXJ0VGltZSIgdHlw -ZT0ieHM6ZGF0ZVRpbWUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9 -IlN0YXR1c0NvbW1lbnRzIiB0eXBlPSJ0bnM6TGlzdE9mV29ya09yZGVyU3RhdHVzVHlwZSIgbWlu -T2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hz -OmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3JkZXJUeXBlIiB0eXBlPSJ0 -bnM6V29ya09yZGVyVHlwZSIgLz4NCg0KICA8eHM6Y29tcGxleFR5cGUgbmFtZT0iTGlzdE9mV29y -a09yZGVyVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0i -V29ya09yZGVyVHlwZSIgdHlwZT0idG5zOldvcmtPcmRlclR5cGUiIG1pbk9jY3Vycz0iMCIgbWF4 -T2NjdXJzPSJ1bmJvdW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+ -DQogIDwveHM6Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZldvcmtPcmRl -clR5cGUiIHR5cGU9InRuczpMaXN0T2ZXb3JrT3JkZXJUeXBlIiBuaWxsYWJsZT0idHJ1ZSI+PC94 -czplbGVtZW50Pg0KDQo8L3hzOnNjaGVtYT4= +cGxleFR5cGUgbmFtZT0iVmVjdG9yVW5pb24iPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4 +czplbGVtZW50IG5hbWU9IlN3aXRjaEZpZWxkIiB0eXBlPSJ4czp1bnNpZ25lZEludCIgbWluT2Nj +dXJzPSIwIiAvPg0KICAgICAgPHhzOmNob2ljZT4NCiAgICAgICAgPHhzOmVsZW1lbnQgbmFtZT0i +WCIgdHlwZT0ieHM6ZG91YmxlIiBtaW5PY2N1cnM9IjAiIC8+DQogICAgICAgIDx4czplbGVtZW50 +IG5hbWU9IlkiIHR5cGU9InhzOmRvdWJsZSIgbWluT2NjdXJzPSIwIiAvPg0KICAgICAgICA8eHM6 +ZWxlbWVudCBuYW1lPSJaIiB0eXBlPSJ4czpkb3VibGUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAg +IDwveHM6Y2hvaWNlPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29tcGxleFR5cGU+DQog +IDx4czplbGVtZW50IG5hbWU9IlZlY3RvclVuaW9uIiB0eXBlPSJ0bnM6VmVjdG9yVW5pb24iIC8+ +DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RPZlZlY3RvclVuaW9uIj4NCiAgICA8eHM6 +c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJWZWN0b3JVbmlvbiIgdHlwZT0idG5z +OlZlY3RvclVuaW9uIiBtaW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBuaWxsYWJs +ZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8 +eHM6ZWxlbWVudCBuYW1lPSJMaXN0T2ZWZWN0b3JVbmlvbiIgdHlwZT0idG5zOkxpc3RPZlZlY3Rv +clVuaW9uIiBuaWxsYWJsZT0idHJ1ZSI+PC94czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlw +ZSBuYW1lPSJWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAg +ICAgIDx4czplbGVtZW50IG5hbWU9IlgiIHR5cGU9InhzOmRvdWJsZSIgbWluT2NjdXJzPSIwIiAv +Pg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iWSIgdHlwZT0ieHM6ZG91YmxlIiBtaW5PY2N1cnM9 +IjAiIC8+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJaIiB0eXBlPSJ4czpkb3VibGUiIG1pbk9j +Y3Vycz0iMCIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8 +eHM6ZWxlbWVudCBuYW1lPSJWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIHR5cGU9InRuczpWZWN0 +b3JXaXRoT3B0aW9uYWxGaWVsZHMiIC8+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RP +ZlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzIiB0eXBlPSJ0bnM6VmVjdG9y +V2l0aE9wdGlvbmFsRmllbGRzIiBtaW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBu +aWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBl +Pg0KICA8eHM6ZWxlbWVudCBuYW1lPSJMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIHR5 +cGU9InRuczpMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIG5pbGxhYmxlPSJ0cnVlIj48 +L3hzOmVsZW1lbnQ+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ik11bHRpcGxlVmVjdG9ycyI+ +DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yIiB0eXBl +PSJ0bnM6VmVjdG9yIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iVmVjdG9yVW5pb24iIHR5cGU9InRuczpWZWN0b3JVbmlvbiIgbWluT2Nj +dXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlZlY3Rv +cldpdGhPcHRpb25hbEZpZWxkcyIgdHlwZT0idG5zOlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyIg +bWluT2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9 +IlZlY3RvckFycmF5IiB0eXBlPSJ0bnM6TGlzdE9mVmVjdG9yIiBtaW5PY2N1cnM9IjAiIG5pbGxh +YmxlPSJ0cnVlIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yVW5pb25BcnJheSIg +dHlwZT0idG5zOkxpc3RPZlZlY3RvclVuaW9uIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVl +IiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzQXJy +YXkiIHR5cGU9InRuczpMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIG1pbk9jY3Vycz0i +MCIgbmlsbGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4 +VHlwZT4NCiAgPHhzOmVsZW1lbnQgbmFtZT0iTXVsdGlwbGVWZWN0b3JzIiB0eXBlPSJ0bnM6TXVs +dGlwbGVWZWN0b3JzIiAvPg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJMaXN0T2ZNdWx0aXBs +ZVZlY3RvcnMiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9Ik11 +bHRpcGxlVmVjdG9ycyIgdHlwZT0idG5zOk11bHRpcGxlVmVjdG9ycyIgbWluT2NjdXJzPSIwIiBt +YXhPY2N1cnM9InVuYm91bmRlZCIgbmlsbGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5j +ZT4NCiAgPC94czpjb21wbGV4VHlwZT4NCiAgPHhzOmVsZW1lbnQgbmFtZT0iTGlzdE9mTXVsdGlw +bGVWZWN0b3JzIiB0eXBlPSJ0bnM6TGlzdE9mTXVsdGlwbGVWZWN0b3JzIiBuaWxsYWJsZT0idHJ1 +ZSI+PC94czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJXb3JrT3JkZXJTdGF0 +dXNUeXBlIj4NCiAgICA8eHM6c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJBY3Rv +ciIgdHlwZT0ieHM6c3RyaW5nIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAg +ICAgPHhzOmVsZW1lbnQgbmFtZT0iVGltZXN0YW1wIiB0eXBlPSJ4czpkYXRlVGltZSIgbWluT2Nj +dXJzPSIwIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQ29tbWVudCIgdHlwZT0idWE6TG9j +YWxpemVkVGV4dCIgbWluT2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNl +cXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3Jk +ZXJTdGF0dXNUeXBlIiB0eXBlPSJ0bnM6V29ya09yZGVyU3RhdHVzVHlwZSIgLz4NCg0KICA8eHM6 +Y29tcGxleFR5cGUgbmFtZT0iTGlzdE9mV29ya09yZGVyU3RhdHVzVHlwZSI+DQogICAgPHhzOnNl +cXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgdHlw +ZT0idG5zOldvcmtPcmRlclN0YXR1c1R5cGUiIG1pbk9jY3Vycz0iMCIgbWF4T2NjdXJzPSJ1bmJv +dW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29t +cGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZldvcmtPcmRlclN0YXR1c1R5cGUi +IHR5cGU9InRuczpMaXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiBuaWxsYWJsZT0idHJ1ZSI+PC94 +czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJXb3JrT3JkZXJUeXBlIj4NCiAg +ICA8eHM6c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJJRCIgdHlwZT0idWE6R3Vp +ZCIgbWluT2NjdXJzPSIwIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQXNzZXRJRCIgdHlw +ZT0ieHM6c3RyaW5nIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iU3RhcnRUaW1lIiB0eXBlPSJ4czpkYXRlVGltZSIgbWluT2NjdXJzPSIw +IiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iU3RhdHVzQ29tbWVudHMiIHR5cGU9InRuczpM +aXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAv +Pg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50 +IG5hbWU9IldvcmtPcmRlclR5cGUiIHR5cGU9InRuczpXb3JrT3JkZXJUeXBlIiAvPg0KDQogIDx4 +czpjb21wbGV4VHlwZSBuYW1lPSJMaXN0T2ZXb3JrT3JkZXJUeXBlIj4NCiAgICA8eHM6c2VxdWVu +Y2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3JkZXJUeXBlIiB0eXBlPSJ0bnM6V29y +a09yZGVyVHlwZSIgbWluT2NjdXJzPSIwIiBtYXhPY2N1cnM9InVuYm91bmRlZCIgbmlsbGFibGU9 +InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4VHlwZT4NCiAgPHhz +OmVsZW1lbnQgbmFtZT0iTGlzdE9mV29ya09yZGVyVHlwZSIgdHlwZT0idG5zOkxpc3RPZldvcmtP +cmRlclR5cGUiIG5pbGxhYmxlPSJ0cnVlIj48L3hzOmVsZW1lbnQ+DQoNCjwveHM6c2NoZW1hPg== @@ -18942,6 +19283,36 @@ czplbGVtZW50Pg0KDQo8L3hzOnNjaGVtYT4= //xs:element[@name='Vector'] + + VectorUnion + + i=69 + ns=1;i=3550 + + + //xs:element[@name='VectorUnion'] + + + + VectorWithOptionalFields + + i=69 + ns=1;i=3550 + + + //xs:element[@name='VectorWithOptionalFields'] + + + + MultipleVectors + + i=69 + ns=1;i=3550 + + + //xs:element[@name='MultipleVectors'] + + WorkOrderStatusType @@ -18997,6 +19368,27 @@ czplbGVtZW50Pg0KDQo8L3hzOnNjaGVtYT4= i=76 + + Default JSON + + ns=1;i=3584 + i=76 + + + + Default JSON + + ns=1;i=3585 + i=76 + + + + Default JSON + + ns=1;i=3615 + i=76 + + Default JSON diff --git a/Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.uanodes b/Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.uanodes index 1a970df54..9f0c6d45a 100644 Binary files a/Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.uanodes and b/Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.uanodes differ diff --git a/Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.xml b/Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.xml index 22245b979..7fa8b2f0c 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.xml +++ b/Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.xml @@ -2948,6 +2948,84 @@ 1 + + Variable_2 + + ns=1;i=3582 + + + 1 + VectorUnionValue + + + i=47 + + + i=63 + + + i=78 + + 3582 + + ns=1;i=3584 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3583 + + + 1 + VectorWithOptionalFieldsValue + + + i=47 + + + i=63 + + + i=78 + + 3583 + + ns=1;i=3585 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3614 + + + 1 + MultipleVectorsValue + + + i=47 + + + i=63 + + + i=78 + + 3614 + + ns=1;i=3615 + + -1 + 1 + 1 + ObjectType_8 @@ -5603,6 +5681,87 @@ 1 1 + + Variable_2 + + ns=1;i=3608 + + + 1 + VectorUnionValue + + + i=47 + + + i=63 + + + i=78 + + 3608 + + ns=1;i=3584 + + 1 + 0 + 1 + 1 + + + Variable_2 + + ns=1;i=3609 + + + 1 + VectorWithOptionalFieldsValue + + + i=47 + + + i=63 + + + i=78 + + 3609 + + ns=1;i=3585 + + 1 + 0 + 1 + 1 + + + Variable_2 + + ns=1;i=3627 + + + 1 + MultipleVectorsValue + + + i=47 + + + i=63 + + + i=78 + + 3627 + + ns=1;i=3615 + + 1 + 0 + 1 + 1 + ObjectType_8 @@ -8476,6 +8635,216 @@ 1 + + DataType_64 + + ns=1;i=3584 + + + 1 + VectorUnion + + + i=12756 + + + + i=14798 + + + + + i=12756 + + Union_2 + + + X + + i=11 + + -1 + + 0 + false + + + Y + + i=11 + + -1 + + 0 + false + + + Z + + i=11 + + -1 + + 0 + false + + + + + + + + DataType_64 + + ns=1;i=3585 + + + 1 + VectorWithOptionalFields + + + i=22 + + + + i=14798 + + + + + i=22 + + StructureWithOptionalFields_1 + + + X + + i=11 + + -1 + + 0 + true + + + Y + + i=11 + + -1 + + 0 + true + + + Z + + i=11 + + -1 + + 0 + true + + + + + + + + DataType_64 + + ns=1;i=3615 + + + 1 + MultipleVectors + + + i=22 + + + + i=14798 + + + + + i=22 + + Structure_0 + + + Vector + + ns=1;i=1888 + + -1 + + 0 + false + + + VectorUnion + + ns=1;i=3584 + + -1 + + 0 + false + + + VectorWithOptionalFields + + ns=1;i=3585 + + -1 + + 0 + false + + + VectorArray + + ns=1;i=1888 + + 1 + + 0 + + 0 + false + + + VectorUnionArray + + ns=1;i=3584 + + 1 + + 0 + + 0 + false + + + VectorWithOptionalFieldsArray + + ns=1;i=3585 + + 1 + + 0 + + 0 + false + + + + + + DataType_64 @@ -14275,6 +14644,75 @@ 1 + + Variable_2 + + ns=1;i=3586 + + + 1 + VectorUnionValue + + + i=47 + + + i=63 + + 3586 + + ns=1;i=3584 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3587 + + + 1 + VectorWithOptionalFieldsValue + + + i=47 + + + i=63 + + 3587 + + ns=1;i=3585 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3616 + + + 1 + MultipleVectorsValue + + + i=47 + + + i=63 + + 3616 + + ns=1;i=3615 + + -1 + 1 + 1 + Object_1 @@ -17646,6 +18084,78 @@ 1 1 + + Variable_2 + + ns=1;i=3610 + + + 1 + VectorUnionValue + + + i=47 + + + i=63 + + 3610 + + ns=1;i=3584 + + 1 + 0 + 1 + 1 + + + Variable_2 + + ns=1;i=3611 + + + 1 + VectorWithOptionalFieldsValue + + + i=47 + + + i=63 + + 3611 + + ns=1;i=3585 + + 1 + 0 + 1 + 1 + + + Variable_2 + + ns=1;i=3628 + + + 1 + MultipleVectorsValue + + + i=47 + + + i=63 + + 3628 + + ns=1;i=3615 + + 1 + 0 + 1 + 1 + Object_1 @@ -29297,6 +29807,75 @@ 1 + + Variable_2 + + ns=1;i=3588 + + + 1 + VectorUnionValue + + + i=47 + + + i=63 + + 3588 + + ns=1;i=3584 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3589 + + + 1 + VectorWithOptionalFieldsValue + + + i=47 + + + i=63 + + 3589 + + ns=1;i=3585 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3617 + + + 1 + MultipleVectorsValue + + + i=47 + + + i=63 + + 3617 + + ns=1;i=3615 + + -1 + 1 + 1 + Object_1 @@ -32678,6 +33257,78 @@ 1 1 + + Variable_2 + + ns=1;i=3612 + + + 1 + VectorUnionValue + + + i=47 + + + i=63 + + 3612 + + ns=1;i=3584 + + 1 + 0 + 1 + 1 + + + Variable_2 + + ns=1;i=3613 + + + 1 + VectorWithOptionalFieldsValue + + + i=47 + + + i=63 + + 3613 + + ns=1;i=3585 + + 1 + 0 + 1 + 1 + + + Variable_2 + + ns=1;i=3629 + + + 1 + MultipleVectorsValue + + + i=47 + + + i=63 + + 3629 + + ns=1;i=3615 + + 1 + 0 + 1 + 1 + Object_1 @@ -39755,6 +40406,105 @@ + + Object_1 + + ns=1;i=3590 + + + 0 + Default Binary + + + i=76 + + 3590 + + + + i=38 + + true + + ns=1;i=3584 + + + + + i=39 + + + ns=1;i=3592 + + + + + + Object_1 + + ns=1;i=3591 + + + 0 + Default Binary + + + i=76 + + 3591 + + + + i=38 + + true + + ns=1;i=3585 + + + + + i=39 + + + ns=1;i=3595 + + + + + + Object_1 + + ns=1;i=3618 + + + 0 + Default Binary + + + i=76 + + 3618 + + + + i=38 + + true + + ns=1;i=3615 + + + + + i=39 + + + ns=1;i=3619 + + + + Object_1 @@ -40075,20 +40825,44 @@ IE5hbWU9IlZlY3RvciIgQmFzZVR5cGU9InVhOkV4dGVuc2lvbk9iamVjdCI+DQogICAgPG9wYzpG aWVsZCBOYW1lPSJYIiBUeXBlTmFtZT0ib3BjOkRvdWJsZSIgLz4NCiAgICA8b3BjOkZpZWxkIE5h bWU9IlkiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iWiIg VHlwZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQogIDxv -cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgQmFzZVR5cGU9InVh -OkV4dGVuc2lvbk9iamVjdCI+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJBY3RvciIgVHlwZU5hbWU9 -Im9wYzpTdHJpbmciIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJUaW1lc3RhbXAiIFR5cGVOYW1l -PSJvcGM6RGF0ZVRpbWUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJDb21tZW50IiBUeXBlTmFt -ZT0idWE6TG9jYWxpemVkVGV4dCIgLz4NCiAgPC9vcGM6U3RydWN0dXJlZFR5cGU+DQoNCiAgPG9w -YzpTdHJ1Y3R1cmVkVHlwZSBOYW1lPSJXb3JrT3JkZXJUeXBlIiBCYXNlVHlwZT0idWE6RXh0ZW5z -aW9uT2JqZWN0Ij4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IklEIiBUeXBlTmFtZT0ib3BjOkd1aWQi -IC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJBc3NldElEIiBUeXBlTmFtZT0ib3BjOlN0cmluZyIg -Lz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlN0YXJ0VGltZSIgVHlwZU5hbWU9Im9wYzpEYXRlVGlt -ZSIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9Ik5vT2ZTdGF0dXNDb21tZW50cyIgVHlwZU5hbWU9 -Im9wYzpJbnQzMiIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlN0YXR1c0NvbW1lbnRzIiBUeXBl -TmFtZT0idG5zOldvcmtPcmRlclN0YXR1c1R5cGUiIExlbmd0aEZpZWxkPSJOb09mU3RhdHVzQ29t -bWVudHMiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQo8L29wYzpUeXBlRGljdGlvbmFy -eT4= +cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iVmVjdG9yVW5pb24iIEJhc2VUeXBlPSJ1YTpVbmlvbiI+ +DQogICAgPG9wYzpGaWVsZCBOYW1lPSJYIiBUeXBlTmFtZT0ib3BjOkRvdWJsZSIgLz4NCiAgICA8 +b3BjOkZpZWxkIE5hbWU9IlkiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6Rmll +bGQgTmFtZT0iWiIgVHlwZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRU +eXBlPg0KDQogIDxvcGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmll +bGRzIiBCYXNlVHlwZT0idWE6RXh0ZW5zaW9uT2JqZWN0Ij4NCiAgICA8b3BjOkZpZWxkIE5hbWU9 +IlgiIFR5cGVOYW1lPSJvcGM6RG91YmxlIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iWSIgVHlw +ZU5hbWU9Im9wYzpEb3VibGUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJaIiBUeXBlTmFtZT0i +b3BjOkRvdWJsZSIgLz4NCiAgPC9vcGM6U3RydWN0dXJlZFR5cGU+DQoNCiAgPG9wYzpTdHJ1Y3R1 +cmVkVHlwZSBOYW1lPSJNdWx0aXBsZVZlY3RvcnMiIEJhc2VUeXBlPSJ1YTpFeHRlbnNpb25PYmpl +Y3QiPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yIiBUeXBlTmFtZT0idG5zOlZlY3RvciIg +Lz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9IlZlY3RvclVuaW9uIiBUeXBlTmFtZT0idG5zOlZlY3Rv +clVuaW9uIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRz +IiBUeXBlTmFtZT0idG5zOlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyIgLz4NCiAgICA8b3BjOkZp +ZWxkIE5hbWU9Ik5vT2ZWZWN0b3JBcnJheSIgVHlwZU5hbWU9Im9wYzpJbnQzMiIgLz4NCiAgICA8 +b3BjOkZpZWxkIE5hbWU9IlZlY3RvckFycmF5IiBUeXBlTmFtZT0idG5zOlZlY3RvciIgTGVuZ3Ro +RmllbGQ9Ik5vT2ZWZWN0b3JBcnJheSIgLz4NCiAgICA8b3BjOkZpZWxkIE5hbWU9Ik5vT2ZWZWN0 +b3JVbmlvbkFycmF5IiBUeXBlTmFtZT0ib3BjOkludDMyIiAvPg0KICAgIDxvcGM6RmllbGQgTmFt +ZT0iVmVjdG9yVW5pb25BcnJheSIgVHlwZU5hbWU9InRuczpWZWN0b3JVbmlvbiIgTGVuZ3RoRmll +bGQ9Ik5vT2ZWZWN0b3JVbmlvbkFycmF5IiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iTm9PZlZl +Y3RvcldpdGhPcHRpb25hbEZpZWxkc0FycmF5IiBUeXBlTmFtZT0ib3BjOkludDMyIiAvPg0KICAg +IDxvcGM6RmllbGQgTmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzQXJyYXkiIFR5cGVOYW1l +PSJ0bnM6VmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzIiBMZW5ndGhGaWVsZD0iTm9PZlZlY3Rvcldp +dGhPcHRpb25hbEZpZWxkc0FycmF5IiAvPg0KICA8L29wYzpTdHJ1Y3R1cmVkVHlwZT4NCg0KICA8 +b3BjOlN0cnVjdHVyZWRUeXBlIE5hbWU9IldvcmtPcmRlclN0YXR1c1R5cGUiIEJhc2VUeXBlPSJ1 +YTpFeHRlbnNpb25PYmplY3QiPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQWN0b3IiIFR5cGVOYW1l +PSJvcGM6U3RyaW5nIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iVGltZXN0YW1wIiBUeXBlTmFt +ZT0ib3BjOkRhdGVUaW1lIiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQ29tbWVudCIgVHlwZU5h +bWU9InVhOkxvY2FsaXplZFRleHQiIC8+DQogIDwvb3BjOlN0cnVjdHVyZWRUeXBlPg0KDQogIDxv +cGM6U3RydWN0dXJlZFR5cGUgTmFtZT0iV29ya09yZGVyVHlwZSIgQmFzZVR5cGU9InVhOkV4dGVu +c2lvbk9iamVjdCI+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJJRCIgVHlwZU5hbWU9Im9wYzpHdWlk +IiAvPg0KICAgIDxvcGM6RmllbGQgTmFtZT0iQXNzZXRJRCIgVHlwZU5hbWU9Im9wYzpTdHJpbmci +IC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJTdGFydFRpbWUiIFR5cGVOYW1lPSJvcGM6RGF0ZVRp +bWUiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJOb09mU3RhdHVzQ29tbWVudHMiIFR5cGVOYW1l +PSJvcGM6SW50MzIiIC8+DQogICAgPG9wYzpGaWVsZCBOYW1lPSJTdGF0dXNDb21tZW50cyIgVHlw +ZU5hbWU9InRuczpXb3JrT3JkZXJTdGF0dXNUeXBlIiBMZW5ndGhGaWVsZD0iTm9PZlN0YXR1c0Nv +bW1lbnRzIiAvPg0KICA8L29wYzpTdHJ1Y3R1cmVkVHlwZT4NCg0KPC9vcGM6VHlwZURpY3Rpb25h +cnk+ @@ -40304,6 +41078,90 @@ eT4= 1 1 + + Variable_2 + + ns=1;i=3592 + + + 1 + VectorUnion + + + i=47 + + + i=69 + + 3592 + + + VectorUnion + + + + i=12 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3595 + + + 1 + VectorWithOptionalFields + + + i=47 + + + i=69 + + 3595 + + + VectorWithOptionalFields + + + + i=12 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3619 + + + 1 + MultipleVectors + + + i=47 + + + i=69 + + 3619 + + + MultipleVectors + + + + i=12 + + -1 + 1 + 1 + Variable_2 @@ -40526,6 +41384,105 @@ eT4= + + Object_1 + + ns=1;i=3598 + + + 0 + Default XML + + + i=76 + + 3598 + + + + i=38 + + true + + ns=1;i=3584 + + + + + i=39 + + + ns=1;i=3600 + + + + + + Object_1 + + ns=1;i=3599 + + + 0 + Default XML + + + i=76 + + 3599 + + + + i=38 + + true + + ns=1;i=3585 + + + + + i=39 + + + ns=1;i=3603 + + + + + + Object_1 + + ns=1;i=3622 + + + 0 + Default XML + + + i=76 + + 3622 + + + + i=38 + + true + + ns=1;i=3615 + + + + + i=39 + + + ns=1;i=3623 + + + + Object_1 @@ -40613,7 +41570,7 @@ c2QiDQogIHhtbG5zOnRucz0iaHR0cDovL3Rlc3Qub3JnL1VBL0RhdGEvIg0KICB0YXJnZXROYW1l c3BhY2U9Imh0dHA6Ly90ZXN0Lm9yZy9VQS9EYXRhLyINCiAgZWxlbWVudEZvcm1EZWZhdWx0PSJx dWFsaWZpZWQiDQo+DQogIDx4czphbm5vdGF0aW9uPg0KICAgIDx4czphcHBpbmZvPg0KICAgICAg PHVhOk1vZGVsIE1vZGVsVXJpPSJodHRwOi8vdGVzdC5vcmcvVUEvRGF0YS8iIFZlcnNpb249IjEu -MC4wIiBQdWJsaWNhdGlvbkRhdGU9IjIwMjMtMDYtMDZUMDY6MzM6NTEuNTc2OTYyOVoiIC8+DQog +MC4wIiBQdWJsaWNhdGlvbkRhdGU9IjIwMjMtMTAtMDlUMDg6NTE6MjQuNTIzNzA4OFoiIC8+DQog ICAgPC94czphcHBpbmZvPg0KICA8L3hzOmFubm90YXRpb24+DQogIA0KICA8eHM6aW1wb3J0IG5h bWVzcGFjZT0iaHR0cDovL29wY2ZvdW5kYXRpb24ub3JnL1VBLzIwMDgvMDIvVHlwZXMueHNkIiAv Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJTY2FsYXJTdHJ1Y3R1cmVEYXRhVHlwZSI+DQog @@ -40852,35 +41809,82 @@ YW1lPSJWZWN0b3IiIHR5cGU9InRuczpWZWN0b3IiIG1pbk9jY3Vycz0iMCIgbWF4T2NjdXJzPSJ1 bmJvdW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6 Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZlZlY3RvciIgdHlwZT0idG5z Okxpc3RPZlZlY3RvciIgbmlsbGFibGU9InRydWUiPjwveHM6ZWxlbWVudD4NCg0KICA8eHM6Y29t -cGxleFR5cGUgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0K -ICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQWN0b3IiIHR5cGU9InhzOnN0cmluZyIgbWluT2NjdXJz -PSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlRpbWVzdGFt -cCIgdHlwZT0ieHM6ZGF0ZVRpbWUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4czplbGVtZW50 -IG5hbWU9IkNvbW1lbnQiIHR5cGU9InVhOkxvY2FsaXplZFRleHQiIG1pbk9jY3Vycz0iMCIgbmls -bGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4VHlwZT4N -CiAgPHhzOmVsZW1lbnQgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgdHlwZT0idG5zOldvcmtP -cmRlclN0YXR1c1R5cGUiIC8+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RPZldvcmtP -cmRlclN0YXR1c1R5cGUiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4czplbGVtZW50IG5h -bWU9IldvcmtPcmRlclN0YXR1c1R5cGUiIHR5cGU9InRuczpXb3JrT3JkZXJTdGF0dXNUeXBlIiBt -aW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAg -ICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1l -PSJMaXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiB0eXBlPSJ0bnM6TGlzdE9mV29ya09yZGVyU3Rh -dHVzVHlwZSIgbmlsbGFibGU9InRydWUiPjwveHM6ZWxlbWVudD4NCg0KICA8eHM6Y29tcGxleFR5 -cGUgbmFtZT0iV29ya09yZGVyVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVs -ZW1lbnQgbmFtZT0iSUQiIHR5cGU9InVhOkd1aWQiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4 -czplbGVtZW50IG5hbWU9IkFzc2V0SUQiIHR5cGU9InhzOnN0cmluZyIgbWluT2NjdXJzPSIwIiBu -aWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlN0YXJ0VGltZSIgdHlw -ZT0ieHM6ZGF0ZVRpbWUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9 -IlN0YXR1c0NvbW1lbnRzIiB0eXBlPSJ0bnM6TGlzdE9mV29ya09yZGVyU3RhdHVzVHlwZSIgbWlu -T2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hz -OmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3JkZXJUeXBlIiB0eXBlPSJ0 -bnM6V29ya09yZGVyVHlwZSIgLz4NCg0KICA8eHM6Y29tcGxleFR5cGUgbmFtZT0iTGlzdE9mV29y -a09yZGVyVHlwZSI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0i -V29ya09yZGVyVHlwZSIgdHlwZT0idG5zOldvcmtPcmRlclR5cGUiIG1pbk9jY3Vycz0iMCIgbWF4 -T2NjdXJzPSJ1bmJvdW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+ -DQogIDwveHM6Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZldvcmtPcmRl -clR5cGUiIHR5cGU9InRuczpMaXN0T2ZXb3JrT3JkZXJUeXBlIiBuaWxsYWJsZT0idHJ1ZSI+PC94 -czplbGVtZW50Pg0KDQo8L3hzOnNjaGVtYT4= +cGxleFR5cGUgbmFtZT0iVmVjdG9yVW5pb24iPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4 +czplbGVtZW50IG5hbWU9IlN3aXRjaEZpZWxkIiB0eXBlPSJ4czp1bnNpZ25lZEludCIgbWluT2Nj +dXJzPSIwIiAvPg0KICAgICAgPHhzOmNob2ljZT4NCiAgICAgICAgPHhzOmVsZW1lbnQgbmFtZT0i +WCIgdHlwZT0ieHM6ZG91YmxlIiBtaW5PY2N1cnM9IjAiIC8+DQogICAgICAgIDx4czplbGVtZW50 +IG5hbWU9IlkiIHR5cGU9InhzOmRvdWJsZSIgbWluT2NjdXJzPSIwIiAvPg0KICAgICAgICA8eHM6 +ZWxlbWVudCBuYW1lPSJaIiB0eXBlPSJ4czpkb3VibGUiIG1pbk9jY3Vycz0iMCIgLz4NCiAgICAg +IDwveHM6Y2hvaWNlPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29tcGxleFR5cGU+DQog +IDx4czplbGVtZW50IG5hbWU9IlZlY3RvclVuaW9uIiB0eXBlPSJ0bnM6VmVjdG9yVW5pb24iIC8+ +DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RPZlZlY3RvclVuaW9uIj4NCiAgICA8eHM6 +c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJWZWN0b3JVbmlvbiIgdHlwZT0idG5z +OlZlY3RvclVuaW9uIiBtaW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBuaWxsYWJs +ZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8 +eHM6ZWxlbWVudCBuYW1lPSJMaXN0T2ZWZWN0b3JVbmlvbiIgdHlwZT0idG5zOkxpc3RPZlZlY3Rv +clVuaW9uIiBuaWxsYWJsZT0idHJ1ZSI+PC94czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlw +ZSBuYW1lPSJWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAg +ICAgIDx4czplbGVtZW50IG5hbWU9IlgiIHR5cGU9InhzOmRvdWJsZSIgbWluT2NjdXJzPSIwIiAv +Pg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iWSIgdHlwZT0ieHM6ZG91YmxlIiBtaW5PY2N1cnM9 +IjAiIC8+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJaIiB0eXBlPSJ4czpkb3VibGUiIG1pbk9j +Y3Vycz0iMCIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8 +eHM6ZWxlbWVudCBuYW1lPSJWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIHR5cGU9InRuczpWZWN0 +b3JXaXRoT3B0aW9uYWxGaWVsZHMiIC8+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ikxpc3RP +ZlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyI+DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzIiB0eXBlPSJ0bnM6VmVjdG9y +V2l0aE9wdGlvbmFsRmllbGRzIiBtaW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIiBu +aWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNlcXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBl +Pg0KICA8eHM6ZWxlbWVudCBuYW1lPSJMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIHR5 +cGU9InRuczpMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIG5pbGxhYmxlPSJ0cnVlIj48 +L3hzOmVsZW1lbnQ+DQoNCiAgPHhzOmNvbXBsZXhUeXBlIG5hbWU9Ik11bHRpcGxlVmVjdG9ycyI+ +DQogICAgPHhzOnNlcXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yIiB0eXBl +PSJ0bnM6VmVjdG9yIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iVmVjdG9yVW5pb24iIHR5cGU9InRuczpWZWN0b3JVbmlvbiIgbWluT2Nj +dXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9IlZlY3Rv +cldpdGhPcHRpb25hbEZpZWxkcyIgdHlwZT0idG5zOlZlY3RvcldpdGhPcHRpb25hbEZpZWxkcyIg +bWluT2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9 +IlZlY3RvckFycmF5IiB0eXBlPSJ0bnM6TGlzdE9mVmVjdG9yIiBtaW5PY2N1cnM9IjAiIG5pbGxh +YmxlPSJ0cnVlIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yVW5pb25BcnJheSIg +dHlwZT0idG5zOkxpc3RPZlZlY3RvclVuaW9uIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVl +IiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iVmVjdG9yV2l0aE9wdGlvbmFsRmllbGRzQXJy +YXkiIHR5cGU9InRuczpMaXN0T2ZWZWN0b3JXaXRoT3B0aW9uYWxGaWVsZHMiIG1pbk9jY3Vycz0i +MCIgbmlsbGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4 +VHlwZT4NCiAgPHhzOmVsZW1lbnQgbmFtZT0iTXVsdGlwbGVWZWN0b3JzIiB0eXBlPSJ0bnM6TXVs +dGlwbGVWZWN0b3JzIiAvPg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJMaXN0T2ZNdWx0aXBs +ZVZlY3RvcnMiPg0KICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgIDx4czplbGVtZW50IG5hbWU9Ik11 +bHRpcGxlVmVjdG9ycyIgdHlwZT0idG5zOk11bHRpcGxlVmVjdG9ycyIgbWluT2NjdXJzPSIwIiBt +YXhPY2N1cnM9InVuYm91bmRlZCIgbmlsbGFibGU9InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5j +ZT4NCiAgPC94czpjb21wbGV4VHlwZT4NCiAgPHhzOmVsZW1lbnQgbmFtZT0iTGlzdE9mTXVsdGlw +bGVWZWN0b3JzIiB0eXBlPSJ0bnM6TGlzdE9mTXVsdGlwbGVWZWN0b3JzIiBuaWxsYWJsZT0idHJ1 +ZSI+PC94czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJXb3JrT3JkZXJTdGF0 +dXNUeXBlIj4NCiAgICA8eHM6c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJBY3Rv +ciIgdHlwZT0ieHM6c3RyaW5nIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAg +ICAgPHhzOmVsZW1lbnQgbmFtZT0iVGltZXN0YW1wIiB0eXBlPSJ4czpkYXRlVGltZSIgbWluT2Nj +dXJzPSIwIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQ29tbWVudCIgdHlwZT0idWE6TG9j +YWxpemVkVGV4dCIgbWluT2NjdXJzPSIwIiBuaWxsYWJsZT0idHJ1ZSIgLz4NCiAgICA8L3hzOnNl +cXVlbmNlPg0KICA8L3hzOmNvbXBsZXhUeXBlPg0KICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3Jk +ZXJTdGF0dXNUeXBlIiB0eXBlPSJ0bnM6V29ya09yZGVyU3RhdHVzVHlwZSIgLz4NCg0KICA8eHM6 +Y29tcGxleFR5cGUgbmFtZT0iTGlzdE9mV29ya09yZGVyU3RhdHVzVHlwZSI+DQogICAgPHhzOnNl +cXVlbmNlPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iV29ya09yZGVyU3RhdHVzVHlwZSIgdHlw +ZT0idG5zOldvcmtPcmRlclN0YXR1c1R5cGUiIG1pbk9jY3Vycz0iMCIgbWF4T2NjdXJzPSJ1bmJv +dW5kZWQiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29t +cGxleFR5cGU+DQogIDx4czplbGVtZW50IG5hbWU9Ikxpc3RPZldvcmtPcmRlclN0YXR1c1R5cGUi +IHR5cGU9InRuczpMaXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiBuaWxsYWJsZT0idHJ1ZSI+PC94 +czplbGVtZW50Pg0KDQogIDx4czpjb21wbGV4VHlwZSBuYW1lPSJXb3JrT3JkZXJUeXBlIj4NCiAg +ICA8eHM6c2VxdWVuY2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJJRCIgdHlwZT0idWE6R3Vp +ZCIgbWluT2NjdXJzPSIwIiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iQXNzZXRJRCIgdHlw +ZT0ieHM6c3RyaW5nIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KICAgICAgPHhz +OmVsZW1lbnQgbmFtZT0iU3RhcnRUaW1lIiB0eXBlPSJ4czpkYXRlVGltZSIgbWluT2NjdXJzPSIw +IiAvPg0KICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iU3RhdHVzQ29tbWVudHMiIHR5cGU9InRuczpM +aXN0T2ZXb3JrT3JkZXJTdGF0dXNUeXBlIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAv +Pg0KICAgIDwveHM6c2VxdWVuY2U+DQogIDwveHM6Y29tcGxleFR5cGU+DQogIDx4czplbGVtZW50 +IG5hbWU9IldvcmtPcmRlclR5cGUiIHR5cGU9InRuczpXb3JrT3JkZXJUeXBlIiAvPg0KDQogIDx4 +czpjb21wbGV4VHlwZSBuYW1lPSJMaXN0T2ZXb3JrT3JkZXJUeXBlIj4NCiAgICA8eHM6c2VxdWVu +Y2U+DQogICAgICA8eHM6ZWxlbWVudCBuYW1lPSJXb3JrT3JkZXJUeXBlIiB0eXBlPSJ0bnM6V29y +a09yZGVyVHlwZSIgbWluT2NjdXJzPSIwIiBtYXhPY2N1cnM9InVuYm91bmRlZCIgbmlsbGFibGU9 +InRydWUiIC8+DQogICAgPC94czpzZXF1ZW5jZT4NCiAgPC94czpjb21wbGV4VHlwZT4NCiAgPHhz +OmVsZW1lbnQgbmFtZT0iTGlzdE9mV29ya09yZGVyVHlwZSIgdHlwZT0idG5zOkxpc3RPZldvcmtP +cmRlclR5cGUiIG5pbGxhYmxlPSJ0cnVlIj48L3hzOmVsZW1lbnQ+DQoNCjwveHM6c2NoZW1hPg== @@ -41096,6 +42100,90 @@ czplbGVtZW50Pg0KDQo8L3hzOnNjaGVtYT4= 1 1 + + Variable_2 + + ns=1;i=3600 + + + 1 + VectorUnion + + + i=47 + + + i=69 + + 3600 + + + //xs:element[@name='VectorUnion'] + + + + i=12 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3603 + + + 1 + VectorWithOptionalFields + + + i=47 + + + i=69 + + 3603 + + + //xs:element[@name='VectorWithOptionalFields'] + + + + i=12 + + -1 + 1 + 1 + + + Variable_2 + + ns=1;i=3623 + + + 1 + MultipleVectors + + + i=47 + + + i=69 + + 3623 + + + //xs:element[@name='MultipleVectors'] + + + + i=12 + + -1 + 1 + 1 + Variable_2 @@ -41278,6 +42366,81 @@ czplbGVtZW50Pg0KDQo8L3hzOnNjaGVtYT4= + + Object_1 + + ns=1;i=3606 + + + 0 + Default JSON + + + i=76 + + 3606 + + + + i=38 + + true + + ns=1;i=3584 + + + + + + Object_1 + + ns=1;i=3607 + + + 0 + Default JSON + + + i=76 + + 3607 + + + + i=38 + + true + + ns=1;i=3585 + + + + + + Object_1 + + ns=1;i=3626 + + + 0 + Default JSON + + + i=76 + + 3626 + + + + i=38 + + true + + ns=1;i=3615 + + + + Object_1 diff --git a/Applications/Quickstarts.Servers/TestData/TestData.Types.bsd b/Applications/Quickstarts.Servers/TestData/TestData.Types.bsd index a2fc611e2..9b0f82f19 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.Types.bsd +++ b/Applications/Quickstarts.Servers/TestData/TestData.Types.bsd @@ -239,6 +239,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Applications/Quickstarts.Servers/TestData/TestData.Types.xsd b/Applications/Quickstarts.Servers/TestData/TestData.Types.xsd index 5d6b17cf8..abf2afc54 100644 --- a/Applications/Quickstarts.Servers/TestData/TestData.Types.xsd +++ b/Applications/Quickstarts.Servers/TestData/TestData.Types.xsd @@ -7,7 +7,7 @@ > - + @@ -235,6 +235,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Applications/Quickstarts.Servers/TestData/TestDataDesign.csv b/Applications/Quickstarts.Servers/TestData/TestDataDesign.csv index d61bd615a..f21636eff 100644 --- a/Applications/Quickstarts.Servers/TestData/TestDataDesign.csv +++ b/Applications/Quickstarts.Servers/TestData/TestDataDesign.csv @@ -2579,3 +2579,51 @@ UserArrayValueDataType_Encoding_DefaultJson,3578,Object Vector_Encoding_DefaultJson,3579,Object WorkOrderStatusType_Encoding_DefaultJson,3580,Object WorkOrderType_Encoding_DefaultJson,3581,Object +ScalarValueObjectType_VectorUnionValue,3582,Variable +ScalarValueObjectType_VectorWithOptionalFieldsValue,3583,Variable +VectorUnion,3584,DataType +VectorWithOptionalFields,3585,DataType +Data_Static_Scalar_VectorUnionValue,3586,Variable +Data_Static_Scalar_VectorWithOptionalFieldsValue,3587,Variable +Data_Dynamic_Scalar_VectorUnionValue,3588,Variable +Data_Dynamic_Scalar_VectorWithOptionalFieldsValue,3589,Variable +VectorUnion_Encoding_DefaultBinary,3590,Object +VectorWithOptionalFields_Encoding_DefaultBinary,3591,Object +TestData_BinarySchema_VectorUnion,3592,Variable +TestData_BinarySchema_VectorUnion_DataTypeVersion,3593,Variable +TestData_BinarySchema_VectorUnion_DictionaryFragment,3594,Variable +TestData_BinarySchema_VectorWithOptionalFields,3595,Variable +TestData_BinarySchema_VectorWithOptionalFields_DataTypeVersion,3596,Variable +TestData_BinarySchema_VectorWithOptionalFields_DictionaryFragment,3597,Variable +VectorUnion_Encoding_DefaultXml,3598,Object +VectorWithOptionalFields_Encoding_DefaultXml,3599,Object +TestData_XmlSchema_VectorUnion,3600,Variable +TestData_XmlSchema_VectorUnion_DataTypeVersion,3601,Variable +TestData_XmlSchema_VectorUnion_DictionaryFragment,3602,Variable +TestData_XmlSchema_VectorWithOptionalFields,3603,Variable +TestData_XmlSchema_VectorWithOptionalFields_DataTypeVersion,3604,Variable +TestData_XmlSchema_VectorWithOptionalFields_DictionaryFragment,3605,Variable +VectorUnion_Encoding_DefaultJson,3606,Object +VectorWithOptionalFields_Encoding_DefaultJson,3607,Object +ArrayValueObjectType_VectorUnionValue,3608,Variable +ArrayValueObjectType_VectorWithOptionalFieldsValue,3609,Variable +Data_Static_Array_VectorUnionValue,3610,Variable +Data_Static_Array_VectorWithOptionalFieldsValue,3611,Variable +Data_Dynamic_Array_VectorUnionValue,3612,Variable +Data_Dynamic_Array_VectorWithOptionalFieldsValue,3613,Variable +ScalarValueObjectType_MultipleVectorsValue,3614,Variable +MultipleVectors,3615,DataType +Data_Static_Scalar_MultipleVectorsValue,3616,Variable +Data_Dynamic_Scalar_MultipleVectorsValue,3617,Variable +MultipleVectors_Encoding_DefaultBinary,3618,Object +TestData_BinarySchema_MultipleVectors,3619,Variable +TestData_BinarySchema_MultipleVectors_DataTypeVersion,3620,Variable +TestData_BinarySchema_MultipleVectors_DictionaryFragment,3621,Variable +MultipleVectors_Encoding_DefaultXml,3622,Object +TestData_XmlSchema_MultipleVectors,3623,Variable +TestData_XmlSchema_MultipleVectors_DataTypeVersion,3624,Variable +TestData_XmlSchema_MultipleVectors_DictionaryFragment,3625,Variable +MultipleVectors_Encoding_DefaultJson,3626,Object +ArrayValueObjectType_MultipleVectorsValue,3627,Variable +Data_Static_Array_MultipleVectorsValue,3628,Variable +Data_Dynamic_Array_MultipleVectorsValue,3629,Variable diff --git a/Applications/Quickstarts.Servers/TestData/TestDataDesign.xml b/Applications/Quickstarts.Servers/TestData/TestDataDesign.xml index ed59e1d03..aa85572dd 100644 --- a/Applications/Quickstarts.Servers/TestData/TestDataDesign.xml +++ b/Applications/Quickstarts.Servers/TestData/TestDataDesign.xml @@ -258,6 +258,9 @@ + + + @@ -417,6 +420,9 @@ + + + @@ -643,7 +649,7 @@ - - + - + @@ -58,7 +58,7 @@ - + @@ -81,18 +81,18 @@ - + $(BaseIntermediateOutputPath)/zipnodeset2 Schema/Opc.Ua.NodeSet2.xml - + - + diff --git a/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs b/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs index 4dd2815d0..2ffdf3a7d 100644 --- a/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs +++ b/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs @@ -16,6 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; +using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Opc.Ua.Security.Certificates; @@ -110,53 +111,70 @@ public virtual void Update( CertificateTrustList trustedStore, CertificateStoreIdentifier rejectedCertificateStore) { - lock (m_lock) + try { - ResetValidatedCertificates(); + m_semaphore.Wait(); - m_trustedCertificateStore = null; - m_trustedCertificateList = null; + InternalUpdate(issuerStore, trustedStore, rejectedCertificateStore); + } + finally + { + m_semaphore.Release(); + } + } - if (trustedStore != null) - { - m_trustedCertificateStore = new CertificateStoreIdentifier(); + /// + /// Updates the validator with a new set of trust lists. + /// + private void InternalUpdate( + CertificateTrustList issuerStore, + CertificateTrustList trustedStore, + CertificateStoreIdentifier rejectedCertificateStore) + { + InternalResetValidatedCertificates(); - m_trustedCertificateStore.StoreType = trustedStore.StoreType; - m_trustedCertificateStore.StorePath = trustedStore.StorePath; - m_trustedCertificateStore.ValidationOptions = trustedStore.ValidationOptions; + m_trustedCertificateStore = null; + m_trustedCertificateList = null; - if (trustedStore.TrustedCertificates != null) - { - m_trustedCertificateList = new CertificateIdentifierCollection(); - m_trustedCertificateList.AddRange(trustedStore.TrustedCertificates); - } - } + if (trustedStore != null) + { + m_trustedCertificateStore = new CertificateStoreIdentifier(); - m_issuerCertificateStore = null; - m_issuerCertificateList = null; + m_trustedCertificateStore.StoreType = trustedStore.StoreType; + m_trustedCertificateStore.StorePath = trustedStore.StorePath; + m_trustedCertificateStore.ValidationOptions = trustedStore.ValidationOptions; - if (issuerStore != null) + if (trustedStore.TrustedCertificates != null) { - m_issuerCertificateStore = new CertificateStoreIdentifier(); + m_trustedCertificateList = new CertificateIdentifierCollection(); + m_trustedCertificateList.AddRange(trustedStore.TrustedCertificates); + } + } - m_issuerCertificateStore.StoreType = issuerStore.StoreType; - m_issuerCertificateStore.StorePath = issuerStore.StorePath; - m_issuerCertificateStore.ValidationOptions = issuerStore.ValidationOptions; + m_issuerCertificateStore = null; + m_issuerCertificateList = null; - if (issuerStore.TrustedCertificates != null) - { - m_issuerCertificateList = new CertificateIdentifierCollection(); - m_issuerCertificateList.AddRange(issuerStore.TrustedCertificates); - } - } + if (issuerStore != null) + { + m_issuerCertificateStore = new CertificateStoreIdentifier(); - m_rejectedCertificateStore = null; + m_issuerCertificateStore.StoreType = issuerStore.StoreType; + m_issuerCertificateStore.StorePath = issuerStore.StorePath; + m_issuerCertificateStore.ValidationOptions = issuerStore.ValidationOptions; - if (rejectedCertificateStore != null) + if (issuerStore.TrustedCertificates != null) { - m_rejectedCertificateStore = (CertificateStoreIdentifier)rejectedCertificateStore.MemberwiseClone(); + m_issuerCertificateList = new CertificateIdentifierCollection(); + m_issuerCertificateList.AddRange(issuerStore.TrustedCertificates); } } + + m_rejectedCertificateStore = null; + + if (rejectedCertificateStore != null) + { + m_rejectedCertificateStore = (CertificateStoreIdentifier)rejectedCertificateStore.MemberwiseClone(); + } } /// @@ -169,12 +187,15 @@ public virtual async Task Update(SecurityConfiguration configuration) throw new ArgumentNullException(nameof(configuration)); } - lock (m_lock) + try { - Update( + await m_semaphore.WaitAsync().ConfigureAwait(false); + + InternalUpdate( configuration.TrustedIssuerCertificates, configuration.TrustedPeerCertificates, configuration.RejectedCertificateStore); + // protect the flags if application called to set property if ((m_protectFlags & ProtectFlags.AutoAcceptUntrustedCertificates) == 0) { @@ -197,6 +218,10 @@ public virtual async Task Update(SecurityConfiguration configuration) m_useValidatedCertificates = configuration.UseValidatedCertificates; } } + finally + { + m_semaphore.Release(); + } if (configuration.ApplicationCertificate != null) { @@ -209,13 +234,20 @@ public virtual async Task Update(SecurityConfiguration configuration) /// public virtual async Task UpdateCertificate(SecurityConfiguration securityConfiguration) { - lock (m_lock) + try { + await m_semaphore.WaitAsync().ConfigureAwait(false); + securityConfiguration.ApplicationCertificate.Certificate = null; + + await securityConfiguration.ApplicationCertificate.LoadPrivateKeyEx( + securityConfiguration.CertificatePasswordProvider).ConfigureAwait(false); + } + finally + { + m_semaphore.Release(); } - await securityConfiguration.ApplicationCertificate.LoadPrivateKeyEx( - securityConfiguration.CertificatePasswordProvider).ConfigureAwait(false); await Update(securityConfiguration).ConfigureAwait(false); lock (m_callbackLock) @@ -233,15 +265,29 @@ await securityConfiguration.ApplicationCertificate.LoadPrivateKeyEx( /// public void ResetValidatedCertificates() { - lock (m_lock) + try { - // dispose outdated list - foreach (var cert in m_validatedCertificates.Values) - { - Utils.SilentDispose(cert); - } - m_validatedCertificates.Clear(); + m_semaphore.Wait(); + + InternalResetValidatedCertificates(); + } + finally + { + m_semaphore.Release(); + } + } + + /// + /// Reset the list of validated certificates. + /// + private void InternalResetValidatedCertificates() + { + // dispose outdated list + foreach (var cert in m_validatedCertificates.Values) + { + Utils.SilentDispose(cert); } + m_validatedCertificates.Clear(); } /// @@ -252,15 +298,21 @@ public bool AutoAcceptUntrustedCertificates get => m_autoAcceptUntrustedCertificates; set { - lock (m_lock) + try { + m_semaphore.Wait(); + m_protectFlags |= ProtectFlags.AutoAcceptUntrustedCertificates; if (m_autoAcceptUntrustedCertificates != value) { m_autoAcceptUntrustedCertificates = value; - ResetValidatedCertificates(); + InternalResetValidatedCertificates(); } } + finally + { + m_semaphore.Release(); + } } } @@ -272,15 +324,21 @@ public bool RejectSHA1SignedCertificates get => m_rejectSHA1SignedCertificates; set { - lock (m_lock) + try { + m_semaphore.Wait(); + m_protectFlags |= ProtectFlags.RejectSHA1SignedCertificates; if (m_rejectSHA1SignedCertificates != value) { m_rejectSHA1SignedCertificates = value; - ResetValidatedCertificates(); + InternalResetValidatedCertificates(); } } + finally + { + m_semaphore.Release(); + } } } @@ -292,15 +350,21 @@ public bool RejectUnknownRevocationStatus get => m_rejectUnknownRevocationStatus; set { - lock (m_lock) + try { + m_semaphore.Wait(); + m_protectFlags |= ProtectFlags.RejectUnknownRevocationStatus; if (m_rejectUnknownRevocationStatus != value) { m_rejectUnknownRevocationStatus = value; - ResetValidatedCertificates(); + InternalResetValidatedCertificates(); } } + finally + { + m_semaphore.Release(); + } } } @@ -312,8 +376,10 @@ public ushort MinimumCertificateKeySize get => m_minimumCertificateKeySize; set { - lock (m_lock) + try { + m_semaphore.Wait(); + m_protectFlags |= ProtectFlags.MinimumCertificateKeySize; if (m_minimumCertificateKeySize != value) { @@ -321,6 +387,10 @@ public ushort MinimumCertificateKeySize ResetValidatedCertificates(); } } + finally + { + m_semaphore.Release(); + } } } @@ -332,8 +402,10 @@ public bool UseValidatedCertificates get => m_useValidatedCertificates; set { - lock (m_lock) + try { + m_semaphore.Wait(); + m_protectFlags |= ProtectFlags.UseValidatedCertificates; if (m_useValidatedCertificates != value) { @@ -341,6 +413,11 @@ public bool UseValidatedCertificates ResetValidatedCertificates(); } } + finally + { + m_semaphore.Release(); + } + } } @@ -357,7 +434,7 @@ public void Validate(X509Certificate2 certificate) /// Validates a certificate. /// /// - /// Each UA application may have a list of trusted certificates that is different from + /// Each UA application may have a list of trusted certificates that is different from /// all other UA applications that may be running on the same machine. As a result, the /// certificate validator cannot rely completely on the Windows certificate store and /// user or machine specific CTLs (certificate trust lists). @@ -367,113 +444,196 @@ public virtual void Validate(X509Certificate2Collection chain) Validate(chain, null); } + /// + public Task ValidateAsync(X509Certificate2 certificate, CancellationToken ct) + { + return ValidateAsync(new X509Certificate2Collection() { certificate }, ct); + } + + /// + public virtual Task ValidateAsync(X509Certificate2Collection chain, CancellationToken ct) + { + return ValidateAsync(chain, null, ct); + } + /// /// Validates a certificate with domain validation check. - /// + /// /// - public virtual void Validate(X509Certificate2Collection chain, ConfiguredEndpoint endpoint) + public virtual async Task ValidateAsync(X509Certificate2Collection chain, ConfiguredEndpoint endpoint, CancellationToken ct) { X509Certificate2 certificate = chain[0]; try { - lock (m_lock) + try { - InternalValidate(chain, endpoint).GetAwaiter().GetResult(); + await m_semaphore.WaitAsync(ct).ConfigureAwait(false); + + await InternalValidate(chain, endpoint, ct).ConfigureAwait(false); // add to list of validated certificates. m_validatedCertificates[certificate.Thumbprint] = new X509Certificate2(certificate.RawData); + + return; + } + finally + { + m_semaphore.Release(); } } catch (ServiceResultException se) { - // check for errors that may be suppressed. - if (ContainsUnsuppressibleSC(se.Result)) + HandleCertificateValidationException(se, certificate, chain); + } + + // add to list of peers. + try + { + await m_semaphore.WaitAsync(ct).ConfigureAwait(false); + + Utils.LogCertificate(LogLevel.Warning, "Validation errors suppressed: ", certificate); + m_validatedCertificates[certificate.Thumbprint] = new X509Certificate2(certificate.RawData); + } + finally + { + m_semaphore.Release(); + } + } + + /// + /// Validates a certificate with domain validation check. + /// + /// + public virtual void Validate(X509Certificate2Collection chain, ConfiguredEndpoint endpoint) + { + X509Certificate2 certificate = chain[0]; + + try + { + try { - Utils.LogCertificate(LogLevel.Error, "Certificate rejected. Reason={0}.", - certificate, se.Result.StatusCode); + m_semaphore.Wait(); + + InternalValidate(chain, endpoint).GetAwaiter().GetResult(); - // save the chain in rejected store to allow to add certs to a trusted or issuer store - SaveCertificates(chain); + // add to list of validated certificates. + m_validatedCertificates[certificate.Thumbprint] = new X509Certificate2(certificate.RawData); - LogInnerServiceResults(LogLevel.Error, se.Result.InnerResult); - throw new ServiceResultException(se, StatusCodes.BadCertificateInvalid); + return; } - else + finally { - Utils.LogCertificate(LogLevel.Warning, "Certificate Validation failed. Reason={0}.", - certificate, se.Result.StatusCode); - LogInnerServiceResults(LogLevel.Warning, se.Result.InnerResult); + m_semaphore.Release(); } + } + catch (ServiceResultException se) + { + HandleCertificateValidationException(se, certificate, chain); + } - // invoke callback. - bool accept = false; - string applicationErrorMsg = string.Empty; + // add to list of peers. + try + { + m_semaphore.Wait(); - ServiceResult serviceResult = se.Result; - lock (m_callbackLock) + Utils.LogCertificate(LogLevel.Warning, "Validation errors suppressed: ", certificate); + m_validatedCertificates[certificate.Thumbprint] = new X509Certificate2(certificate.RawData); + } + finally + { + m_semaphore.Release(); + } + } + + /// + /// + /// + /// + /// + /// + /// + private void HandleCertificateValidationException(ServiceResultException se, X509Certificate2 certificate, X509Certificate2Collection chain) + { + // check for errors that may be suppressed. + if (ContainsUnsuppressibleSC(se.Result)) + { + Utils.LogCertificate(LogLevel.Error, "Certificate rejected. Reason={0}.", + certificate, se.Result.StatusCode); + + // save the chain in rejected store to allow to add certs to a trusted or issuer store + SaveCertificates(chain); + + LogInnerServiceResults(LogLevel.Error, se.Result.InnerResult); + throw new ServiceResultException(se, StatusCodes.BadCertificateInvalid); + } + else + { + Utils.LogCertificate(LogLevel.Warning, "Certificate Validation failed. Reason={0}.", + certificate, se.Result.StatusCode); + LogInnerServiceResults(LogLevel.Warning, se.Result.InnerResult); + } + + // invoke callback. + bool accept = false; + string applicationErrorMsg = string.Empty; + + ServiceResult serviceResult = se.Result; + lock (m_callbackLock) + { + do { - do + accept = false; + if (m_CertificateValidation != null) { - accept = false; - if (m_CertificateValidation != null) - { - CertificateValidationEventArgs args = new CertificateValidationEventArgs(serviceResult, certificate); - m_CertificateValidation(this, args); - if (args.AcceptAll) - { - accept = true; - serviceResult = null; - break; - } - applicationErrorMsg = args.ApplicationErrorMsg; - accept = args.Accept; - } - else if (m_autoAcceptUntrustedCertificates && - serviceResult.StatusCode == StatusCodes.BadCertificateUntrusted) + CertificateValidationEventArgs args = new CertificateValidationEventArgs(serviceResult, certificate); + m_CertificateValidation(this, args); + if (args.AcceptAll) { accept = true; - Utils.LogCertificate("Auto accepted certificate: ", certificate); + serviceResult = null; + break; } + applicationErrorMsg = args.ApplicationErrorMsg; + accept = args.Accept; + } + else if (m_autoAcceptUntrustedCertificates && + serviceResult.StatusCode == StatusCodes.BadCertificateUntrusted) + { + accept = true; + Utils.LogCertificate("Auto accepted certificate: ", certificate); + } - if (accept) + if (accept) + { + serviceResult = serviceResult.InnerResult; + } + else + { + // report the rejected service result + if (string.IsNullOrEmpty(applicationErrorMsg)) { - serviceResult = serviceResult.InnerResult; + se = new ServiceResultException(serviceResult); } else { - // report the rejected service result - if (string.IsNullOrEmpty(applicationErrorMsg)) - { - se = new ServiceResultException(serviceResult); - } - else - { - se = new ServiceResultException(applicationErrorMsg); - } + se = new ServiceResultException(applicationErrorMsg); } - } while (accept && serviceResult != null); - } - - // throw if rejected. - if (!accept) - { - // write the invalid certificate chain to rejected store if specified. - Utils.LogCertificate(LogLevel.Error, "Certificate rejected. Reason={0}.", - certificate, serviceResult != null ? serviceResult.StatusCode.ToString() : "Unknown Error"); + } + } while (accept && serviceResult != null); + } - // save the chain in rejected store to allow to add cert to a trusted or issuer store - SaveCertificates(chain); + // throw if rejected. + if (!accept) + { + // write the invalid certificate chain to rejected store if specified. + Utils.LogCertificate(LogLevel.Error, "Certificate rejected. Reason={0}.", + certificate, serviceResult != null ? serviceResult.StatusCode.ToString() : "Unknown Error"); - throw new ServiceResultException(se, StatusCodes.BadCertificateInvalid); - } + // save the chain in rejected store to allow to add cert to a trusted or issuer store + SaveCertificates(chain); - // add to list of peers. - lock (m_lock) - { - Utils.LogCertificate(LogLevel.Warning, "Validation errors suppressed: ", certificate); - m_validatedCertificates[certificate.Thumbprint] = new X509Certificate2(certificate.RawData); - } + throw new ServiceResultException(se, StatusCodes.BadCertificateInvalid); } } @@ -524,8 +684,10 @@ private void SaveCertificate(X509Certificate2 certificate) /// private void SaveCertificates(X509Certificate2Collection certificateChain) { - lock (m_lock) + try { + m_semaphore.Wait(); + if (m_rejectedCertificateStore != null) { Utils.LogTrace("Writing rejected certificate chain to: {0}", m_rejectedCertificateStore); @@ -564,6 +726,10 @@ private void SaveCertificates(X509Certificate2Collection certificateChain) } } } + finally + { + m_semaphore.Release(); + } } /// @@ -923,8 +1089,9 @@ await GetIssuerNoException(certificate, explicitList, certificateStore, checkRec /// /// The certificates to be checked. /// The endpoint for domain validation. + /// The cancellation token. /// If certificate[0] cannot be accepted - protected virtual async Task InternalValidate(X509Certificate2Collection certificates, ConfiguredEndpoint endpoint) + protected virtual async Task InternalValidate(X509Certificate2Collection certificates, ConfiguredEndpoint endpoint, CancellationToken ct = default) { X509Certificate2 certificate = certificates[0]; @@ -959,7 +1126,7 @@ protected virtual async Task InternalValidate(X509Certificate2Collection certifi #if NET5_0_OR_GREATER DisableCertificateDownloads = true, #endif - }; + }; foreach (CertificateIdentifier issuer in issuers) { @@ -1347,8 +1514,8 @@ private static ServiceResult CheckChainStatus(X509ChainStatus status, Certificat goto case X509ChainStatusFlags.UntrustedRoot; case X509ChainStatusFlags.UntrustedRoot: { - // self signed cert signature validation - // .NET Core ChainStatus returns NotSignatureValid only on Windows, + // self signed cert signature validation + // .NET Core ChainStatus returns NotSignatureValid only on Windows, // so we have to do the extra cert signature check on all platforms if (issuer == null && id.Certificate != null && X509Utils.IsSelfSigned(id.Certificate)) @@ -1583,7 +1750,7 @@ private enum ProtectFlags #endregion #region Private Fields - private object m_lock = new object(); + private SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1); private object m_callbackLock = new object(); private Dictionary m_validatedCertificates; private CertificateStoreIdentifier m_trustedCertificateStore; @@ -1613,7 +1780,7 @@ public class CertificateValidationEventArgs : EventArgs /// /// Creates a new instance. /// - internal CertificateValidationEventArgs(ServiceResult error, X509Certificate2 certificate) + public CertificateValidationEventArgs(ServiceResult error, X509Certificate2 certificate) { m_error = error; m_certificate = certificate; @@ -1686,7 +1853,7 @@ public class CertificateUpdateEventArgs : EventArgs /// /// Creates a new instance. /// - internal CertificateUpdateEventArgs( + public CertificateUpdateEventArgs( SecurityConfiguration configuration, ICertificateValidator validator) { diff --git a/Stack/Opc.Ua.Core/Security/Certificates/ICertificateValidator.cs b/Stack/Opc.Ua.Core/Security/Certificates/ICertificateValidator.cs index 3219da61c..256350525 100644 --- a/Stack/Opc.Ua.Core/Security/Certificates/ICertificateValidator.cs +++ b/Stack/Opc.Ua.Core/Security/Certificates/ICertificateValidator.cs @@ -11,6 +11,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; namespace Opc.Ua { @@ -29,5 +31,14 @@ public interface ICertificateValidator /// void Validate(X509Certificate2Collection certificateChain); + /// + /// Validates a certificate. + /// + Task ValidateAsync(X509Certificate2 certificate, CancellationToken ct); + + /// + /// Validates a certificate chain. + /// + Task ValidateAsync(X509Certificate2Collection certificateChain, CancellationToken ct); } } diff --git a/Stack/Opc.Ua.Core/Security/Certificates/X509Utils.cs b/Stack/Opc.Ua.Core/Security/Certificates/X509Utils.cs index 7feb23fcf..13121065f 100644 --- a/Stack/Opc.Ua.Core/Security/Certificates/X509Utils.cs +++ b/Stack/Opc.Ua.Core/Security/Certificates/X509Utils.cs @@ -17,6 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; +using System.Threading; using System.Threading.Tasks; using Opc.Ua.Security.Certificates; @@ -561,6 +562,43 @@ public static X509Certificate2 AddToStore( return certificate; } + /// e + /// Extension to add a certificate to a . + /// + /// + /// Saves also the private key, if available. + /// If written to a Pfx file, the password is used for protection. + /// + /// The certificate to store. + /// Type of certificate store (Directory) . + /// The store path (syntax depends on storeType). + /// The password to use to protect the certificate. + /// The cancellation token. + public static async Task AddToStoreAsync( + this X509Certificate2 certificate, + string storeType, + string storePath, + string password = null, + CancellationToken ct = default) + { + // add cert to the store. + if (!String.IsNullOrEmpty(storePath) && !String.IsNullOrEmpty(storeType)) + { + using (ICertificateStore store = Opc.Ua.CertificateStoreIdentifier.CreateStore(storeType)) + { + if (store == null) + { + throw new ArgumentException("Invalid store type"); + } + + store.Open(storePath, false); + await store.Add(certificate, password).ConfigureAwait(false); + store.Close(); + } + } + return certificate; + } + /// /// Get the hash algorithm from the hash size in bits. /// diff --git a/Stack/Opc.Ua.Core/Stack/Bindings/ArraySegmentStream.cs b/Stack/Opc.Ua.Core/Stack/Bindings/ArraySegmentStream.cs index 86b39a118..93d61973e 100644 --- a/Stack/Opc.Ua.Core/Stack/Bindings/ArraySegmentStream.cs +++ b/Stack/Opc.Ua.Core/Stack/Bindings/ArraySegmentStream.cs @@ -225,7 +225,10 @@ public override long Seek(long offset, SeekOrigin origin) int position = (int)offset; - CheckEndOfStream(); + if (position >= GetAbsolutePosition()) + { + CheckEndOfStream(); + } for (int ii = 0; ii < m_buffers.Count; ii++) { diff --git a/Stack/Opc.Ua.Core/Stack/Client/ClientBase.cs b/Stack/Opc.Ua.Core/Stack/Client/ClientBase.cs index 48c349e85..7d6a00faf 100644 --- a/Stack/Opc.Ua.Core/Stack/Client/ClientBase.cs +++ b/Stack/Opc.Ua.Core/Stack/Client/ClientBase.cs @@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. using System; using System.Collections; using System.Threading; +using System.Threading.Tasks; namespace Opc.Ua { @@ -274,6 +275,21 @@ public virtual StatusCode Close() return StatusCodes.Good; } + /// + /// Closes the channel using async call. + /// + public virtual Task CloseAsync(CancellationToken ct = default) + { + if (m_channel != null) + { + m_channel.Close(); + m_channel = null; + } + + m_authenticationToken = null; + return Task.FromResult(StatusCodes.Good); + } + /// /// Whether the object has been disposed. /// diff --git a/Stack/Opc.Ua.Core/Stack/Client/DiscoveryClient.cs b/Stack/Opc.Ua.Core/Stack/Client/DiscoveryClient.cs index d81e89ca2..1cc658329 100644 --- a/Stack/Opc.Ua.Core/Stack/Client/DiscoveryClient.cs +++ b/Stack/Opc.Ua.Core/Stack/Client/DiscoveryClient.cs @@ -162,6 +162,7 @@ public virtual EndpointDescriptionCollection GetEndpoints(StringCollection profi return PatchEndpointUrls(endpoints); } +#if NET_STANDARD_ASYNC /// /// Invokes the GetEndpoints service async. /// @@ -172,6 +173,7 @@ public async virtual Task GetEndpointsAsync(Strin var response = await GetEndpointsAsync(null, this.Endpoint.EndpointUrl, null, profileUris, ct).ConfigureAwait(false); return PatchEndpointUrls(response.Endpoints); } +#endif /// /// Invokes the FindServers service. @@ -192,6 +194,7 @@ public virtual ApplicationDescriptionCollection FindServers(StringCollection ser return servers; } +#if NET_STANDARD_ASYNC /// /// Invokes the FindServers service async. /// @@ -208,6 +211,7 @@ public virtual async Task FindServersAsync(Str ct).ConfigureAwait(false); return response.Servers; } +#endif /// /// Invokes the FindServersOnNetwork service. diff --git a/Stack/Opc.Ua.Core/Stack/Client/UaChannelBase.cs b/Stack/Opc.Ua.Core/Stack/Client/UaChannelBase.cs index bb7ba59ee..e58105a9e 100644 --- a/Stack/Opc.Ua.Core/Stack/Client/UaChannelBase.cs +++ b/Stack/Opc.Ua.Core/Stack/Client/UaChannelBase.cs @@ -439,6 +439,19 @@ public IServiceResponse EndSendRequest(IAsyncResult result) #endif } + /// + /// Completes an asynchronous operation to send a request over the secure channel. + /// + public Task EndSendRequestAsync(IAsyncResult result, CancellationToken ct) + { + if (m_uaBypassChannel != null) + { + return m_uaBypassChannel.EndSendRequestAsync(result, ct); + } + + throw new NotImplementedException(); + } + /// /// Sends a request over the secure channel. /// diff --git a/Stack/Opc.Ua.Core/Stack/Configuration/ConfiguredEndpoints.cs b/Stack/Opc.Ua.Core/Stack/Configuration/ConfiguredEndpoints.cs index 654ef40f2..32eefd215 100644 --- a/Stack/Opc.Ua.Core/Stack/Configuration/ConfiguredEndpoints.cs +++ b/Stack/Opc.Ua.Core/Stack/Configuration/ConfiguredEndpoints.cs @@ -1110,6 +1110,7 @@ public void UpdateFromServer( } } +#if NET_STANDARD_ASYNC /// /// Updates an endpoint with information from the server's discovery endpoint. /// @@ -1175,9 +1176,10 @@ public async Task UpdateFromServerAsync( } finally { - client.Close(); + await client.CloseAsync(ct).ConfigureAwait(false); } } +#endif /// /// Returns a discovery url that can be used to update the endpoint description. @@ -1207,7 +1209,7 @@ public Uri GetDiscoveryUrl(Uri endpointUrl) { if (endpointUrl.Scheme.StartsWith(Utils.UriSchemeHttp, StringComparison.Ordinal)) { - return new Uri(String.Format(CultureInfo.InvariantCulture, "{0}"+ kDiscoverySuffix, endpointUrl)); + return new Uri(String.Format(CultureInfo.InvariantCulture, "{0}" + kDiscoverySuffix, endpointUrl)); } else { diff --git a/Stack/Opc.Ua.Core/Stack/Nodes/TypeTable.cs b/Stack/Opc.Ua.Core/Stack/Nodes/TypeTable.cs index e5aa6b4ed..fc2294a31 100644 --- a/Stack/Opc.Ua.Core/Stack/Nodes/TypeTable.cs +++ b/Stack/Opc.Ua.Core/Stack/Nodes/TypeTable.cs @@ -11,6 +11,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace Opc.Ua { @@ -128,6 +130,18 @@ public NodeId FindSuperType(NodeId typeId) } } + /// + public Task FindSuperTypeAsync(ExpandedNodeId typeId, CancellationToken ct) + { + return Task.FromResult(FindSuperType(typeId)); + } + + /// + public Task FindSuperTypeAsync(NodeId typeId, CancellationToken ct) + { + return Task.FromResult(FindSuperType(typeId)); + } + /// public IList FindSubTypes(ExpandedNodeId typeId) { @@ -535,7 +549,7 @@ public void Add(ILocalNode node) } } - // any new encodings. + // any new encodings. IList encodings = node.References.Find(ReferenceTypeIds.HasEncoding, false, false, null); if (encodings.Count > 0) diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/ChannelAsyncOperation.cs b/Stack/Opc.Ua.Core/Stack/Tcp/ChannelAsyncOperation.cs index 5ddb1a1a5..efc962edf 100644 --- a/Stack/Opc.Ua.Core/Stack/Tcp/ChannelAsyncOperation.cs +++ b/Stack/Opc.Ua.Core/Stack/Tcp/ChannelAsyncOperation.cs @@ -68,6 +68,15 @@ protected virtual void Dispose(bool disposing) m_event.Dispose(); m_event = null; } + + if (m_tcs != null) + { + if (!m_tcs.Task.IsCompleted) + { + m_tcs.TrySetCanceled(); + } + m_tcs = null; + } } } } @@ -192,6 +201,98 @@ public T End(int timeout, bool throwOnError = true) } } + /// + /// The awaitable response returned from the server. + /// + public async Task EndAsync(int timeout, bool throwOnError = true, CancellationToken ct = default) + { + // check if the request has already completed. + bool mustWait = false; + + lock (m_lock) + { + mustWait = !m_completed; + + if (mustWait) + { + m_tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + } + } + + // wait for completion. + if (mustWait) + { + bool badRequestInterrupted = false; + try + { + Task awaitableTask = m_tcs.Task; +#if NET6_0_OR_GREATER + if (timeout != Int32.MaxValue) + { + awaitableTask = m_tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(timeout), ct); + } + else if (ct != default) + { + awaitableTask = m_tcs.Task.WaitAsync(ct); + } +#else + if (timeout != Int32.MaxValue || ct != default) + { + Task completedTask = await Task.WhenAny(m_tcs.Task, Task.Delay(timeout, ct)).ConfigureAwait(false); + if (m_tcs.Task == completedTask) + { + if (!m_tcs.Task.Result) + { + badRequestInterrupted = true; + } + } + else + { + m_tcs.TrySetCanceled(); + badRequestInterrupted = true; + } + } + else +#endif + if (!await awaitableTask.ConfigureAwait(false)) + { + badRequestInterrupted = true; + } + } + catch (TimeoutException) + { + badRequestInterrupted = true; + } + catch (TaskCanceledException) + { + badRequestInterrupted = true; + } + finally + { + lock (m_lock) + { + m_tcs = null; + } + } + + if (badRequestInterrupted && throwOnError) + { + throw new ServiceResultException(StatusCodes.BadRequestInterrupted); + } + } + + // return the response. + lock (m_lock) + { + if (m_error != null && throwOnError) + { + throw new ServiceResultException(m_error); + } + + return m_response; + } + } + /// /// Stores additional state information associated with the operation. /// @@ -210,7 +311,7 @@ public IDictionary Properties } } } - #endregion +#endregion #region IAsyncResult Members /// @@ -313,14 +414,18 @@ protected virtual bool InternalComplete(bool doNotBlock, object result) { m_event.Set(); } + + if (m_tcs != null) + { + m_tcs.TrySetResult(true); + } } if (m_callback != null) { if (doNotBlock) { - Task.Run(() => - { + Task.Run(() => { m_callback(this); }); } @@ -348,6 +453,7 @@ protected virtual bool InternalComplete(bool doNotBlock, object result) private bool m_synchronous; private bool m_completed; private ManualResetEvent m_event; + private TaskCompletionSource m_tcs; private T m_response; private ServiceResult m_error; private Timer m_timer; diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Asymmetric.cs b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Asymmetric.cs index 273dc0196..becf10e83 100644 --- a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Asymmetric.cs +++ b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Asymmetric.cs @@ -284,7 +284,7 @@ protected int GetAsymmetricHeaderSize( if (securityPolicyUri != null) { - headerSize += new UTF8Encoding().GetByteCount(securityPolicyUri); + headerSize += Encoding.UTF8.GetByteCount(securityPolicyUri); } headerSize += TcpMessageLimits.StringLengthSize; @@ -323,7 +323,7 @@ protected int GetAsymmetricHeaderSize( if (securityPolicyUri != null) { - headerSize += new UTF8Encoding().GetByteCount(securityPolicyUri); + headerSize += Encoding.UTF8.GetByteCount(securityPolicyUri); } headerSize += TcpMessageLimits.StringLengthSize; @@ -473,7 +473,7 @@ private int GetMaxSenderCertificateSize(X509Certificate2 senderCertificate, stri if (securityPolicyUri != null) { - occupiedSize += new UTF8Encoding().GetByteCount(securityPolicyUri); //security policy uri size + occupiedSize += Encoding.UTF8.GetByteCount(securityPolicyUri); //security policy uri size } occupiedSize += TcpMessageLimits.StringLengthSize; //SenderCertificateLength diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Rsa.cs b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Rsa.cs index f609a5231..527a270d6 100644 --- a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Rsa.cs +++ b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Rsa.cs @@ -67,7 +67,7 @@ private static bool Rsa_Verify( // verify signature. if (!rsa.VerifyData(dataToVerify.Array, dataToVerify.Offset, dataToVerify.Count, signature, algorithm, padding)) { - string messageType = new UTF8Encoding().GetString(dataToVerify.Array, dataToVerify.Offset, 4); + string messageType = Encoding.UTF8.GetString(dataToVerify.Array, dataToVerify.Offset, 4); int messageLength = BitConverter.ToInt32(dataToVerify.Array, dataToVerify.Offset + 4); string actualSignature = Utils.ToHexString(signature); Utils.LogError("Could not validate signature."); diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Symmetric.cs b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Symmetric.cs index 5335ab0e6..b0acce037 100644 --- a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Symmetric.cs +++ b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Symmetric.cs @@ -736,7 +736,7 @@ private bool SymmetricVerify( { if (computedSignature[ii] != signature[ii]) { - string messageType = new UTF8Encoding().GetString(dataToVerify.Array, dataToVerify.Offset, 4); + string messageType = Encoding.UTF8.GetString(dataToVerify.Array, dataToVerify.Offset, 4); int messageLength = BitConverter.ToInt32(dataToVerify.Array, dataToVerify.Offset + 4); string expectedSignature = Utils.ToHexString(computedSignature); string actualSignature = Utils.ToHexString(signature); diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.cs b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.cs index f5c1c0ae5..8c17419ca 100644 --- a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.cs +++ b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.cs @@ -82,7 +82,7 @@ public UaSCUaBinaryChannel( } } - if (new UTF8Encoding().GetByteCount(securityPolicyUri) > TcpMessageLimits.MaxSecurityPolicyUriSize) + if (Encoding.UTF8.GetByteCount(securityPolicyUri) > TcpMessageLimits.MaxSecurityPolicyUriSize) { throw new ArgumentException( Utils.Format("UTF-8 form of the security policy URI may not be more than {0} bytes.", TcpMessageLimits.MaxSecurityPolicyUriSize), @@ -540,11 +540,9 @@ protected static void WriteErrorMessageBody(BinaryEncoder encoder, ServiceResult // check that length is not exceeded. if (reason != null) { - UTF8Encoding encoding = new UTF8Encoding(); - - if (encoding.GetByteCount(reason) > TcpMessageLimits.MaxErrorReasonLength) + if (Encoding.UTF8.GetByteCount(reason) > TcpMessageLimits.MaxErrorReasonLength) { - reason = reason.Substring(0, TcpMessageLimits.MaxErrorReasonLength / encoding.GetMaxByteCount(1)); + reason = reason.Substring(0, TcpMessageLimits.MaxErrorReasonLength / Encoding.UTF8.GetMaxByteCount(1)); } } @@ -574,7 +572,12 @@ protected static ServiceResult ReadErrorMessageBody(BinaryDecoder decoder) reasonBytes[ii] = decoder.ReadByte(null); } - reason = new UTF8Encoding().GetString(reasonBytes, 0, reasonLength); + reason = Encoding.UTF8.GetString(reasonBytes, 0, reasonLength); + } + + if (reason == null) + { + reason = new ServiceResult(statusCode).ToString(); } return ServiceResult.Create(statusCode, "Error received from remote host: {0}", reason); diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryClientChannel.cs b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryClientChannel.cs index a3e1bd860..b9a6a441a 100644 --- a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryClientChannel.cs +++ b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryClientChannel.cs @@ -159,7 +159,6 @@ public IAsyncResult BeginConnect(Uri url, int timeout, AsyncCallback callback, o using (var cts = new CancellationTokenSource(timeout)) { await (Socket?.BeginConnect(m_via, m_ConnectCallback, operation, cts.Token) ?? Task.FromResult(false)).ConfigureAwait(false); - } }); } @@ -191,38 +190,78 @@ public void EndConnect(IAsyncResult result) } } + /// + /// Finishes a connect operation. + /// + public async Task EndConnectAsync(IAsyncResult result, CancellationToken ct = default) + { + var operation = result as WriteOperation; + if (operation == null) throw new ArgumentNullException(nameof(result)); + + try + { + await operation.EndAsync(Int32.MaxValue, true, ct).ConfigureAwait(false); + Utils.LogInfo("CLIENTCHANNEL SOCKET CONNECTED: {0:X8}, ChannelId={1}", Socket.Handle, ChannelId); + } + catch (Exception e) + { + Shutdown(ServiceResult.Create(e, StatusCodes.BadTcpInternalError, "Fatal error during connect.")); + throw; + } + finally + { + OperationCompleted(operation); + } + } + /// /// Closes a connection with the server. /// - public void Close(int timeout) + public async Task CloseAsync(int timeout, CancellationToken ct = default) { - WriteOperation operation = null; + WriteOperation operation = InternalClose(timeout); - lock (DataLock) + // wait for the close to succeed. + if (operation != null) { - // nothing to do if the connection is already closed. - if (State == TcpChannelState.Closed) + try { - return; + await operation.EndAsync(timeout, false, ct).ConfigureAwait(false); } - - // check if a handshake is in progress. - if (m_handshakeOperation != null && !m_handshakeOperation.IsCompleted) + catch (ServiceResultException e) { - m_handshakeOperation.Fault(ServiceResult.Create(StatusCodes.BadConnectionClosed, "Channel was closed by the user.")); - } - - Utils.LogTrace("ChannelId {0}: Close", ChannelId); + switch (e.StatusCode) + { + case StatusCodes.BadRequestInterrupted: + case StatusCodes.BadSecureChannelClosed: + { + break; + } - // attempt a graceful shutdown. - if (State == TcpChannelState.Open) + default: + { + Utils.LogWarning(e, "ChannelId {0}: Could not gracefully close the channel. Reason={1}", ChannelId, e.Result.StatusCode); + break; + } + } + } + catch (Exception e) { - State = TcpChannelState.Closing; - operation = BeginOperation(timeout, null, null); - SendCloseSecureChannelRequest(operation); + Utils.LogError(e, "ChannelId {0}: Could not gracefully close the channel.", ChannelId); } } + // shutdown. + Shutdown(StatusCodes.BadConnectionClosed); + } + + /// + /// Closes a connection with the server. + /// + public void Close(int timeout) + { + WriteOperation operation = InternalClose(timeout); + // wait for the close to succeed. if (operation != null) { @@ -343,6 +382,30 @@ public IServiceResponse EndSendRequest(IAsyncResult result) return operation.MessageBody as IServiceResponse; } + + /// + /// Returns the response to a previously sent request. + /// + public async Task EndSendRequestAsync(IAsyncResult result, CancellationToken ct) + { + WriteOperation operation = result as WriteOperation; + + if (operation == null) + { + throw new ArgumentNullException(nameof(result)); + } + + try + { + await operation.EndAsync(Int32.MaxValue, true, ct).ConfigureAwait(false); + } + finally + { + OperationCompleted(operation); + } + + return operation.MessageBody as IServiceResponse; + } #endregion #region Connect/Reconnect Sequence @@ -1081,8 +1144,6 @@ private void ForceReconnect(ServiceResult reason) return; } - Utils.LogWarning("ChannelId {0}: Force reconnect reason={1}", Id, reason); - // check if reconnects are disabled. if (State == TcpChannelState.Closing || m_waitBetweenReconnects == Timeout.Infinite) { @@ -1090,6 +1151,8 @@ private void ForceReconnect(ServiceResult reason) return; } + Utils.LogWarning("ChannelId {0}: Force reconnect reason={1}", Id, reason); + // cancel all requests. List operations = new List(m_requests.Values); @@ -1275,6 +1338,37 @@ private void OnConnectOnDemandComplete(object state) m_queuedOperations = null; } } + + private WriteOperation InternalClose(int timeout) + { + WriteOperation operation = null; + lock (DataLock) + { + // nothing to do if the connection is already closed. + if (State == TcpChannelState.Closed) + { + return null; + } + + // check if a handshake is in progress. + if (m_handshakeOperation != null && !m_handshakeOperation.IsCompleted) + { + m_handshakeOperation.Fault(ServiceResult.Create(StatusCodes.BadConnectionClosed, "Channel was closed by the user.")); + } + + Utils.LogTrace("ChannelId {0}: Close", ChannelId); + + // attempt a graceful shutdown. + if (State == TcpChannelState.Open) + { + State = TcpChannelState.Closing; + operation = BeginOperation(timeout, null, null); + SendCloseSecureChannelRequest(operation); + } + } + + return operation; + } #endregion #region Message Processing diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryTransportChannel.cs b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryTransportChannel.cs index 583633045..fdbd08f97 100644 --- a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryTransportChannel.cs +++ b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryTransportChannel.cs @@ -331,7 +331,8 @@ public IServiceResponse SendRequest(IServiceRequest request) /// Thrown if any communication error occurs. public Task SendRequestAsync(IServiceRequest request, CancellationToken ct) { - return Task.Factory.FromAsync(BeginSendRequest(request, null, null), EndSendRequest); + var operation = BeginSendRequest(request, null, null); + return EndSendRequestAsync(operation, ct); } /// @@ -384,6 +385,26 @@ public IServiceResponse EndSendRequest(IAsyncResult result) return channel.EndSendRequest(result); } + /// + /// Completes an asynchronous operation to send a request over the secure channel. + /// + /// The result returned from the BeginSendRequest call. + /// + /// + /// Thrown if any communication error occurs. + /// + public Task EndSendRequestAsync(IAsyncResult result, CancellationToken ct) + { + UaSCUaBinaryClientChannel channel = m_channel; + + if (channel == null) + { + throw ServiceResultException.Create(StatusCodes.BadSecureChannelClosed, "Channel has been closed."); + } + + return channel.EndSendRequestAsync(result, ct); + } + /// /// Saves the settings so the channel can be opened later. /// diff --git a/Stack/Opc.Ua.Core/Stack/Transport/ITransportChannel.cs b/Stack/Opc.Ua.Core/Stack/Transport/ITransportChannel.cs index 9b2155028..b23893d0a 100644 --- a/Stack/Opc.Ua.Core/Stack/Transport/ITransportChannel.cs +++ b/Stack/Opc.Ua.Core/Stack/Transport/ITransportChannel.cs @@ -191,6 +191,16 @@ IAsyncResult BeginOpen( /// Thrown if any communication error occurs. /// IServiceResponse EndSendRequest(IAsyncResult result); + + /// + /// Completes an asynchronous operation to send a request over the secure channel. + /// Awaitable version + /// + /// The result returned from the BeginSendRequest call. + /// The cancellation token. + /// Thrown if any communication error occurs. + /// + Task EndSendRequestAsync(IAsyncResult result, CancellationToken ct); } /// diff --git a/Stack/Opc.Ua.Core/Stack/Types/UserIdentityToken.cs b/Stack/Opc.Ua.Core/Stack/Types/UserIdentityToken.cs index cb2409e30..0de5feeaa 100644 --- a/Stack/Opc.Ua.Core/Stack/Types/UserIdentityToken.cs +++ b/Stack/Opc.Ua.Core/Stack/Types/UserIdentityToken.cs @@ -85,13 +85,13 @@ public override void Encrypt(X509Certificate2 certificate, byte[] senderNonce, s // handle no encryption. if (String.IsNullOrEmpty(securityPolicyUri) || securityPolicyUri == SecurityPolicies.None) { - m_password = new UTF8Encoding().GetBytes(m_decryptedPassword); + m_password = Encoding.UTF8.GetBytes(m_decryptedPassword); m_encryptionAlgorithm = null; return; } // encrypt the password. - byte[] dataToEncrypt = Utils.Append(new UTF8Encoding().GetBytes(m_decryptedPassword), senderNonce); + byte[] dataToEncrypt = Utils.Append(Encoding.UTF8.GetBytes(m_decryptedPassword), senderNonce); EncryptedData encryptedData = SecurityPolicies.Encrypt( certificate, @@ -110,7 +110,7 @@ public override void Decrypt(X509Certificate2 certificate, byte[] senderNonce, s // handle no encryption. if (String.IsNullOrEmpty(securityPolicyUri) || securityPolicyUri == SecurityPolicies.None) { - m_decryptedPassword = new UTF8Encoding().GetString(m_password, 0, m_password.Length); + m_decryptedPassword = Encoding.UTF8.GetString(m_password, 0, m_password.Length); return; } @@ -150,7 +150,7 @@ public override void Decrypt(X509Certificate2 certificate, byte[] senderNonce, s } // convert to UTF-8. - m_decryptedPassword = new UTF8Encoding().GetString(decryptedPassword, 0, startOfNonce); + m_decryptedPassword = Encoding.UTF8.GetString(decryptedPassword, 0, startOfNonce); } #endregion diff --git a/Stack/Opc.Ua.Core/Types/BuiltIn/ITypeTable.cs b/Stack/Opc.Ua.Core/Types/BuiltIn/ITypeTable.cs index a6b2a6318..4a00771bc 100644 --- a/Stack/Opc.Ua.Core/Types/BuiltIn/ITypeTable.cs +++ b/Stack/Opc.Ua.Core/Types/BuiltIn/ITypeTable.cs @@ -11,11 +11,13 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace Opc.Ua { /// - /// Stores the type tree for a server. + /// Stores the type tree for a server. /// public interface ITypeTable { @@ -51,6 +53,24 @@ public interface ITypeTable /// The immediate supertype idnetyfier for NodeId FindSuperType(NodeId typeId); +#if (NET_STANDARD_ASYNC) + /// + /// Returns the immediate supertype for the type. + /// + /// The extended type identifier. + /// + /// A type identifier of the + Task FindSuperTypeAsync(ExpandedNodeId typeId, CancellationToken ct = default); + + /// + /// Returns the immediate supertype for the type. + /// + /// The type identifier. + /// + /// The immediate supertype idnetyfier for + Task FindSuperTypeAsync(NodeId typeId, CancellationToken ct = default); +#endif + /// /// Returns the immediate subtypes for the type. /// @@ -93,7 +113,7 @@ public interface ITypeTable NodeId FindReferenceType(QualifiedName browseName); /// - /// Checks if the identifier represents a that provides encodings + /// Checks if the identifier represents a that provides encodings /// for the . /// /// The id the encoding node . @@ -109,7 +129,7 @@ public interface ITypeTable /// The identifier of the expected type . /// The value. /// - /// true if the value contained in an extension object matches the + /// true if the value contained in an extension object matches the /// expected data type; otherwise, false. /// bool IsEncodingFor(NodeId expectedTypeId, ExtensionObject value); diff --git a/Stack/Opc.Ua.Core/Types/BuiltIn/Uuid.cs b/Stack/Opc.Ua.Core/Types/BuiltIn/Uuid.cs index 8e8965074..5089824ca 100644 --- a/Stack/Opc.Ua.Core/Types/BuiltIn/Uuid.cs +++ b/Stack/Opc.Ua.Core/Types/BuiltIn/Uuid.cs @@ -24,7 +24,7 @@ namespace Opc.Ua /// and encoded/decoded to/from an underlying stream. /// x [DataContract(Name = "Guid", Namespace = Namespaces.OpcUaXsd)] - public struct Uuid : IComparable, IFormattable + public struct Uuid : IComparable, IFormattable, IEquatable { #region Constructors /// @@ -207,6 +207,18 @@ public override bool Equals(object obj) return (CompareTo(obj) == 0); } + /// + /// Returns true if the objects are equal. + /// + /// + /// Returns true if the objects are equal. + /// + /// The object being compared to *this* object + public bool Equals(Uuid other) + { + return (CompareTo(other) == 0); + } + /// /// Returns a hash code for the object. /// @@ -247,7 +259,7 @@ public int CompareTo(object obj) return ((Uuid)obj).m_guid.CompareTo(m_guid); } - // compare guids. + // compare guids. if (obj is Guid) { return m_guid.CompareTo((Guid)obj); @@ -274,7 +286,7 @@ public string ToString(string format, IFormatProvider formatProvider) #region Private Fields private Guid m_guid; - #endregion + #endregion } #region UuidCollection Class diff --git a/Stack/Opc.Ua.Core/Types/Encoders/BinaryDecoder.cs b/Stack/Opc.Ua.Core/Types/Encoders/BinaryDecoder.cs index eb9e270e7..b925b8944 100644 --- a/Stack/Opc.Ua.Core/Types/Encoders/BinaryDecoder.cs +++ b/Stack/Opc.Ua.Core/Types/Encoders/BinaryDecoder.cs @@ -2126,22 +2126,31 @@ private ExtensionObject ReadExtensionObject() // verify the decoder did not exceed the length of the encodeable object int used = Position - start; - if (length < used) + if (length != used) { throw ServiceResultException.Create( - StatusCodes.BadEncodingLimitsExceeded, - "The encodeable.Decoder operation exceeded the length of the extension object. {0} > {1}", + StatusCodes.BadDecodingError, + "The encodeable.Decoder operation did not match the length of the extension object. {0} != {1}", used, length); } } - catch (ServiceResultException sre) when (sre.StatusCode == StatusCodes.BadEncodingLimitsExceeded) + catch (EndOfStreamException eofStream) { // type was known but decoding failed, reset stream! m_reader.BaseStream.Position = start; encodeable = null; - Utils.LogWarning(sre, "Failed to decode encodeable type '{0}', NodeId='{1}'. BinaryDecoder recovered.", + Utils.LogWarning(eofStream, "End of stream, failed to decode encodeable type '{0}', NodeId='{1}'. BinaryDecoder recovered.", systemType.Name, extension.TypeId); } + catch (ServiceResultException sre) when + ((sre.StatusCode == StatusCodes.BadEncodingLimitsExceeded) || (sre.StatusCode == StatusCodes.BadDecodingError)) + { + // type was known but decoding failed, reset stream! + m_reader.BaseStream.Position = start; + encodeable = null; + Utils.LogWarning(sre, "{0}, failed to decode encodeable type '{1}', NodeId='{2}'. BinaryDecoder recovered.", + sre.Message, systemType.Name, extension.TypeId); + } finally { m_nestingLevel = nestingLevel; diff --git a/Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs b/Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs index 58a72292c..95a886e60 100644 --- a/Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs +++ b/Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs @@ -90,11 +90,13 @@ protected virtual void Dispose(bool disposing) { m_writer.Flush(); m_writer.Dispose(); + m_writer = null; } if (!m_leaveOpen) { m_ostrm?.Dispose(); + m_ostrm = null; } } } @@ -440,7 +442,7 @@ public void WriteString(string fieldName, string value) return; } - byte[] bytes = new UTF8Encoding().GetBytes(value); + byte[] bytes = Encoding.UTF8.GetBytes(value); if (m_context.MaxStringLength > 0 && m_context.MaxStringLength < bytes.Length) { @@ -451,7 +453,7 @@ public void WriteString(string fieldName, string value) bytes.Length); } - WriteByteString(null, new UTF8Encoding().GetBytes(value)); + WriteByteString(null, Encoding.UTF8.GetBytes(value)); } /// @@ -534,7 +536,7 @@ public void WriteXmlElement(string fieldName, XmlElement value) return; } - WriteByteString(null, new UTF8Encoding().GetBytes(value.OuterXml)); + WriteByteString(null, Encoding.UTF8.GetBytes(value.OuterXml)); } /// diff --git a/Stack/Opc.Ua.Core/Types/Encoders/EncodeableFactory.cs b/Stack/Opc.Ua.Core/Types/Encoders/EncodeableFactory.cs index bebe73356..e9ebdc65a 100644 --- a/Stack/Opc.Ua.Core/Types/Encoders/EncodeableFactory.cs +++ b/Stack/Opc.Ua.Core/Types/Encoders/EncodeableFactory.cs @@ -12,6 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.Serialization; @@ -72,15 +73,31 @@ public EncodeableFactory(IEncodeableFactory factory) #if DEBUG m_instanceId = Interlocked.Increment(ref m_globalInstanceCount); #endif + if (factory != null) + { + m_encodeableTypes = ((EncodeableFactory)factory.Clone()).m_encodeableTypes; + } + } + #endregion - lock (factory.SyncRoot) + #region IDisposable + /// + /// An overrideable version of the Dispose. + /// + protected virtual void Dispose(bool disposing) + { + if (disposing) { - foreach (KeyValuePair current in factory.EncodeableTypes) - { - m_encodeableTypes.Add(current.Key, current.Value); - } + m_readerWriterLockSlim?.Dispose(); } } + + /// + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } #endregion #region Private Members @@ -108,61 +125,85 @@ private void AddEncodeableTypes(string assemblyName) /// A dictionary of unbound typeIds, e.g. JSON type ids referenced by object name. private void AddEncodeableType(Type systemType, Dictionary unboundTypeIds) { - lock (m_lock) + + if (systemType == null) { - if (systemType == null) - { - return; - } + return; + } - if (!typeof(IEncodeable).GetTypeInfo().IsAssignableFrom(systemType.GetTypeInfo())) - { - return; - } + if (!typeof(IEncodeable).GetTypeInfo().IsAssignableFrom(systemType.GetTypeInfo())) + { + return; + } - IEncodeable encodeable = Activator.CreateInstance(systemType) as IEncodeable; + IEncodeable encodeable = Activator.CreateInstance(systemType) as IEncodeable; - if (encodeable == null) - { - return; - } + if (encodeable == null) + { + return; + } #if DEBUG - if (m_shared) - { - Utils.LogTrace("WARNING: Adding type '{0}' to shared Factory #{1}.", systemType.Name, m_instanceId); - } + if (m_shared) + { + Utils.LogTrace("WARNING: Adding type '{0}' to shared Factory #{1}.", systemType.Name, m_instanceId); + } #endif - ExpandedNodeId nodeId = encodeable.TypeId; + // assume write lock + Debug.Assert(m_readerWriterLockSlim.IsWriteLockHeld); - if (!NodeId.IsNull(nodeId)) - { - // check for default namespace. - if (nodeId.NamespaceUri == Namespaces.OpcUa) - { - nodeId = new ExpandedNodeId(nodeId.InnerNodeId); - } + ExpandedNodeId nodeId = encodeable.TypeId; - m_encodeableTypes[nodeId] = systemType; + if (!NodeId.IsNull(nodeId)) + { + // check for default namespace. + if (nodeId.NamespaceUri == Namespaces.OpcUa) + { + nodeId = new ExpandedNodeId(nodeId.InnerNodeId); } - nodeId = encodeable.BinaryEncodingId; + m_encodeableTypes[nodeId] = systemType; + } - if (!NodeId.IsNull(nodeId)) + nodeId = encodeable.BinaryEncodingId; + + if (!NodeId.IsNull(nodeId)) + { + // check for default namespace. + if (nodeId.NamespaceUri == Namespaces.OpcUa) { - // check for default namespace. - if (nodeId.NamespaceUri == Namespaces.OpcUa) - { - nodeId = new ExpandedNodeId(nodeId.InnerNodeId); - } + nodeId = new ExpandedNodeId(nodeId.InnerNodeId); + } - m_encodeableTypes[nodeId] = systemType; + m_encodeableTypes[nodeId] = systemType; + } + + try + { + nodeId = encodeable.XmlEncodingId; + } + catch (NotSupportedException) + { + nodeId = NodeId.Null; + } + + if (!NodeId.IsNull(nodeId)) + { + // check for default namespace. + if (nodeId.NamespaceUri == Namespaces.OpcUa) + { + nodeId = new ExpandedNodeId(nodeId.InnerNodeId); } + m_encodeableTypes[nodeId] = systemType; + } + + if (encodeable is IJsonEncodeable jsonEncodeable) + { try { - nodeId = encodeable.XmlEncodingId; + nodeId = jsonEncodeable.JsonEncodingId; } catch (NotSupportedException) { @@ -179,34 +220,11 @@ private void AddEncodeableType(Type systemType, Dictionary - /// Returns the object used to synchronize access to the factory. - /// - /// - /// Returns the object used to synchronize access to the factory. - /// - public object SyncRoot - { - get { return m_lock; } - } - /// /// Returns a unique identifier for the table instance. Used to debug problems with shared tables. /// @@ -338,7 +345,15 @@ public int InstanceId /// The underlying system type to add to the factory public void AddEncodeableType(Type systemType) { - AddEncodeableType(systemType, null); + try + { + m_readerWriterLockSlim.EnterWriteLock(); + AddEncodeableType(systemType, null); + } + finally + { + m_readerWriterLockSlim.ExitWriteLock(); + } } /// @@ -348,19 +363,23 @@ public void AddEncodeableType(Type systemType) /// The system type to use for the specified encoding. public void AddEncodeableType(ExpandedNodeId encodingId, Type systemType) { - lock (m_lock) + if (systemType != null && !NodeId.IsNull(encodingId)) { - if (systemType != null && !NodeId.IsNull(encodingId)) - { #if DEBUG - if (m_shared) - { - Utils.LogWarning("WARNING: Adding type '{0}' to shared Factory #{1}.", systemType.Name, m_instanceId); - } + if (m_shared) + { + Utils.LogWarning("WARNING: Adding type '{0}' to shared Factory #{1}.", systemType.Name, m_instanceId); + } #endif - + try + { + m_readerWriterLockSlim.EnterWriteLock(); m_encodeableTypes[encodingId] = systemType; } + finally + { + m_readerWriterLockSlim.ExitWriteLock(); + } } } @@ -389,8 +408,10 @@ public void AddEncodeableTypes(Assembly assembly) } #endif - lock (m_lock) + try { + m_readerWriterLockSlim.EnterWriteLock(); + Type[] systemTypes = assembly.GetExportedTypes(); var unboundTypeIds = new Dictionary(); @@ -442,6 +463,10 @@ public void AddEncodeableTypes(Assembly assembly) // only needed while adding assembly types unboundTypeIds.Clear(); } + finally + { + m_readerWriterLockSlim.ExitWriteLock(); + } } } @@ -451,8 +476,9 @@ public void AddEncodeableTypes(Assembly assembly) /// The underlying system types to add to the factory public void AddEncodeableTypes(IEnumerable systemTypes) { - lock (m_lock) + try { + m_readerWriterLockSlim.EnterWriteLock(); foreach (var type in systemTypes) { if (type.GetTypeInfo().IsAbstract) @@ -460,9 +486,13 @@ public void AddEncodeableTypes(IEnumerable systemTypes) continue; } - AddEncodeableType(type); + AddEncodeableType(type, null); } } + finally + { + m_readerWriterLockSlim.ExitWriteLock(); + } } /// @@ -474,8 +504,10 @@ public void AddEncodeableTypes(IEnumerable systemTypes) /// The type id to return the system-type of public Type GetSystemType(ExpandedNodeId typeId) { - lock (m_lock) + try { + m_readerWriterLockSlim.EnterReadLock(); + Type systemType = null; if (NodeId.IsNull(typeId) || !m_encodeableTypes.TryGetValue(typeId, out systemType)) @@ -485,6 +517,10 @@ public Type GetSystemType(ExpandedNodeId typeId) return systemType; } + finally + { + m_readerWriterLockSlim.ExitReadLock(); + } } /// @@ -493,8 +529,37 @@ public Type GetSystemType(ExpandedNodeId typeId) public IReadOnlyDictionary EncodeableTypes => m_encodeableTypes; #endregion + #region ICloneable Methods + /// + public object Clone() + { + return MemberwiseClone(); + } + + /// + public new object MemberwiseClone() + { + EncodeableFactory clone = new EncodeableFactory(null); + + try + { + m_readerWriterLockSlim.EnterReadLock(); + foreach (KeyValuePair current in m_encodeableTypes) + { + clone.m_encodeableTypes.Add(current.Key, current.Value); + } + } + finally + { + m_readerWriterLockSlim.ExitReadLock(); + } + + return clone; + } + #endregion + #region Private Fields - private object m_lock = new object(); + private ReaderWriterLockSlim m_readerWriterLockSlim = new ReaderWriterLockSlim(); private Dictionary m_encodeableTypes; private static EncodeableFactory s_globalFactory = new EncodeableFactory(); diff --git a/Stack/Opc.Ua.Core/Types/Encoders/IEncodeableFactory.cs b/Stack/Opc.Ua.Core/Types/Encoders/IEncodeableFactory.cs index 66803dd11..c94715755 100644 --- a/Stack/Opc.Ua.Core/Types/Encoders/IEncodeableFactory.cs +++ b/Stack/Opc.Ua.Core/Types/Encoders/IEncodeableFactory.cs @@ -28,16 +28,8 @@ namespace Opc.Ua /// Once the types exist within the factory, these types can be then easily queried. ///
/// - public interface IEncodeableFactory + public interface IEncodeableFactory : ICloneable { - /// - /// Returns the object used to synchronize access to the factory. - /// - /// - /// Returns the object used to synchronize access to the factory. - /// - object SyncRoot { get; } - /// /// Returns a unique identifier for the table instance. Used to debug problems with shared tables. /// diff --git a/Stack/Opc.Ua.Core/Types/Encoders/JsonDecoder.cs b/Stack/Opc.Ua.Core/Types/Encoders/JsonDecoder.cs index 8df73c32c..fd91e49b3 100644 --- a/Stack/Opc.Ua.Core/Types/Encoders/JsonDecoder.cs +++ b/Stack/Opc.Ua.Core/Types/Encoders/JsonDecoder.cs @@ -264,6 +264,7 @@ protected virtual void Dispose(bool disposing) if (m_reader != null) { m_reader.Close(); + m_reader = null; } } } @@ -827,7 +828,7 @@ public XmlElement ReadXmlElement(string fieldName) if (bytes != null && bytes.Length > 0) { XmlDocument document = new XmlDocument(); - string xmlString = new UTF8Encoding().GetString(bytes, 0, bytes.Length); + string xmlString = Encoding.UTF8.GetString(bytes, 0, bytes.Length); using (XmlReader reader = XmlReader.Create(new StringReader(xmlString), Utils.DefaultXmlReaderSettings())) { diff --git a/Stack/Opc.Ua.Core/Types/Encoders/JsonEncoder.cs b/Stack/Opc.Ua.Core/Types/Encoders/JsonEncoder.cs index c53f13399..53abaf951 100644 --- a/Stack/Opc.Ua.Core/Types/Encoders/JsonEncoder.cs +++ b/Stack/Opc.Ua.Core/Types/Encoders/JsonEncoder.cs @@ -320,6 +320,7 @@ protected virtual void Dispose(bool disposing) if (m_writer != null) { Close(); + m_writer = null; } if (!m_leaveOpen) diff --git a/Stack/Opc.Ua.Core/Types/Schemas/BinarySchemaValidator.cs b/Stack/Opc.Ua.Core/Types/Schemas/BinarySchemaValidator.cs index 113576ee7..ada9ff1e7 100644 --- a/Stack/Opc.Ua.Core/Types/Schemas/BinarySchemaValidator.cs +++ b/Stack/Opc.Ua.Core/Types/Schemas/BinarySchemaValidator.cs @@ -16,7 +16,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. using System.IO; using System.Linq; using System.Text; -using System.Threading.Tasks; using System.Xml; using System.Xml.Serialization; @@ -72,21 +71,21 @@ public BinarySchemaValidator(IDictionary importTable) : base(imp /// /// Generates the code from the contents of the address space. /// - public async Task Validate(Stream stream) + public void Validate(Stream stream) { // read and parse the file. Dictionary = (TypeDictionary)LoadInput(typeof(TypeDictionary), stream); - await Validate().ConfigureAwait(false); + Validate(); } /// /// Generates the code from the contents of the address space. /// - public async Task Validate(string inputPath) + public void Validate(string inputPath) { // read and parse the file. Dictionary = (TypeDictionary)LoadInput(typeof(TypeDictionary), inputPath); - await Validate().ConfigureAwait(false); + Validate(); } /// @@ -128,7 +127,7 @@ public override string GetSchema(string typeName) writer.Dispose(); } - return new UTF8Encoding().GetString(ostrm.ToArray(), 0, (int)ostrm.Length); + return Encoding.UTF8.GetString(ostrm.ToArray(), 0, (int)ostrm.Length); } #endregion @@ -136,7 +135,7 @@ public override string GetSchema(string typeName) /// /// Generates the code from the contents of the address space. /// - private async Task Validate() + private void Validate() { m_descriptions = new Dictionary(); m_validatedDescriptions = new List(); @@ -147,7 +146,7 @@ private async Task Validate() { foreach (ImportDirective directive in Dictionary.Import) { - await Import(directive).ConfigureAwait(false); + Import(directive); } } else @@ -156,7 +155,7 @@ private async Task Validate() if (!WellKnownDictionaries.Any(n => string.Equals(n[0], Dictionary.TargetNamespace, StringComparison.Ordinal))) { ImportDirective directive = new ImportDirective { Namespace = Namespaces.OpcUa }; - await Import(directive).ConfigureAwait(false); + Import(directive); } } @@ -187,7 +186,7 @@ private async Task Validate() /// /// Imports a dictionary identified by an import directive. /// - private async Task Import(ImportDirective directive) + private void Import(ImportDirective directive) { // check if already loaded. if (LoadedFiles.ContainsKey(directive.Namespace)) @@ -211,7 +210,7 @@ private async Task Import(ImportDirective directive) { for (int ii = 0; ii < dictionary.Import.Length; ii++) { - await Import(dictionary.Import[ii]).ConfigureAwait(false); + Import(dictionary.Import[ii]); } } diff --git a/Stack/Opc.Ua.Core/Types/Schemas/XmlSchemaValidator.cs b/Stack/Opc.Ua.Core/Types/Schemas/XmlSchemaValidator.cs index f9c5cacf7..ae0bb641a 100644 --- a/Stack/Opc.Ua.Core/Types/Schemas/XmlSchemaValidator.cs +++ b/Stack/Opc.Ua.Core/Types/Schemas/XmlSchemaValidator.cs @@ -159,7 +159,7 @@ public override string GetSchema(string typeName) writer.Dispose(); } - return new UTF8Encoding().GetString(ostrm.ToArray()); + return Encoding.UTF8.GetString(ostrm.ToArray()); } #endregion diff --git a/Stack/Opc.Ua.Core/Types/Utils/ServiceResultException.cs b/Stack/Opc.Ua.Core/Types/Utils/ServiceResultException.cs index 5202419e9..4ddba641e 100644 --- a/Stack/Opc.Ua.Core/Types/Utils/ServiceResultException.cs +++ b/Stack/Opc.Ua.Core/Types/Utils/ServiceResultException.cs @@ -21,6 +21,7 @@ namespace Opc.Ua /// An exception thrown when a UA defined error occurs. /// [DataContractAttribute] + [SerializableAttribute] public class ServiceResultException : Exception { #region Constructors @@ -112,12 +113,12 @@ public ServiceResultException(ServiceResult status) : base(GetMessage(status)) /// /// The namespace that qualifies symbolic identifier. - /// + ///
public string NamespaceUri => m_status.NamespaceUri; /// /// The qualified name of the symbolic identifier associated with the status code. - /// + ///
public string SymbolicId => m_status.SymbolicId; /// diff --git a/Stack/Opc.Ua.Core/Types/Utils/TypeInfo.cs b/Stack/Opc.Ua.Core/Types/Utils/TypeInfo.cs index 690c06359..fc49a1feb 100644 --- a/Stack/Opc.Ua.Core/Types/Utils/TypeInfo.cs +++ b/Stack/Opc.Ua.Core/Types/Utils/TypeInfo.cs @@ -12,6 +12,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. using System; using System.Reflection; +using System.Threading; +using System.Threading.Tasks; using System.Xml; namespace Opc.Ua @@ -512,6 +514,44 @@ public static BuiltInType GetBuiltInType(NodeId datatypeId, ITypeTable typeTree) return BuiltInType.Null; } +#if (NET_STANDARD_ASYNC) + /// + /// Returns the BuiltInType type for the DataTypeId. + /// + /// The data type identyfier for a node in a server's address space.. + /// The type tree for a server. . + /// + /// + /// A value for + /// + public static async Task GetBuiltInTypeAsync(NodeId datatypeId, ITypeTable typeTree, CancellationToken ct = default) + { + NodeId typeId = datatypeId; + + while (!Opc.Ua.NodeId.IsNull(typeId)) + { + if (typeId != null && typeId.NamespaceIndex == 0 && typeId.IdType == Opc.Ua.IdType.Numeric) + { + BuiltInType id = (BuiltInType)(int)(uint)typeId.Identifier; + + if (id > BuiltInType.Null && id <= BuiltInType.Enumeration && id != BuiltInType.DiagnosticInfo) + { + return id; + } + } + + if (typeTree == null) + { + break; + } + + typeId = await typeTree.FindSuperTypeAsync(typeId, ct).ConfigureAwait(false); + } + + return BuiltInType.Null; + } +#endif + /// /// Returns the system type for the datatype. /// @@ -886,7 +926,7 @@ public static TypeInfo IsInstanceOfDataType( return null; } - // check every element in the array or matrix. + // check every element in the array or matrix. Array array = value as Array; if (array == null) { @@ -1214,7 +1254,7 @@ public static TypeInfo Construct(Type systemType) return TypeInfo.Unknown; } - // check for generic type. + // check for generic type. if (systemType.GetTypeInfo().IsGenericType) { Type[] argTypes = systemType.GetGenericArguments(); @@ -1310,7 +1350,7 @@ public static TypeInfo Construct(Type systemType) } } - // unknown type. + // unknown type. return TypeInfo.Unknown; } diff --git a/Stack/Opc.Ua.Core/Types/Utils/Utils.cs b/Stack/Opc.Ua.Core/Types/Utils/Utils.cs index 91b406d75..e7e54cce3 100644 --- a/Stack/Opc.Ua.Core/Types/Utils/Utils.cs +++ b/Stack/Opc.Ua.Core/Types/Utils/Utils.cs @@ -2834,7 +2834,7 @@ private static byte[] PSHA(HMAC hmac, string label, byte[] data, int offset, int // convert label to UTF-8 byte sequence. if (!String.IsNullOrEmpty(label)) { - seed = new UTF8Encoding().GetBytes(label); + seed = Encoding.UTF8.GetBytes(label); } // append data to label. diff --git a/Tests/Opc.Ua.Client.ComplexTypes.Tests/Opc.Ua.Client.ComplexTypes.Tests.csproj b/Tests/Opc.Ua.Client.ComplexTypes.Tests/Opc.Ua.Client.ComplexTypes.Tests.csproj index e176f9441..252a39776 100644 --- a/Tests/Opc.Ua.Client.ComplexTypes.Tests/Opc.Ua.Client.ComplexTypes.Tests.csproj +++ b/Tests/Opc.Ua.Client.ComplexTypes.Tests/Opc.Ua.Client.ComplexTypes.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Tests/Opc.Ua.Client.ComplexTypes.Tests/TypeSystemClientTest.cs b/Tests/Opc.Ua.Client.ComplexTypes.Tests/TypeSystemClientTest.cs index 56e8a0cde..3bc9532d8 100644 --- a/Tests/Opc.Ua.Client.ComplexTypes.Tests/TypeSystemClientTest.cs +++ b/Tests/Opc.Ua.Client.ComplexTypes.Tests/TypeSystemClientTest.cs @@ -62,6 +62,10 @@ public class TypeSystemClientTest : IUAClient string m_pkiRoot; Uri m_url; + // for test that fetched and browsed node count match + int m_fetchedNodesCount; + int m_browsedNodesCount; + public TypeSystemClientTest() { m_uriScheme = Utils.UriSchemeOpcTcp; @@ -79,6 +83,9 @@ public TypeSystemClientTest(string uriScheme) [OneTimeSetUp] public Task OneTimeSetUp() { + m_fetchedNodesCount = -1; + m_browsedNodesCount = -1; + return OneTimeSetUpAsync(null); } @@ -97,6 +104,7 @@ public async Task OneTimeSetUpAsync(TextWriter writer = null) SecurityNone = true, AutoAccept = true, AllNodeManagers = true, + OperationLimits = true, }; if (writer != null) { @@ -192,46 +200,51 @@ public async Task LoadTypeSystem(bool onlyEnumTypes, bool disableDataTypeDefinit } [Test, Order(200)] - public async Task BrowseComplexTypesServer() + public async Task BrowseComplexTypesServerAsync() { var samples = new ClientSamples(TestContext.Out, null, null, true); - await samples.LoadTypeSystem(Session).ConfigureAwait(false); + await samples.LoadTypeSystemAsync(Session).ConfigureAwait(false); ReferenceDescriptionCollection referenceDescriptions = - samples.BrowseFullAddressSpace(this, Objects.RootFolder); + await samples.BrowseFullAddressSpaceAsync(this, Objects.RootFolder).ConfigureAwait(false); TestContext.Out.WriteLine("References: {0}", referenceDescriptions.Count); + m_browsedNodesCount = referenceDescriptions.Count; NodeIdCollection variableIds = new NodeIdCollection(referenceDescriptions - .Where(r => r.NodeClass == NodeClass.Variable && r.TypeDefinition.NamespaceIndex != 0) + .Where(r => r.NodeClass == NodeClass.Variable) .Select(r => ExpandedNodeId.ToNodeId(r.NodeId, m_session.NamespaceUris))); TestContext.Out.WriteLine("VariableIds: {0}", variableIds.Count); (var values, var serviceResults) = await samples.ReadAllValuesAsync(this, variableIds).ConfigureAwait(false); + int ii = 0; foreach (var serviceResult in serviceResults) { - Assert.IsTrue(ServiceResult.IsGood(serviceResult)); + var result = serviceResults[ii++]; + Assert.IsTrue(ServiceResult.IsGood(serviceResult), $"Expected good result, but received {serviceResult}"); } } [Test, Order(300)] - public async Task FetchComplexTypesServer() + public async Task FetchComplexTypesServerAsync() { var samples = new ClientSamples(TestContext.Out, null, null, true); - await samples.LoadTypeSystem(m_session).ConfigureAwait(false); + await samples.LoadTypeSystemAsync(m_session).ConfigureAwait(false); IList allNodes = null; - allNodes = samples.FetchAllNodesNodeCache( - this, Objects.RootFolder, true, true, false); + allNodes = await samples.FetchAllNodesNodeCacheAsync( + this, Objects.RootFolder, true, false, false).ConfigureAwait(false); TestContext.Out.WriteLine("References: {0}", allNodes.Count); + m_fetchedNodesCount = allNodes.Count; + NodeIdCollection variableIds = new NodeIdCollection(allNodes - .Where(r => r.NodeClass == NodeClass.Variable && ((VariableNode)r).DataType.NamespaceIndex != 0) + .Where(r => r.NodeClass == NodeClass.Variable && r is VariableNode && ((VariableNode)r).DataType.NamespaceIndex != 0) .Select(r => ExpandedNodeId.ToNodeId(r.NodeId, m_session.NamespaceUris))); TestContext.Out.WriteLine("VariableIds: {0}", variableIds.Count); @@ -242,13 +255,99 @@ public async Task FetchComplexTypesServer() { Assert.IsTrue(ServiceResult.IsGood(serviceResult)); } + + // check if complex type is properly decoded + bool testFailed = false; + for (int ii = 0; ii < values.Count; ii++) + { + DataValue value = values[ii]; + NodeId variableId = variableIds[ii]; + ExpandedNodeId variableExpandedNodeId = NodeId.ToExpandedNodeId(variableId, m_session.NamespaceUris); + var variableNode = allNodes.Where(n => n.NodeId == variableId).FirstOrDefault() as VariableNode; + if (variableNode != null && + variableNode.DataType.NamespaceIndex != 0) + { + TestContext.Out.WriteLine("Check for custom type: {0}", variableNode); + ExpandedNodeId fullTypeId = NodeId.ToExpandedNodeId(variableNode.DataType, m_session.NamespaceUris); + Type type = m_session.Factory.GetSystemType(fullTypeId); + if (type == null) + { + // check for opaque type + NodeId superType = m_session.NodeCache.FindSuperType(fullTypeId); + NodeId lastGoodType = variableNode.DataType; + while (!superType.IsNullNodeId && superType != DataTypes.BaseDataType) + { + if (superType == DataTypeIds.Structure) + { + testFailed = true; + break; + } + lastGoodType = superType; + superType = m_session.NodeCache.FindSuperType(superType); + } + + if (testFailed) + { + TestContext.Out.WriteLine("-- Variable: {0} complex type unavailable --> {1}", variableNode.NodeId, variableNode.DataType); + (_, _) = await samples.ReadAllValuesAsync(this, new NodeIdCollection() { variableId }).ConfigureAwait(false); + } + else + { + TestContext.Out.WriteLine("-- Variable: {0} opaque typeid --> {1}", variableNode.NodeId, lastGoodType); + } + continue; + } + + if (value.Value is ExtensionObject) + { + Type valueType = ((ExtensionObject)value.Value).Body.GetType(); + if (valueType != type) + { + testFailed = true; + TestContext.Out.WriteLine("Variable: {0} type is decoded as ExtensionObject --> {1}", variableNode, value.Value); + (_, _) = await samples.ReadAllValuesAsync(this, new NodeIdCollection() { variableId }).ConfigureAwait(false); + } + continue; + } + + if (value.Value is Array array && + array.GetType().GetElementType() == typeof(ExtensionObject)) + { + foreach (ExtensionObject valueItem in array) + { + Type valueType = valueItem.Body.GetType(); + if (valueType != type) + { + testFailed = true; + TestContext.Out.WriteLine("Variable: {0} type is decoded as ExtensionObject --> {1}", variableNode, valueItem); + (_, _) = await samples.ReadAllValuesAsync(this, new NodeIdCollection() { variableId }).ConfigureAwait(false); + } + } + } + } + } + + if (testFailed) + { + Assert.Fail("Test failed, unknown or undecodable complex type detected. See log for information."); + } + } + + [Test, Order(330)] + public void ValidateFetchedAndBrowsedNodesMatch() + { + if (m_browsedNodesCount < 0 || m_fetchedNodesCount < 0) + { + Assert.Ignore("The browse or fetch test did not run."); + } + Assert.AreEqual(m_fetchedNodesCount, m_browsedNodesCount); } [Test, Order(400)] - public async Task ReadWriteScalaVariableType() + public async Task ReadWriteScalarVariableTypeAsync() { var samples = new ClientSamples(TestContext.Out, null, null, true); - await samples.LoadTypeSystem(m_session).ConfigureAwait(false); + await samples.LoadTypeSystemAsync(m_session).ConfigureAwait(false); // test the static version of the structure ExpandedNodeId structureVariable = TestData.VariableIds.Data_Static_Structure_ScalarStructure; diff --git a/Tests/Opc.Ua.Client.ComplexTypes.Tests/Types/MockResolver.cs b/Tests/Opc.Ua.Client.ComplexTypes.Tests/Types/MockResolver.cs index 938ea4324..354ba90c1 100644 --- a/Tests/Opc.Ua.Client.ComplexTypes.Tests/Types/MockResolver.cs +++ b/Tests/Opc.Ua.Client.ComplexTypes.Tests/Types/MockResolver.cs @@ -2,7 +2,7 @@ * Copyright (c) 2005-2021 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -11,7 +11,7 @@ * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace Opc.Ua.Client.ComplexTypes.Tests.Types @@ -74,26 +75,26 @@ private void Initialize() public IEncodeableFactory Factory => m_factory; /// - public Task> LoadDataTypeSystem(NodeId dataTypeSystem = null) + public Task> LoadDataTypeSystem(NodeId dataTypeSystem = null, CancellationToken ct = default) { return Task.FromResult(m_dataTypeDictionary); } /// - public IList BrowseForEncodings(IList nodeIds, string[] supportedEncodings) + public Task> BrowseForEncodingsAsync(IList nodeIds, string[] supportedEncodings, CancellationToken ct = default) { - return new List(); + return Task.FromResult((IList)new List()); } /// - public IList BrowseForEncodings( + public Task<(IList encodings, ExpandedNodeId binaryEncodingId, ExpandedNodeId xmlEncodingId)> BrowseForEncodingsAsync( ExpandedNodeId nodeId, string[] supportedEncodings, - out ExpandedNodeId binaryEncodingId, - out ExpandedNodeId xmlEncodingId) + CancellationToken ct = default) { - binaryEncodingId = ExpandedNodeId.Null; - xmlEncodingId = ExpandedNodeId.Null; + var binaryEncodingId = ExpandedNodeId.Null; + var xmlEncodingId = ExpandedNodeId.Null; + IList encodings = null; var node = m_dataTypeNodes[ExpandedNodeId.ToNodeId(nodeId, NamespaceUris)]; if (node is DataTypeNode dataTypeNode) @@ -121,33 +122,26 @@ public IList BrowseForEncodings( } result.Add(ExpandedNodeId.ToNodeId(reference.TargetId, NamespaceUris)); } - return result; + encodings = result; } - return null; + return Task.FromResult((encodings, binaryEncodingId, xmlEncodingId)); } /// - public bool BrowseTypeIdsForDictionaryComponent( + public Task<(ExpandedNodeId typeId, ExpandedNodeId encodingId, DataTypeNode dataTypeNode)> BrowseTypeIdsForDictionaryComponentAsync( ExpandedNodeId nodeId, - out ExpandedNodeId typeId, - out ExpandedNodeId encodingId, - out DataTypeNode dataTypeNode) + CancellationToken ct = default) { - typeId = ExpandedNodeId.Null; - encodingId = ExpandedNodeId.Null; - dataTypeNode = null; - - // not implemented yet - - return false; + return Task.FromResult<(ExpandedNodeId typeId, ExpandedNodeId encodingId, DataTypeNode dataTypeNode)>((null, null, null)); } /// - public IList LoadDataTypes( + public async Task> LoadDataTypesAsync( ExpandedNodeId dataType, bool nestedSubTypes = false, bool addRootNode = false, - bool filterUATypes = true) + bool filterUATypes = true, + CancellationToken ct = default) { var result = new List(); var nodesToBrowse = new ExpandedNodeIdCollection { @@ -156,7 +150,7 @@ public IList LoadDataTypes( if (addRootNode) { - var rootNode = Find(dataType); + var rootNode = await FindAsync(dataType, ct).ConfigureAwait(false); if (!(rootNode is DataTypeNode)) { throw new ServiceResultException("Root Node is not a DataType node."); @@ -203,34 +197,33 @@ public IList LoadDataTypes( } /// - public INode Find(ExpandedNodeId nodeId) + public Task FindAsync(ExpandedNodeId nodeId, CancellationToken ct = default) { - return m_dataTypeNodes[ExpandedNodeId.ToNodeId(nodeId, NamespaceUris)]; + return Task.FromResult(m_dataTypeNodes[ExpandedNodeId.ToNodeId(nodeId, NamespaceUris)]); } - /// - public object GetEnumTypeArray(ExpandedNodeId nodeId) + public Task GetEnumTypeArrayAsync(ExpandedNodeId nodeId, CancellationToken ct = default) { - return null; + return Task.FromResult(null); } /// - public NodeId FindSuperType(NodeId typeId) + public Task FindSuperTypeAsync(NodeId typeId, CancellationToken ct = default) { var node = m_dataTypeNodes[typeId]; if (node is DataTypeNode dataTypeNode) { if (dataTypeNode.DataTypeDefinition.Body is EnumDefinition enumDefinition) { - return DataTypeIds.Enumeration; + return Task.FromResult(DataTypeIds.Enumeration); } else if (dataTypeNode.DataTypeDefinition.Body is StructureDefinition structureDefinition) { - return structureDefinition.BaseDataType; + return Task.FromResult(structureDefinition.BaseDataType); } } - return DataTypeIds.BaseDataType; + return Task.FromResult(DataTypeIds.BaseDataType); } #endregion IComplexTypeResolver diff --git a/Tests/Opc.Ua.Client.Tests/ClientFixture.cs b/Tests/Opc.Ua.Client.Tests/ClientFixture.cs index 417c9d3a8..952263d77 100644 --- a/Tests/Opc.Ua.Client.Tests/ClientFixture.cs +++ b/Tests/Opc.Ua.Client.Tests/ClientFixture.cs @@ -78,6 +78,8 @@ public async Task LoadClientConfiguration(string pkiRoot = null, string clientNa .Build( "urn:localhost:opcfoundation.org:" + clientName, "http://opcfoundation.org/UA/" + clientName) + .SetMaxByteStringLength(4 * 1024 * 1024) + .SetMaxArrayLength(1024 * 1024) .AsClient() .SetClientOperationLimits(new OperationLimits { MaxNodesPerBrowse = kDefaultOperationLimits, diff --git a/Tests/Opc.Ua.Client.Tests/ClientTest.cs b/Tests/Opc.Ua.Client.Tests/ClientTest.cs index 7e9986215..35e036d45 100644 --- a/Tests/Opc.Ua.Client.Tests/ClientTest.cs +++ b/Tests/Opc.Ua.Client.Tests/ClientTest.cs @@ -1164,7 +1164,7 @@ public async Task LoadStandardDataTypeSystem() [Test, Order(710)] [TestCaseSource(nameof(TypeSystems))] - public async Task LoadAllServerDataTypeSystems(NodeId dataTypeSystem) + public void LoadAllServerDataTypeSystems(NodeId dataTypeSystem) { // find the dictionary for the description. Browser browser = new Browser(Session) { @@ -1185,7 +1185,7 @@ public async Task LoadAllServerDataTypeSystems(NodeId dataTypeSystem) NodeId dictionaryId = ExpandedNodeId.ToNodeId(r.NodeId, Session.NamespaceUris); TestContext.Out.WriteLine(" ReadDictionary {0} {1}", r.BrowseName.Name, dictionaryId); var dictionaryToLoad = new DataDictionary(Session); - await dictionaryToLoad.Load(dictionaryId, r.BrowseName.Name).ConfigureAwait(false); + dictionaryToLoad.Load(dictionaryId, r.BrowseName.Name); // internal API for testing only var dictionary = dictionaryToLoad.ReadDictionary(dictionaryId); @@ -1195,7 +1195,7 @@ public async Task LoadAllServerDataTypeSystems(NodeId dataTypeSystem) { try { - await dictionaryToLoad.Validate(dictionary, true).ConfigureAwait(false); + dictionaryToLoad.Validate(dictionary, true); } catch (Exception ex) { @@ -1204,7 +1204,7 @@ public async Task LoadAllServerDataTypeSystems(NodeId dataTypeSystem) } else { - await dictionaryToLoad.Validate(dictionary, true).ConfigureAwait(false); + dictionaryToLoad.Validate(dictionary, true); } } } diff --git a/Tests/Opc.Ua.Client.Tests/NodeCacheAsyncTest.cs b/Tests/Opc.Ua.Client.Tests/NodeCacheAsyncTest.cs new file mode 100644 index 000000000..4a4c16685 --- /dev/null +++ b/Tests/Opc.Ua.Client.Tests/NodeCacheAsyncTest.cs @@ -0,0 +1,508 @@ +/* ======================================================================== + * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved. + * + * OPC Foundation MIT License 1.00 + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * The complete license agreement can be found here: + * http://opcfoundation.org/License/MIT/1.00/ + * ======================================================================*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using NUnit.Framework; +using Opc.Ua.Server.Tests; + +namespace Opc.Ua.Client.Tests +{ + /// + /// Client tests. + /// + [TestFixture, Category("Client"), Category("NodeCacheAsync")] + [SetCulture("en-us"), SetUICulture("en-us")] + [TestFixtureSource(nameof(FixtureArgs))] + [MemoryDiagnoser] + [DisassemblyDiagnoser] + public class NodeCacheAsyncTest : ClientTestFramework + { + private const int kTestSetSize = 100; + + public NodeCacheAsyncTest(string uriScheme = Utils.UriSchemeOpcTcp) : + base(uriScheme) + { + } + + #region Test Setup + /// + /// Set up a Server and a Client instance. + /// + [OneTimeSetUp] + public new Task OneTimeSetUp() + { + SupportsExternalServerUrl = true; + // create a new session for every test + SingleSession = false; + return base.OneTimeSetUp(); + } + + /// + /// Tear down the Server and the Client. + /// + [OneTimeTearDown] + public new Task OneTimeTearDownAsync() + { + return base.OneTimeTearDownAsync(); + } + + /// + /// Test setup. + /// + [SetUp] + public new async Task SetUp() + { + await base.SetUp().ConfigureAwait(false); + + // clear node cache + Session.NodeCache.Clear(); + } + + /// + /// Test teardown. + /// + [TearDown] + public new Task TearDown() + { + return base.TearDown(); + } + #endregion + + #region Benchmark Setup + /// + /// Global Setup for benchmarks. + /// + [GlobalSetup] + public new void GlobalSetup() + { + base.GlobalSetup(); + } + + /// + /// Global cleanup for benchmarks. + /// + [GlobalCleanup] + public new void GlobalCleanup() + { + base.GlobalCleanup(); + } + #endregion + + #region Test Methods + /// + /// Load Ua types in node cache. + /// + [Test, Order(500)] + public void NodeCache_LoadUaDefinedTypes() + { + INodeCache nodeCache = Session.NodeCache; + Assert.IsNotNull(nodeCache); + + // load the predefined types + nodeCache.LoadUaDefinedTypes(Session.SystemContext); + + // reload the predefined types + nodeCache.LoadUaDefinedTypes(Session.SystemContext); + } + + /// + /// Browse all variables in the objects folder. + /// + [Test, Order(100)] + public async Task NodeCache_BrowseAllVariables() + { + var result = new List(); + var nodesToBrowse = new ExpandedNodeIdCollection { + ObjectIds.ObjectsFolder + }; + + await Session.FetchTypeTreeAsync(ReferenceTypeIds.References).ConfigureAwait(false); // TODO: Async + + while (nodesToBrowse.Count > 0) + { + var nextNodesToBrowse = new ExpandedNodeIdCollection(); + foreach (var node in nodesToBrowse) + { + try + { + var organizers = await Session.NodeCache.FindReferencesAsync( + node, + ReferenceTypeIds.HierarchicalReferences, + false, + true).ConfigureAwait(false); + nextNodesToBrowse.AddRange(organizers.Select(n => n.NodeId)); + var objectNodes = organizers.Where(n => n is ObjectNode); + var variableNodes = organizers.Where(n => n is VariableNode); + result.AddRange(variableNodes); + } + catch (ServiceResultException sre) + { + if (sre.StatusCode == StatusCodes.BadUserAccessDenied) + { + TestContext.Out.WriteLine($"Access denied: Skip node {node}."); + } + } + } + nodesToBrowse = new ExpandedNodeIdCollection(nextNodesToBrowse.Distinct()); + TestContext.Out.WriteLine("Found {0} duplicates", nextNodesToBrowse.Count - nodesToBrowse.Count); + } + + TestContext.Out.WriteLine("Found {0} variables", result.Count); + } + + /// + /// Browse all variables in the objects folder. + /// + [Test, Order(200)] + public async Task NodeCache_BrowseAllVariables_MultipleNodes() + { + var result = new List(); + var nodesToBrowse = new ExpandedNodeIdCollection { + ObjectIds.ObjectsFolder + }; + + await Session.FetchTypeTreeAsync(ReferenceTypeIds.References).ConfigureAwait(false); + var referenceTypeIds = new NodeIdCollection() { ReferenceTypeIds.HierarchicalReferences }; + while (nodesToBrowse.Count > 0) + { + var nextNodesToBrowse = new ExpandedNodeIdCollection(); + try + { + var organizers = await Session.NodeCache.FindReferencesAsync( + nodesToBrowse, + referenceTypeIds, + false, + true).ConfigureAwait(false); + nextNodesToBrowse.AddRange(organizers.Select(n => n.NodeId)); + var objectNodes = organizers.Where(n => n is ObjectNode); + var variableNodes = organizers.Where(n => n is VariableNode); + result.AddRange(variableNodes); + } + catch (ServiceResultException sre) + { + if (sre.StatusCode == StatusCodes.BadUserAccessDenied) + { + TestContext.Out.WriteLine($"Access denied: Skipped node."); + } + } + nodesToBrowse = new ExpandedNodeIdCollection(nextNodesToBrowse.Distinct()); + TestContext.Out.WriteLine("Found {0} duplicates", nextNodesToBrowse.Count - nodesToBrowse.Count); + } + + TestContext.Out.WriteLine("Found {0} variables", result.Count); + } + + [Test, Order(720)] + public async Task NodeCacheFind() + { + if (ReferenceDescriptions == null) + { + BrowseFullAddressSpace(); + } + + foreach (var reference in ReferenceDescriptions.Take(MaxReferences)) + { + var nodeId = ExpandedNodeId.ToNodeId(reference.NodeId, Session.NamespaceUris); + var node = await Session.NodeCache.FindAsync(reference.NodeId).ConfigureAwait(false); + TestContext.Out.WriteLine("NodeId: {0} Node: {1}", nodeId, node); + } + } + + [Test, Order(730)] + public async Task NodeCacheFetchNode() + { + if (ReferenceDescriptions == null) + { + BrowseFullAddressSpace(); + } + + foreach (var reference in ReferenceDescriptions.Take(MaxReferences)) + { + var nodeId = ExpandedNodeId.ToNodeId(reference.NodeId, Session.NamespaceUris); + var node = await Session.NodeCache.FetchNodeAsync(reference.NodeId).ConfigureAwait(false); + TestContext.Out.WriteLine("NodeId: {0} Node: {1}", nodeId, node); + } + } + + [Test, Order(740)] + public async Task NodeCacheFetchNodes() + { + if (ReferenceDescriptions == null) + { + BrowseFullAddressSpace(); + } + + var testSet = ReferenceDescriptions.Take(MaxReferences).Select(r => r.NodeId).ToList(); + IList nodeCollection = await Session.NodeCache.FetchNodesAsync(testSet).ConfigureAwait(false); + + foreach (var node in nodeCollection) + { + var nodeId = ExpandedNodeId.ToNodeId(node.NodeId, Session.NamespaceUris); + TestContext.Out.WriteLine("NodeId: {0} Node: {1}", nodeId, node); + } + } + + [Test, Order(750)] + public async Task NodeCacheFindReferences() + { + if (ReferenceDescriptions == null) + { + BrowseFullAddressSpace(); + } + + var testSet = ReferenceDescriptions.Take(MaxReferences).Select(r => r.NodeId).ToList(); + IList nodes = await Session.NodeCache.FindReferencesAsync(testSet, new NodeIdCollection() { ReferenceTypeIds.NonHierarchicalReferences }, false, true).ConfigureAwait(false); + + foreach (var node in nodes) + { + var nodeId = ExpandedNodeId.ToNodeId(node.NodeId, Session.NamespaceUris); + TestContext.Out.WriteLine("NodeId: {0} Node: {1}", nodeId, node); + } + } + + [Test, Order(900)] + public async Task FetchTypeTreeAsync() + { + await Session.FetchTypeTreeAsync(NodeId.ToExpandedNodeId(DataTypeIds.BaseDataType, Session.NamespaceUris)).ConfigureAwait(false); + } + + [Test, Order(910)] + public async Task FetchAllReferenceTypesAsync() + { + var bindingFlags = + BindingFlags.Instance | + BindingFlags.Static | + BindingFlags.Public; + var fieldValues = typeof(ReferenceTypeIds) + .GetFields(bindingFlags) + .Select(field => NodeId.ToExpandedNodeId((NodeId)field.GetValue(null), Session.NamespaceUris)); + + await Session.FetchTypeTreeAsync(new ExpandedNodeIdCollection(fieldValues)).ConfigureAwait(false); + } + + /// + /// Test concurrent access of FetchNodes. + /// + [Test, Order(1000)] + public async Task NodeCacheFetchNodesConcurrentAsync() + { + if (ReferenceDescriptions == null) + { + BrowseFullAddressSpace(); + } + + Random random = new Random(62541); + var testSet = ReferenceDescriptions.OrderBy(o => random.Next()).Take(kTestSetSize).Select(r => r.NodeId).ToList(); + var taskList = new List(); + + // test concurrent access of FetchNodes + for (int i = 0; i < 10; i++) + { + Task t = Session.NodeCache.FetchNodesAsync(testSet); + taskList.Add(t); + } + await Task.WhenAll(taskList.ToArray()).ConfigureAwait(false); + } + + /// + /// Test concurrent access of Find. + /// + [Test, Order(1100)] + public async Task NodeCacheFindNodesConcurrent() + { + if (ReferenceDescriptions == null) + { + BrowseFullAddressSpace(); + } + + Random random = new Random(62541); + var testSet = ReferenceDescriptions.OrderBy(o => random.Next()).Take(kTestSetSize).Select(r => r.NodeId).ToList(); + var taskList = new List(); + + // test concurrent access of FetchNodes + for (int i = 0; i < 10; i++) + { + Task t = Session.NodeCache.FindAsync(testSet); + taskList.Add(t); + } + await Task.WhenAll(taskList.ToArray()).ConfigureAwait(false); + } + + /// + /// Test concurrent access of FindReferences. + /// + [Test, Order(1200)] + public async Task NodeCacheFindReferencesConcurrent() + { + if (ReferenceDescriptions == null) + { + BrowseFullAddressSpace(); + } + + Random random = new Random(62541); + var testSet = ReferenceDescriptions.OrderBy(o => random.Next()).Take(kTestSetSize).Select(r => r.NodeId).ToList(); + var taskList = new List(); + var refTypeIds = new List() { ReferenceTypeIds.HierarchicalReferences }; + await FetchAllReferenceTypesAsync().ConfigureAwait(false); + + // test concurrent access of FetchNodes + for (int i = 0; i < 10; i++) + { + Task t = Session.NodeCache.FindReferencesAsync(testSet, refTypeIds, false, true); + taskList.Add(t); + } + await Task.WhenAll(taskList.ToArray()).ConfigureAwait(false); + } + + /// + /// Test concurrent access of many methods in INodecache interface + /// + [Test, Order(1300)] + public async Task NodeCacheTestAllMethodsConcurrently() + { + const int testCases = 10; + const int testCaseRunTime = 5_000; + + if (ReferenceDescriptions == null) + { + BrowseFullAddressSpace(); + } + + Random random = new Random(62541); + var testSetAll = ReferenceDescriptions.OrderBy(o => random.Next()).Where(r => r.NodeClass == NodeClass.Variable).Select(r => r.NodeId).ToList(); + var testSet1 = testSetAll.Take(kTestSetSize).ToList(); + var testSet2 = testSetAll.Skip(kTestSetSize).Take(kTestSetSize).ToList(); + var testSet3 = testSetAll.Skip(kTestSetSize * 2).Take(kTestSetSize).ToList(); + + var taskList = new List(); + var refTypeIds = new List() { ReferenceTypeIds.HierarchicalReferences }; + + // test concurrent access of many methods in INodecache interface + for (int i = 0; i < testCases; i++) + { + int iteration = i; + Task t = Task.Run(async () => { + DateTime start = DateTime.UtcNow; + do + { + switch (iteration) + { + case 0: + await FetchAllReferenceTypesAsync().ConfigureAwait(false); + IList result = await Session.NodeCache.FindReferencesAsync(testSet1, refTypeIds, false, true).ConfigureAwait(false); + break; + case 1: + IList result1 = await Session.NodeCache.FindAsync(testSet2).ConfigureAwait(false); + break; + case 2: + IList result2 = await Session.NodeCache.FetchNodesAsync(testSet3).ConfigureAwait(false); + string displayText = Session.NodeCache.GetDisplayText(result2[0]); + break; + case 3: + IList result3 = await Session.NodeCache.FindReferencesAsync(testSet1[0], refTypeIds[0], false, true).ConfigureAwait(false); + break; + case 4: + INode result4 = await Session.NodeCache.FindAsync(testSet2[0]).ConfigureAwait(false); + Assert.NotNull(result4); + Assert.True(result4 is VariableNode); + break; + case 5: + Node result5 = await Session.NodeCache.FetchNodeAsync(testSet3[0]).ConfigureAwait(false); + Assert.NotNull(result5); + Assert.True(result5 is VariableNode); + await Session.NodeCache.FetchSuperTypesAsync(result5.NodeId).ConfigureAwait(false); + break; + case 6: + string text = Session.NodeCache.GetDisplayText(testSet2[0]); + Assert.NotNull(text); + break; + case 7: + NodeId number = new NodeId((int)BuiltInType.Number); + bool isKnown = Session.NodeCache.IsKnown(new ExpandedNodeId((int)BuiltInType.Int64)); + Assert.True(isKnown); + bool isKnown2 = Session.NodeCache.IsKnown(TestData.DataTypeIds.ScalarStructureDataType); + Assert.True(isKnown2); + NodeId nodeId = await Session.NodeCache.FindSuperTypeAsync(TestData.DataTypeIds.Vector).ConfigureAwait(false); + Assert.AreEqual(DataTypeIds.Structure, nodeId); + NodeId nodeId2 = await Session.NodeCache.FindSuperTypeAsync(ExpandedNodeId.ToNodeId(TestData.DataTypeIds.Vector, Session.NamespaceUris)).ConfigureAwait(false); + Assert.AreEqual(DataTypeIds.Structure, nodeId2); + IList subTypes = Session.NodeCache.FindSubTypes(new ExpandedNodeId((int)BuiltInType.Number)); + bool isTypeOf = Session.NodeCache.IsTypeOf(new ExpandedNodeId((int)BuiltInType.Int32), new ExpandedNodeId((int)BuiltInType.Number)); + bool isTypeOf2 = Session.NodeCache.IsTypeOf(new NodeId((int)BuiltInType.UInt32), number); + break; + case 8: + bool isEncodingOf = Session.NodeCache.IsEncodingOf(new ExpandedNodeId((int)BuiltInType.Int32), DataTypeIds.Structure); + Assert.False(isEncodingOf); + bool isEncodingFor = Session.NodeCache.IsEncodingFor(DataTypeIds.Structure, + new TestData.ScalarStructureDataType()); + Assert.True(isEncodingFor); + bool isEncodingFor2 = Session.NodeCache.IsEncodingFor(new NodeId((int)BuiltInType.UInt32), new NodeId((int)BuiltInType.UInteger)); + Assert.False(isEncodingFor2); + break; + case 9: + NodeId findDataTypeId = Session.NodeCache.FindDataTypeId(new ExpandedNodeId((int)Objects.DataTypeAttributes_Encoding_DefaultBinary)); + NodeId findDataTypeId2 = Session.NodeCache.FindDataTypeId((int)Objects.DataTypeAttributes_Encoding_DefaultBinary); + break; + default: + Assert.Fail("Invalid test case"); + break; + } + } while ((DateTime.UtcNow - start).TotalMilliseconds < testCaseRunTime); + + }); + taskList.Add(t); + } + await Task.WhenAll(taskList.ToArray()).ConfigureAwait(false); + } + #endregion + + #region Benchmarks + #endregion + + #region Private Methods + private void BrowseFullAddressSpace() + { + var requestHeader = new RequestHeader { + Timestamp = DateTime.UtcNow, + TimeoutHint = MaxTimeout + }; + + // Session + var clientTestServices = new ClientTestServices(Session); + ReferenceDescriptions = CommonTestWorkers.BrowseFullAddressSpaceWorker(clientTestServices, requestHeader); + } + #endregion + } +} diff --git a/Tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj b/Tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj index 9fd1f08c4..b47a447cc 100644 --- a/Tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj +++ b/Tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs b/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs index 393fa0f50..da539119a 100644 --- a/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs +++ b/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs @@ -267,7 +267,7 @@ public async Task AddSubscriptionAsync() await subscription.ConditionRefreshAsync().ConfigureAwait(false); var sre = Assert.Throws(() => subscription.Republish(subscription.SequenceNumber)); - Assert.AreEqual(StatusCodes.BadMessageNotAvailable, sre.StatusCode); + Assert.AreEqual(StatusCodes.BadMessageNotAvailable, sre.StatusCode, $"Expected BadMessageNotAvailable, but received {sre.Message}"); subscription.RemoveItems(list); await subscription.ApplyChangesAsync().ConfigureAwait(false); diff --git a/Tests/Opc.Ua.Configuration.Tests/ApplicationInstanceTests.cs b/Tests/Opc.Ua.Configuration.Tests/ApplicationInstanceTests.cs index 1e42986c7..8e81fb75b 100644 --- a/Tests/Opc.Ua.Configuration.Tests/ApplicationInstanceTests.cs +++ b/Tests/Opc.Ua.Configuration.Tests/ApplicationInstanceTests.cs @@ -533,6 +533,53 @@ public async Task TestInvalidAppCertChainDoNotRecreate(InvalidCertType certType, } } } + + /// + /// Test to verify that a new cert is not recreated/replaced if DisableCertificateAutoCreation is set. + /// + [Theory] + public async Task TestDisableCertificateAutoCreationAsync(bool server, bool disableCertificateAutoCreation) + { + // pki directory root for test runs. + var pkiRoot = Path.GetTempPath() + Path.GetRandomFileName() + Path.DirectorySeparatorChar; + + var applicationInstance = new ApplicationInstance() { + ApplicationName = ApplicationName, + DisableCertificateAutoCreation = disableCertificateAutoCreation + }; + Assert.NotNull(applicationInstance); + ApplicationConfiguration config; + if (server) + { + config = await applicationInstance.Build(ApplicationUri, ProductUri) + .AsServer(new string[] { "opc.tcp://localhost:12345/Configuration" }) + .AddSecurityConfiguration(SubjectName, pkiRoot) + .Create().ConfigureAwait(false); + } + else + { + config = await applicationInstance.Build(ApplicationUri, ProductUri) + .AsClient() + .AddSecurityConfiguration(SubjectName, pkiRoot) + .Create().ConfigureAwait(false); + } + Assert.NotNull(config); + + CertificateIdentifier applicationCertificate = applicationInstance.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate; + Assert.IsNull(applicationCertificate.Certificate); + + if (disableCertificateAutoCreation) + { + var sre = Assert.ThrowsAsync(async () => + await applicationInstance.CheckApplicationInstanceCertificate(true, 0).ConfigureAwait(false)); + Assert.AreEqual(StatusCodes.BadConfigurationError, sre.StatusCode); + } + else + { + bool certOK = await applicationInstance.CheckApplicationInstanceCertificate(true, 0).ConfigureAwait(false); + Assert.True(certOK); + } + } #endregion #region Private Methods diff --git a/Tests/Opc.Ua.Configuration.Tests/Opc.Ua.Configuration.Tests.csproj b/Tests/Opc.Ua.Configuration.Tests/Opc.Ua.Configuration.Tests.csproj index c9a00a5d4..c3055ad6e 100644 --- a/Tests/Opc.Ua.Configuration.Tests/Opc.Ua.Configuration.Tests.csproj +++ b/Tests/Opc.Ua.Configuration.Tests/Opc.Ua.Configuration.Tests.csproj @@ -8,7 +8,7 @@ - + @@ -19,7 +19,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Tests/Opc.Ua.Core.Tests/Opc.Ua.Core.Tests.csproj b/Tests/Opc.Ua.Core.Tests/Opc.Ua.Core.Tests.csproj index fbdf0a20b..74f56f5ea 100644 --- a/Tests/Opc.Ua.Core.Tests/Opc.Ua.Core.Tests.csproj +++ b/Tests/Opc.Ua.Core.Tests/Opc.Ua.Core.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/Tests/Opc.Ua.Core.Tests/Types/Schemas/BinarySchemaWellKnownTests.cs b/Tests/Opc.Ua.Core.Tests/Types/Schemas/BinarySchemaWellKnownTests.cs index 5a71e7bbd..fd9e59fac 100644 --- a/Tests/Opc.Ua.Core.Tests/Types/Schemas/BinarySchemaWellKnownTests.cs +++ b/Tests/Opc.Ua.Core.Tests/Types/Schemas/BinarySchemaWellKnownTests.cs @@ -2,7 +2,7 @@ * Copyright (c) 2005-2018 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -11,7 +11,7 @@ * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, @@ -65,14 +65,14 @@ public void LoadResources(string[] schemaData) /// Load and validate well known resource type dictionaries. /// [Theory] - public async Task ValidateResources(string[] schemaData) + public void ValidateResources(string[] schemaData) { var assembly = typeof(BinarySchemaValidator).GetTypeInfo().Assembly; var stream = assembly.GetManifestResourceStream(schemaData[1]); Assert.IsNotNull(stream); var schema = new BinarySchemaValidator(); Assert.IsNotNull(schema); - await schema.Validate(stream).ConfigureAwait(false); + schema.Validate(stream); Assert.IsNotNull(schema.Dictionary); Assert.AreEqual(schemaData[0], schema.Dictionary.TargetNamespace); } diff --git a/Tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj b/Tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj index 4982627c6..7dd3d96be 100644 --- a/Tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj +++ b/Tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/Tests/Opc.Ua.PubSub.Tests/Opc.Ua.PubSub.Tests.csproj b/Tests/Opc.Ua.PubSub.Tests/Opc.Ua.PubSub.Tests.csproj index 772e56873..026198c17 100644 --- a/Tests/Opc.Ua.PubSub.Tests/Opc.Ua.PubSub.Tests.csproj +++ b/Tests/Opc.Ua.PubSub.Tests/Opc.Ua.PubSub.Tests.csproj @@ -8,7 +8,7 @@ - + @@ -21,7 +21,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Tests/Opc.Ua.Security.Certificates.Tests/Opc.Ua.Security.Certificates.Tests.csproj b/Tests/Opc.Ua.Security.Certificates.Tests/Opc.Ua.Security.Certificates.Tests.csproj index f557ad658..ed4c7912a 100644 --- a/Tests/Opc.Ua.Security.Certificates.Tests/Opc.Ua.Security.Certificates.Tests.csproj +++ b/Tests/Opc.Ua.Security.Certificates.Tests/Opc.Ua.Security.Certificates.Tests.csproj @@ -24,7 +24,7 @@ - + @@ -35,7 +35,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj b/Tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj index cf1ea9b51..b1167ab94 100644 --- a/Tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj +++ b/Tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj @@ -8,7 +8,7 @@ - + @@ -20,7 +20,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Tests/Opc.Ua.Server.Tests/ServerFixture.cs b/Tests/Opc.Ua.Server.Tests/ServerFixture.cs index 92fb1afee..17deb7ee6 100644 --- a/Tests/Opc.Ua.Server.Tests/ServerFixture.cs +++ b/Tests/Opc.Ua.Server.Tests/ServerFixture.cs @@ -67,6 +67,8 @@ public async Task LoadConfiguration(string pkiRoot = null) var serverConfig = Application.Build( "urn:localhost:UA:" + typeof(T).Name, "uri:opcfoundation.org:" + typeof(T).Name) + .SetMaxByteStringLength(4 * 1024 * 1024) + .SetMaxArrayLength(1024 * 1024) .AsServer( new string[] { endpointUrl @@ -99,6 +101,12 @@ public async Task LoadConfiguration(string pkiRoot = null) MaxNodesPerWrite = 1000, MaxNodesPerMethodCall = 1000, MaxMonitoredItemsPerCall = 1000, + MaxNodesPerHistoryReadData = 1000, + MaxNodesPerHistoryReadEvents = 1000, + MaxNodesPerHistoryUpdateData = 1000, + MaxNodesPerHistoryUpdateEvents = 1000, + MaxNodesPerNodeManagement = 1000, + MaxNodesPerRegisterNodes = 1000, MaxNodesPerTranslateBrowsePathsToNodeIds = 1000 }); }