From fc29d5ba05ed401cdc6f6d624b87a570ec3f6c8d Mon Sep 17 00:00:00 2001 From: Kevin Herron Date: Wed, 10 Dec 2025 16:30:15 -0800 Subject: [PATCH 1/8] Add lazy-loading DataTypeTree implementation - Add LazyClientDataTypeTree that resolves types on demand by browsing inverse HasSubtype references, avoiding eager enumeration of the entire type hierarchy - Add DataTypeTreeFactory interface with eager() and lazy() factory methods for configuring how the DataTypeTree is created - Add setDataTypeTreeFactory() method to OpcUaClient to allow switching between eager and lazy tree implementations - Add LazyTypeTreeUtils for batched browse and read operations with operation limit handling - Update OpcUaClient.getDataTypeTree() to use the configured factory instead of calling DataTypeTreeBuilder.build() directly - Include integration tests for LazyClientDataTypeTree and DataTypeTreeFactory --- .../typetree/DataTypeTreeFactoryTest.java | 76 +++ .../typetree/LazyClientDataTypeTreeTest.java | 286 +++++++++ .../milo/opcua/sdk/client/OpcUaClient.java | 29 +- .../client/typetree/DataTypeTreeFactory.java | 60 ++ .../typetree/LazyClientDataTypeTree.java | 567 ++++++++++++++++++ .../client/typetree/LazyTypeTreeUtils.java | 253 ++++++++ 6 files changed, 1270 insertions(+), 1 deletion(-) create mode 100644 opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeFactoryTest.java create mode 100644 opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeTest.java create mode 100644 opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeFactory.java create mode 100644 opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTree.java create mode 100644 opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java diff --git a/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeFactoryTest.java b/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeFactoryTest.java new file mode 100644 index 000000000..64aa2cce6 --- /dev/null +++ b/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeFactoryTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; + +import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; +import org.eclipse.milo.opcua.sdk.test.AbstractClientServerTest; +import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class DataTypeTreeFactoryTest extends AbstractClientServerTest { + + @Test + void defaultFactoryCreatesEagerTree() throws Exception { + DataTypeTree tree = client.getDataTypeTree(); + + assertNotNull(tree); + assertNotNull(tree.getDataType(NodeIds.Int32)); + assertNotNull(tree.getDataType(NodeIds.String)); + assertNotNull(tree.getDataType(NodeIds.XVType)); + } + + @Test + void setDataTypeTreeFactoryToLazy() throws Exception { + client.setDataTypeTreeFactory(DataTypeTreeFactory.lazy()); + + DataTypeTree tree = client.getDataTypeTree(); + + assertNotNull(tree); + assertInstanceOf(LazyClientDataTypeTree.class, tree); + assertNotNull(tree.getDataType(NodeIds.Int32)); + assertNotNull(tree.getDataType(NodeIds.String)); + assertNotNull(tree.getDataType(NodeIds.XVType)); + } + + @Test + void setDataTypeTreeFactoryResetsCache() throws Exception { + client.setDataTypeTreeFactory(DataTypeTreeFactory.eager()); + + DataTypeTree tree1 = client.getDataTypeTree(); + assertNotNull(tree1); + + client.setDataTypeTreeFactory(DataTypeTreeFactory.lazy()); + + DataTypeTree tree2 = client.getDataTypeTree(); + assertNotNull(tree2); + + assertNotSame(tree1, tree2); + assertInstanceOf(LazyClientDataTypeTree.class, tree2); + } + + @Test + void customFactoryIsUsed() throws Exception { + var customTree = new LazyClientDataTypeTree(client); + + client.setDataTypeTreeFactory(c -> customTree); + + DataTypeTree tree = client.getDataTypeTree(); + + assertNotNull(tree); + assertInstanceOf(LazyClientDataTypeTree.class, tree); + } +} diff --git a/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeTest.java b/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeTest.java new file mode 100644 index 000000000..ad31b00fd --- /dev/null +++ b/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeTest.java @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.milo.opcua.sdk.core.typetree.AbstractDataTypeTreeTest; +import org.eclipse.milo.opcua.sdk.core.typetree.DataType; +import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; +import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.util.Tree; +import org.junit.jupiter.api.Test; + +/** + * Integration tests for {@link LazyClientDataTypeTree}. + * + *

Extends {@link AbstractDataTypeTreeTest} to inherit all standard DataTypeTree tests, plus + * additional tests specific to lazy loading behavior. + */ +public class LazyClientDataTypeTreeTest extends AbstractDataTypeTreeTest { + + @Override + protected DataTypeTree getDataTypeTree() { + return new LazyClientDataTypeTree(client); + } + + @Test + void initiallyOnlyContainsBaseDataType() { + // Create a fresh tree to test the initial state + var freshTree = new LazyClientDataTypeTree(client); + + // BaseDataType should be resolved (it's the root) + assertTrue(freshTree.isResolved(NodeIds.BaseDataType)); + + // Other types should not be resolved yet + assertFalse(freshTree.isResolved(NodeIds.Int32)); + assertFalse(freshTree.isResolved(NodeIds.String)); + assertFalse(freshTree.isResolved(NodeIds.Structure)); + } + + @Test + void resolvesTypeOnDemand() { + var freshTree = new LazyClientDataTypeTree(client); + + // Int32 not resolved initially + assertFalse(freshTree.isResolved(NodeIds.Int32)); + + // Query Int32 - this should trigger resolution + DataType int32Type = freshTree.getDataType(NodeIds.Int32); + assertNotNull(int32Type); + assertEquals("Int32", int32Type.getBrowseName().name()); + + // Now Int32 should be resolved + assertTrue(freshTree.isResolved(NodeIds.Int32)); + + // Ancestors should also be resolved (Integer, Number, BaseDataType) + assertTrue(freshTree.isResolved(NodeIds.Integer)); + assertTrue(freshTree.isResolved(NodeIds.Number)); + assertTrue(freshTree.isResolved(NodeIds.BaseDataType)); + } + + @Test + void resolvesStructuredTypes() { + var freshTree = new LazyClientDataTypeTree(client); + + // Query a structured type + DataType xvType = freshTree.getDataType(NodeIds.XVType); + assertNotNull(xvType); + assertEquals("XVType", xvType.getBrowseName().name()); + + // Should have encoding IDs + assertNotNull(xvType.getBinaryEncodingId()); + + // Should have a DataTypeDefinition + assertNotNull(xvType.getDataTypeDefinition()); + + // Ancestors should be resolved + assertTrue(freshTree.isResolved(NodeIds.Structure)); + assertTrue(freshTree.isResolved(NodeIds.BaseDataType)); + } + + @Test + void isSubtypeOfWorksWithLazyResolution() { + var freshTree = new LazyClientDataTypeTree(client); + + // Neither Int32 nor Integer are resolved yet + assertFalse(freshTree.isResolved(NodeIds.Int32)); + assertFalse(freshTree.isResolved(NodeIds.Integer)); + + // This should trigger resolution of Int32 and its ancestors + assertTrue(freshTree.isSubtypeOf(NodeIds.Int32, NodeIds.Integer)); + assertTrue(freshTree.isSubtypeOf(NodeIds.Int32, NodeIds.Number)); + assertTrue(freshTree.isSubtypeOf(NodeIds.Int32, NodeIds.BaseDataType)); + + // Int32 is not a subtype of String + assertFalse(freshTree.isSubtypeOf(NodeIds.Int32, NodeIds.String)); + } + + @Test + void containsTypeTriggersResolution() { + var freshTree = new LazyClientDataTypeTree(client); + + // Double not resolved initially + assertFalse(freshTree.isResolved(NodeIds.Double)); + + // containsType should trigger resolution and return true + assertTrue(freshTree.containsType(NodeIds.Double)); + + // Now it should be resolved + assertTrue(freshTree.isResolved(NodeIds.Double)); + } + + @Test + void cachesResolvedTypes() { + var freshTree = new LazyClientDataTypeTree(client); + + // First query - triggers resolution + DataType first = freshTree.getDataType(NodeIds.Int32); + assertNotNull(first); + + // Second query - should return the same result from cache + DataType second = freshTree.getDataType(NodeIds.Int32); + assertNotNull(second); + + assertEquals(first.getNodeId(), second.getNodeId()); + assertEquals(first.getBrowseName(), second.getBrowseName()); + } + + @Test + void lazyTreeMatchesEagerTreeForResolvedTypes() throws UaException { + DataTypeTree eagerTree = DataTypeTreeBuilder.build(client); + var lazyTestTree = new LazyClientDataTypeTree(client); + + // Test a variety of types + NodeId[] typesToTest = { + NodeIds.Int32, + NodeIds.String, + NodeIds.Double, + NodeIds.DateTime, + NodeIds.ByteString, + NodeIds.Structure, + NodeIds.Enumeration, + NodeIds.XVType, + NodeIds.Range + }; + + for (NodeId typeId : typesToTest) { + DataType eagerType = eagerTree.getDataType(typeId); + DataType lazyType = lazyTestTree.getDataType(typeId); + + if (eagerType != null) { + assertNotNull(lazyType, "Lazy tree should resolve type: " + typeId); + assertEquals( + eagerType.getBrowseName(), + lazyType.getBrowseName(), + "BrowseName mismatch for " + typeId); + assertEquals( + eagerType.getBinaryEncodingId(), + lazyType.getBinaryEncodingId(), + "BinaryEncodingId mismatch for " + typeId); + assertEquals( + eagerType.getXmlEncodingId(), + lazyType.getXmlEncodingId(), + "XmlEncodingId mismatch for " + typeId); + assertEquals( + eagerType.getJsonEncodingId(), + lazyType.getJsonEncodingId(), + "JsonEncodingId mismatch for " + typeId); + assertEquals( + eagerType.isAbstract(), lazyType.isAbstract(), "IsAbstract mismatch for " + typeId); + } + } + } + + @Test + void diagnosticTestForStructure() throws Exception { + // Test that Structure can be resolved + var freshTree = new LazyClientDataTypeTree(client); + + // BaseDataType should be the only resolved type initially + assertTrue(freshTree.isResolved(NodeIds.BaseDataType), "BaseDataType should be pre-loaded"); + assertFalse(freshTree.isResolved(NodeIds.Structure), "Structure should not be resolved yet"); + + // Query Structure - should trigger lazy resolution + DataType structureType = freshTree.getType(NodeIds.Structure); + + assertNotNull(structureType, "Structure should be resolved"); + assertEquals("Structure", structureType.getBrowseName().name()); + } + + @Test + void clearFailedResolutionsAllowsRetry() { + var freshTree = new LazyClientDataTypeTree(client); + + // Try to resolve a non-existent type + NodeId fakeTypeId = new NodeId(999, "FakeDataType"); + DataType result = freshTree.getDataType(fakeTypeId); + + // Should return null + assertTrue(result == null || !freshTree.isResolved(fakeTypeId)); + + // Clear failed resolutions + freshTree.clearFailedResolutions(); + + // Now it can be attempted again (will still fail, but the point is it's retried) + result = freshTree.getDataType(fakeTypeId); + assertTrue(result == null || !freshTree.isResolved(fakeTypeId)); + } + + @Test + void getRootReturnsSnapshot() { + var freshTree = new LazyClientDataTypeTree(client); + + // Initially only BaseDataType is in the tree + Tree snapshot1 = freshTree.getRoot(); + var count1 = new AtomicInteger(0); + snapshot1.traverseNodes(node -> count1.incrementAndGet()); + assertEquals(1, count1.get(), "Initial snapshot should only contain BaseDataType"); + + // Resolve some types + freshTree.getDataType(NodeIds.Int32); // Resolves Int32 -> Integer -> Number -> BaseDataType + freshTree.getDataType(NodeIds.String); // Resolves String -> BaseDataType + + // Get a new snapshot - should reflect the resolved types + Tree snapshot2 = freshTree.getRoot(); + var count2 = new AtomicInteger(0); + snapshot2.traverseNodes(node -> count2.incrementAndGet()); + assertTrue(count2.get() > count1.get(), "Second snapshot should contain more types"); + + // The first snapshot should be unchanged (it's a copy) + var recount1 = new AtomicInteger(0); + snapshot1.traverseNodes(node -> recount1.incrementAndGet()); + assertEquals(count1.get(), recount1.get(), "First snapshot should be unchanged"); + + // Verify the snapshots are independent copies (not the same object) + assertNotEquals(snapshot1, snapshot2); + } + + @Test + void getRootSnapshotIsTraversable() { + var freshTree = new LazyClientDataTypeTree(client); + + // Resolve a few types to build up the tree + freshTree.getDataType(NodeIds.Int32); + freshTree.getDataType(NodeIds.Double); + freshTree.getDataType(NodeIds.String); + freshTree.getDataType(NodeIds.Structure); + + // Get a snapshot and traverse it + Tree snapshot = freshTree.getRoot(); + + // Verify we can traverse and find expected types + var foundInt32 = new AtomicInteger(0); + var foundDouble = new AtomicInteger(0); + var foundString = new AtomicInteger(0); + var foundStructure = new AtomicInteger(0); + + snapshot.traverse( + dataType -> { + if (NodeIds.Int32.equals(dataType.getNodeId())) foundInt32.incrementAndGet(); + if (NodeIds.Double.equals(dataType.getNodeId())) foundDouble.incrementAndGet(); + if (NodeIds.String.equals(dataType.getNodeId())) foundString.incrementAndGet(); + if (NodeIds.Structure.equals(dataType.getNodeId())) foundStructure.incrementAndGet(); + }); + + assertEquals(1, foundInt32.get(), "Should find Int32 in snapshot"); + assertEquals(1, foundDouble.get(), "Should find Double in snapshot"); + assertEquals(1, foundString.get(), "Should find String in snapshot"); + assertEquals(1, foundStructure.get(), "Should find Structure in snapshot"); + } +} diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java index 7420e3ed3..062db7e53 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java @@ -39,6 +39,7 @@ import org.eclipse.milo.opcua.sdk.client.subscriptions.OpcUaSubscription; import org.eclipse.milo.opcua.sdk.client.subscriptions.PublishingManager; import org.eclipse.milo.opcua.sdk.client.typetree.DataTypeTreeBuilder; +import org.eclipse.milo.opcua.sdk.client.typetree.DataTypeTreeFactory; import org.eclipse.milo.opcua.sdk.client.typetree.ObjectTypeTreeBuilder; import org.eclipse.milo.opcua.sdk.client.typetree.VariableTypeTreeBuilder; import org.eclipse.milo.opcua.sdk.core.types.codec.DynamicCodecFactory; @@ -332,6 +333,8 @@ public static OpcUaClient create( private DataTypeManagerInitializer dataTypeManagerInitializer = new DefaultDataTypeManagerInitializer(); + private DataTypeTreeFactory dataTypeTreeFactory = DataTypeTreeFactory.eager(); + private final EncodingManager encodingManager = DefaultEncodingManager.createAndInitialize(); private final DataTypeManager staticDataTypeManager = @@ -886,7 +889,7 @@ private void updateServerTable(String[] serverArray) { */ public DataTypeTree getDataTypeTree() throws UaException { try { - return dataTypeTree.getOrThrow(() -> DataTypeTreeBuilder.build(this)); + return dataTypeTree.getOrThrow(() -> dataTypeTreeFactory.create(this)); } catch (Exception e) { throw new UaException(e); } @@ -1095,6 +1098,30 @@ public void setDataTypeManagerInitializer(DataTypeManagerInitializer dataTypeMan dynamicEncodingContext.reset(); } + /** + * Set the {@link DataTypeTreeFactory} used to create the {@link DataTypeTree}. + * + *

By default, the client uses {@link DataTypeTreeFactory#eager()}, which eagerly builds the + * complete DataTypeTree using {@link DataTypeTreeBuilder#build(OpcUaClient)}. + * + *

Use {@link DataTypeTreeFactory#lazy()} to configure the client with a lazy-loading tree that + * resolves types on demand. This can be more efficient when only a subset of types is needed or + * when the server doesn't support recursive forward browsing of the DataType hierarchy. + * + *

This resets the client's cached {@link DataTypeTree}. It will be built or rebuilt the next + * time it is accessed. + * + * @param dataTypeTreeFactory the {@link DataTypeTreeFactory} to set. + * @see #getDataTypeTree() + * @see DataTypeTreeFactory#eager() + * @see DataTypeTreeFactory#lazy() + */ + public void setDataTypeTreeFactory(DataTypeTreeFactory dataTypeTreeFactory) { + this.dataTypeTreeFactory = dataTypeTreeFactory; + + dataTypeTree.reset(); + } + // region Attribute Services /** diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeFactory.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeFactory.java new file mode 100644 index 000000000..b89e0bd1c --- /dev/null +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeFactory.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; +import org.eclipse.milo.opcua.stack.core.UaException; + +/** + * A factory that creates a {@link DataTypeTree} for a given {@link OpcUaClient}. + * + *

Implementations can create different types of DataTypeTrees, such as: + * + *

+ * + * @see DataTypeTreeBuilder + * @see LazyClientDataTypeTree + */ +@FunctionalInterface +public interface DataTypeTreeFactory { + + /** + * Creates a {@link DataTypeTree} for the given client. + * + * @param client the {@link OpcUaClient} to create a DataTypeTree for. + * @return a new {@link DataTypeTree} instance. + * @throws UaException if an error occurs while creating the tree. + */ + DataTypeTree create(OpcUaClient client) throws UaException; + + /** + * Returns the default factory that eagerly builds a {@link DataTypeTree} using {@link + * DataTypeTreeBuilder#build(OpcUaClient)}. + * + * @return the default {@link DataTypeTreeFactory}. + */ + static DataTypeTreeFactory eager() { + return DataTypeTreeBuilder::build; + } + + /** + * Returns a factory that creates a {@link LazyClientDataTypeTree}. + * + * @return a {@link DataTypeTreeFactory} that creates lazy-loading trees. + */ + static DataTypeTreeFactory lazy() { + return LazyClientDataTypeTree::new; + } +} diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTree.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTree.java new file mode 100644 index 000000000..bea9c2f3a --- /dev/null +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTree.java @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.OperationLimits; +import org.eclipse.milo.opcua.sdk.core.typetree.DataType; +import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; +import org.eclipse.milo.opcua.stack.core.AttributeId; +import org.eclipse.milo.opcua.stack.core.NamespaceTable; +import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.eclipse.milo.opcua.stack.core.OpcUaDataType; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.types.DataTypeEncoding; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; +import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; +import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; +import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.DataTypeDefinition; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; +import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; +import org.eclipse.milo.opcua.stack.core.util.Tree; +import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A lazy-loading {@link DataTypeTree} that resolves types on demand by browsing inverse HasSubtype + * references. + * + *

Unlike {@link DataTypeTreeBuilder} which eagerly builds the entire tree by forward browsing + * from {@link NodeIds#BaseDataType}, this implementation starts with only the root type and + * resolves additional types lazily when they are queried. + * + *

This approach is useful when servers don't support recursive forward browsing of the DataType + * hierarchy or when only a subset of types is needed. + * + *

Thread Safety

+ * + *

This implementation is thread-safe. All read operations acquire a read lock and all + * modifications acquire a write lock. However, note that type resolution (which includes network + * I/O to browse and read from the server) is performed while holding the write lock. This means + * that concurrent threads attempting to resolve different types will be serialized. Once a type is + * resolved, later lookups only require the read lock and can proceed concurrently. + * + *

Resolution Behavior

+ * + *

Resolution errors (e.g., network failures, non-existent types) do not cause exceptions to be + * thrown from query methods like {@link #getDataType(NodeId)}. Instead, {@code null} is returned. + * Once a resolution attempt has failed, it will not be retried unless {@link + * #clearFailedResolutions()} is called. + * + *

Namespace Table

+ * + *

This tree caches a copy of the server's {@link NamespaceTable} for converting {@link + * org.eclipse.milo.opcua.stack.core.types.builtin.ExpandedNodeId}s during browse operations. If the + * server's namespace array changes (e.g., after a reconnection or dynamic namespace registration), + * call {@link #invalidateNamespaceTable()} or {@link #refreshNamespaceTable()} to update the cached + * copy. + */ +public class LazyClientDataTypeTree extends DataTypeTree { + + private static final Logger LOGGER = LoggerFactory.getLogger(LazyClientDataTypeTree.class); + + private final OpcUaClient client; + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private final Set attemptedResolution = ConcurrentHashMap.newKeySet(); + + private volatile NamespaceTable namespaceTable; + + /** + * Create a new {@link LazyClientDataTypeTree} with only {@link NodeIds#BaseDataType} initially + * loaded. + * + * @param client a connected {@link OpcUaClient}. + */ + public LazyClientDataTypeTree(OpcUaClient client) { + this(client, createRootTree()); + } + + /** + * Create a new {@link LazyClientDataTypeTree} with a pre-seeded tree. + * + *

This constructor supports preloading known types (e.g., namespace 0 types from a code + * generator) to reduce the number of lazy resolutions needed. + * + * @param client a connected {@link OpcUaClient}. + * @param preSeededTree a pre-built tree containing known types. + */ + public LazyClientDataTypeTree(OpcUaClient client, Tree preSeededTree) { + super(preSeededTree); + this.client = client; + } + + private static Tree createRootTree() { + return new Tree<>( + null, + new ClientDataType( + QualifiedName.parse("0:BaseDataType"), + NodeIds.BaseDataType, + null, + null, + null, + null, + true)); + } + + // ===== Namespace Table Management ===== + + private NamespaceTable getNamespaceTable() throws UaException { + NamespaceTable ns = namespaceTable; + if (ns == null) { + synchronized (this) { + ns = namespaceTable; + if (ns == null) { + ns = client.readNamespaceTable(); + namespaceTable = ns; + } + } + } + return ns; + } + + /** + * Invalidate the cached {@link NamespaceTable}, causing it to be re-read on next use. + * + *

Call this method when the server's namespace array may have changed (e.g., after a + * reconnection or when namespaces are dynamically registered on the server). + * + * @see #refreshNamespaceTable() + */ + public void invalidateNamespaceTable() { + namespaceTable = null; + } + + /** + * Refresh the cached {@link NamespaceTable} immediately by reading it from the server. + * + *

Unlike {@link #invalidateNamespaceTable()}, this method reads the namespace table + * immediately rather than deferring until the next type resolution. + * + * @throws UaException if reading the namespace table fails. + * @see #invalidateNamespaceTable() + */ + public void refreshNamespaceTable() throws UaException { + namespaceTable = client.readNamespaceTable(); + } + + // ===== Resolution State ===== + + /** + * Check if a type has been resolved/loaded without triggering resolution. + * + * @param typeId the {@link NodeId} to check. + * @return {@code true} if the type is already loaded in the tree. + */ + public boolean isResolved(NodeId typeId) { + lock.readLock().lock(); + try { + return types.containsKey(typeId); + } finally { + lock.readLock().unlock(); + } + } + + /** + * Clear failed resolution attempts, allowing retry. + * + *

When a type resolution fails (e.g., due to network errors or non-existent types), the + * failure is recorded to avoid repeated failed attempts. This method clears those records, + * allowing later queries for those types to attempt resolution again. + * + *

This is useful after transient network issues have been resolved or when the server's type + * system may have changed. + */ + public void clearFailedResolutions() { + lock.writeLock().lock(); + try { + attemptedResolution.retainAll(types.keySet()); + } finally { + lock.writeLock().unlock(); + } + } + + // ===== Core Resolution Logic ===== + + private void ensureResolved(NodeId dataTypeId) { + // Fast path under read lock + lock.readLock().lock(); + try { + if (types.containsKey(dataTypeId) || attemptedResolution.contains(dataTypeId)) { + return; + } + } finally { + lock.readLock().unlock(); + } + + // Slow path under write lock + lock.writeLock().lock(); + try { + // Re-check under write lock + if (types.containsKey(dataTypeId) || attemptedResolution.contains(dataTypeId)) { + return; + } + + attemptedResolution.add(dataTypeId); + + try { + resolvePath(dataTypeId); + } catch (UaException e) { + LOGGER.debug("Failed to resolve DataType {}: {}", dataTypeId, e.getMessage()); + } + } finally { + lock.writeLock().unlock(); + } + } + + private void resolvePath(NodeId dataTypeId) throws UaException { + NamespaceTable nsTable = getNamespaceTable(); + OperationLimits limits = client.getOperationLimits(); + + List pathToResolve = + LazyTypeTreeUtils.browseInverseUntilKnown(client, dataTypeId, types.keySet(), nsTable); + + if (pathToResolve.isEmpty() || pathToResolve.size() < 2) { + LOGGER.debug("Could not resolve path to known ancestor for DataType {}", dataTypeId); + return; + } + + // pathToResolve = [target, parent, ..., knownAncestor] + List nodesToAdd = pathToResolve.subList(0, pathToResolve.size() - 1); + NodeId knownAncestorId = pathToResolve.get(pathToResolve.size() - 1); + + List dataTypes = fetchDataTypeInfoBatch(nodesToAdd, nsTable, limits); + + // Add from ancestor toward target (reverse order) + Tree parentTree = types.get(knownAncestorId); + + for (int i = nodesToAdd.size() - 1; i >= 0; i--) { + ClientDataType dataType = dataTypes.get(i); + + if (dataType != null && parentTree != null) { + Tree childTree = parentTree.addChild(dataType); + types.put(dataType.getNodeId(), childTree); + parentTree = childTree; + + LOGGER.debug("Resolved DataType: {}", dataType.getBrowseName().toParseableString()); + } + } + } + + private List fetchDataTypeInfoBatch( + List nodeIds, NamespaceTable nsTable, OperationLimits limits) { + + // Read attributes: BrowseName, IsAbstract, DataTypeDefinition + var readValueIds = new ArrayList(); + for (NodeId nodeId : nodeIds) { + readValueIds.add( + new ReadValueId(nodeId, AttributeId.BrowseName.uid(), null, QualifiedName.NULL_VALUE)); + readValueIds.add( + new ReadValueId(nodeId, AttributeId.IsAbstract.uid(), null, QualifiedName.NULL_VALUE)); + readValueIds.add( + new ReadValueId( + nodeId, AttributeId.DataTypeDefinition.uid(), null, QualifiedName.NULL_VALUE)); + } + + List values = + LazyTypeTreeUtils.readWithOperationLimits(client, readValueIds, limits); + + // Browse encodings + List> encodingRefs = browseEncodings(nodeIds, limits); + + var result = new ArrayList(); + + for (int i = 0; i < nodeIds.size(); i++) { + NodeId nodeId = nodeIds.get(i); + int valueOffset = i * 3; + + QualifiedName browseName = extractBrowseName(values.get(valueOffset)); + Boolean isAbstract = extractIsAbstract(values.get(valueOffset + 1)); + DataTypeDefinition definition = extractDataTypeDefinition(values.get(valueOffset + 2)); + + NodeId binaryEncodingId = null; + NodeId xmlEncodingId = null; + NodeId jsonEncodingId = null; + + for (ReferenceDescription r : encodingRefs.get(i)) { + // Be lenient: also match on unqualified browse name (some servers use wrong namespace) + if (r.getBrowseName().equals(DataTypeEncoding.BINARY_ENCODING_NAME) + || Objects.equals(r.getBrowseName().name(), "Default Binary")) { + binaryEncodingId = r.getNodeId().toNodeId(nsTable).orElse(null); + } else if (r.getBrowseName().equals(DataTypeEncoding.XML_ENCODING_NAME) + || Objects.equals(r.getBrowseName().name(), "Default XML")) { + xmlEncodingId = r.getNodeId().toNodeId(nsTable).orElse(null); + } else if (r.getBrowseName().equals(DataTypeEncoding.JSON_ENCODING_NAME) + || Objects.equals(r.getBrowseName().name(), "Default JSON")) { + jsonEncodingId = r.getNodeId().toNodeId(nsTable).orElse(null); + } + } + + result.add( + new ClientDataType( + browseName, + nodeId, + binaryEncodingId, + xmlEncodingId, + jsonEncodingId, + definition, + isAbstract)); + } + + return result; + } + + private List> browseEncodings( + List dataTypeIds, OperationLimits limits) { + + List browseDescriptions = + dataTypeIds.stream() + .map( + dataTypeId -> + new BrowseDescription( + dataTypeId, + BrowseDirection.Forward, + NodeIds.HasEncoding, + false, + uint(NodeClass.Object.getValue()), + uint(BrowseResultMask.All.getValue()))) + .toList(); + + return LazyTypeTreeUtils.browseWithOperationLimits(client, browseDescriptions, limits); + } + + private static QualifiedName extractBrowseName(DataValue value) { + if (value.statusCode().isGood() && value.value().value() instanceof QualifiedName qn) { + return qn; + } + return QualifiedName.NULL_VALUE; + } + + private static Boolean extractIsAbstract(DataValue value) { + if (value.statusCode().isGood() && value.value().value() instanceof Boolean b) { + return b; + } + return false; + } + + private @Nullable DataTypeDefinition extractDataTypeDefinition(DataValue value) { + if (value.statusCode().isGood()) { + Object o = value.value().value(); + if (o instanceof ExtensionObject xo) { + try { + Object decoded = xo.decode(client.getStaticEncodingContext()); + if (decoded instanceof DataTypeDefinition dtd) { + return dtd; + } + } catch (Exception e) { + LOGGER.debug("Error decoding DataTypeDefinition: {}", e.getMessage()); + } + } else if (o instanceof DataTypeDefinition dtd) { + return dtd; + } + } + return null; + } + + // ===== Overridden Methods ===== + + /** + * Get a snapshot of the root of the underlying {@link Tree} structure. + * + *

Because this tree is lazily populated, returning the live tree would expose callers to + * potential concurrent modification during traversal. Instead, this method returns a deep copy + * (snapshot) of the current tree state, taken under a read lock. + * + *

The snapshot reflects the types that have been resolved at the time of the call. Types + * resolved after the snapshot is taken will not appear in the returned tree. + * + *

Note: The {@link Tree} structure is copied, but the contained {@link DataType} instances are + * shared references. This is safe because {@link DataType} instances are effectively immutable. + * + * @return a snapshot copy of the root node of the underlying {@link Tree} structure. + */ + @Override + public Tree getRoot() { + lock.readLock().lock(); + try { + return tree.map(dataType -> dataType); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public boolean containsType(NodeId typeId) { + ensureResolved(typeId); + lock.readLock().lock(); + try { + return super.containsType(typeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public @Nullable DataType getType(NodeId nodeId) { + ensureResolved(nodeId); + lock.readLock().lock(); + try { + return super.getType(nodeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public Class getBackingClass(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.getBackingClass(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public OpcUaDataType getBuiltinType(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.getBuiltinType(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public @Nullable DataType getDataType(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.getDataType(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public @Nullable NodeId getBinaryEncodingId(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.getBinaryEncodingId(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public @Nullable NodeId getXmlEncodingId(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.getXmlEncodingId(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public @Nullable NodeId getJsonEncodingId(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.getJsonEncodingId(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public @Nullable DataTypeDefinition getDataTypeDefinition(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.getDataTypeDefinition(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public boolean isAssignable(NodeId dataTypeId, Class clazz) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.isAssignable(dataTypeId, clazz); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public boolean isEnumType(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.isEnumType(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public boolean isStructType(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.isStructType(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public @Nullable Tree getTreeNode(NodeId dataTypeId) { + ensureResolved(dataTypeId); + lock.readLock().lock(); + try { + return super.getTreeNode(dataTypeId); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public boolean isSubtypeOf(NodeId typeId, NodeId superTypeId) { + ensureResolved(typeId); + lock.readLock().lock(); + try { + return super.isSubtypeOf(typeId, superTypeId); + } finally { + lock.readLock().unlock(); + } + } +} diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java new file mode 100644 index 000000000..7151e9af9 --- /dev/null +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import static java.util.Objects.requireNonNull; +import static java.util.Objects.requireNonNullElse; +import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; +import static org.eclipse.milo.opcua.stack.core.util.Lists.partition; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.OperationLimits; +import org.eclipse.milo.opcua.stack.core.NamespaceTable; +import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; +import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; +import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; +import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; +import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseNextResponse; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadResponse; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; +import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; +import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Shared utilities for lazy type tree implementations. */ +final class LazyTypeTreeUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(LazyTypeTreeUtils.class); + + private LazyTypeTreeUtils() {} + + /** + * Browse inverse HasSubtype references from {@code startId} until reaching a node that exists in + * {@code knownTypeIds}. + * + * @param client the OPC UA client to use for browsing. + * @param startId the NodeId to start browsing from. + * @param knownTypeIds the set of NodeIds that are already known/loaded. + * @param namespaceTable the namespace table for converting ExpandedNodeIds. + * @return path from startId to known ancestor (inclusive), or empty list if unreachable. + */ + static List browseInverseUntilKnown( + OpcUaClient client, NodeId startId, Set knownTypeIds, NamespaceTable namespaceTable) { + + List path = new ArrayList<>(); + NodeId current = startId; + + while (current != null && !knownTypeIds.contains(current)) { + path.add(current); + current = browseInverseParent(client, current, namespaceTable); + } + + if (current != null && knownTypeIds.contains(current)) { + path.add(current); + return path; + } + + return List.of(); + } + + /** + * Browse the inverse HasSubtype reference from {@code nodeId} to find its parent type. + * + * @param client the OPC UA client to use for browsing. + * @param nodeId the NodeId to browse from. + * @param namespaceTable the namespace table for converting ExpandedNodeIds. + * @return the parent NodeId, or null if not found. + */ + static @Nullable NodeId browseInverseParent( + OpcUaClient client, NodeId nodeId, NamespaceTable namespaceTable) { + + try { + BrowseDescription bd = + new BrowseDescription( + nodeId, + BrowseDirection.Inverse, + NodeIds.HasSubtype, + false, + uint(NodeClass.DataType.getValue()), + uint(BrowseResultMask.All.getValue())); + + BrowseResult result = client.browse(bd); + + if (result.getStatusCode().isGood() + && result.getReferences() != null + && result.getReferences().length > 0) { + + return result.getReferences()[0].getNodeId().toNodeId(namespaceTable).orElse(null); + } + } catch (UaException e) { + LOGGER.debug("Failed to browse inverse parent for {}: {}", nodeId, e.getMessage()); + } + + return null; + } + + /** + * Read values with operation limits, partitioning requests as necessary. + * + * @param client the OPC UA client. + * @param readValueIds the list of ReadValueIds to read. + * @param limits the operation limits from the server. + * @return the list of DataValues corresponding to the read requests. + */ + static List readWithOperationLimits( + OpcUaClient client, List readValueIds, OperationLimits limits) { + + if (readValueIds.isEmpty()) { + return List.of(); + } + + LOGGER.debug("readWithOperationLimits: {}", readValueIds.size()); + + int partitionSize = + limits + .maxNodesPerRead() + .map(UInteger::intValue) + .filter(v -> v > 0) + .orElse(Integer.MAX_VALUE); + + var values = new ArrayList(); + + partition(readValueIds, partitionSize) + .forEach( + partitionList -> { + try { + ReadResponse response = client.read(0.0, TimestampsToReturn.Neither, partitionList); + DataValue[] results = response.getResults(); + Collections.addAll(values, requireNonNull(results)); + } catch (UaException e) { + var value = new DataValue(e.getStatusCode()); + values.addAll(Collections.nCopies(partitionList.size(), value)); + } + }); + + return values; + } + + /** + * Browse with operation limits, partitioning requests as necessary. + * + * @param client the OPC UA client. + * @param browseDescriptions the list of BrowseDescriptions. + * @param limits the operation limits from the server. + * @return the list of reference description lists corresponding to each browse request. + */ + static List> browseWithOperationLimits( + OpcUaClient client, List browseDescriptions, OperationLimits limits) { + + if (browseDescriptions.isEmpty()) { + return List.of(); + } + + LOGGER.debug("browseWithOperationLimits: {}", browseDescriptions.size()); + + int partitionSize = + limits + .maxNodesPerBrowse() + .map(UInteger::intValue) + .filter(v -> v > 0) + .orElse(Integer.MAX_VALUE); + + var references = new ArrayList>(); + + partition(browseDescriptions, partitionSize) + .forEach(partitionList -> references.addAll(browse(client, partitionList))); + + return references; + } + + private static List> browse( + OpcUaClient client, List browseDescriptions) { + + if (browseDescriptions.isEmpty()) { + return List.of(); + } + + final var referenceDescriptionLists = new ArrayList>(); + + try { + client + .browse(browseDescriptions) + .forEach( + result -> { + if (result.getStatusCode().isGood()) { + var references = new ArrayList(); + + ReferenceDescription[] refs = + requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); + Collections.addAll(references, refs); + + ByteString continuationPoint = result.getContinuationPoint(); + List nextRefs = maybeBrowseNext(client, continuationPoint); + references.addAll(nextRefs); + + referenceDescriptionLists.add(references); + } else { + referenceDescriptionLists.add(List.of()); + } + }); + } catch (UaException e) { + referenceDescriptionLists.addAll(Collections.nCopies(browseDescriptions.size(), List.of())); + } + + return referenceDescriptionLists; + } + + private static List maybeBrowseNext( + OpcUaClient client, ByteString continuationPoint) { + + var references = new ArrayList(); + + while (continuationPoint != null && continuationPoint.isNotNull()) { + try { + BrowseNextResponse response = client.browseNext(false, List.of(continuationPoint)); + + BrowseResult result = requireNonNull(response.getResults())[0]; + + ReferenceDescription[] rds = + requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); + + references.addAll(List.of(rds)); + + continuationPoint = result.getContinuationPoint(); + } catch (Exception e) { + LOGGER.warn("BrowseNext failed: {}", e.getMessage(), e); + return references; + } + } + + return references; + } +} From 889103d2a3ca75263ed45d84c7025acbe605e42e Mon Sep 17 00:00:00 2001 From: Kevin Herron Date: Wed, 10 Dec 2025 17:12:32 -0800 Subject: [PATCH 2/8] Extract shared browse/read utilities into ClientBrowseUtils - Add ClientBrowseUtils class with methods for browse and read operations with operation limit handling - Refactor DataTypeTreeBuilder to use shared utilities and OperationLimits - Refactor ObjectTypeTreeBuilder to use shared utilities and OperationLimits - Refactor VariableTypeTreeBuilder to use shared utilities and OperationLimits - Simplify LazyTypeTreeUtils by delegating to ClientBrowseUtils --- .../client/typetree/ClientBrowseUtils.java | 207 +++++++++++++++++ .../client/typetree/DataTypeTreeBuilder.java | 200 ++-------------- .../client/typetree/LazyTypeTreeUtils.java | 122 +--------- .../typetree/ObjectTypeTreeBuilder.java | 192 ++------------- .../typetree/VariableTypeTreeBuilder.java | 219 ++---------------- 5 files changed, 272 insertions(+), 668 deletions(-) create mode 100644 opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ClientBrowseUtils.java diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ClientBrowseUtils.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ClientBrowseUtils.java new file mode 100644 index 000000000..8bd0ee6b0 --- /dev/null +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ClientBrowseUtils.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import static java.util.Objects.requireNonNull; +import static java.util.Objects.requireNonNullElse; +import static org.eclipse.milo.opcua.stack.core.util.Lists.partition; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.OperationLimits; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; +import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseNextResponse; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadResponse; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; +import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Shared utility methods for client-side browse and read operations with operation limit handling. + */ +final class ClientBrowseUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(ClientBrowseUtils.class); + + private ClientBrowseUtils() {} + + /** + * Get the server's operation limits from the client. + * + * @param client the OPC UA client. + * @return the operation limits. + * @throws UaException if fetching operation limits fails. + */ + static OperationLimits getOperationLimits(OpcUaClient client) throws UaException { + return client.getOperationLimits(); + } + + /** + * Read values with operation limits, partitioning requests as necessary. + * + * @param client the OPC UA client. + * @param readValueIds the list of ReadValueIds to read. + * @param limits the operation limits from the server. + * @return the list of DataValues corresponding to the read requests. + */ + static List readWithOperationLimits( + OpcUaClient client, List readValueIds, OperationLimits limits) { + + if (readValueIds.isEmpty()) { + return List.of(); + } + + LOGGER.debug("readWithOperationLimits: {}", readValueIds.size()); + + int partitionSize = + limits + .maxNodesPerRead() + .map(UInteger::intValue) + .filter(v -> v > 0) + .orElse(Integer.MAX_VALUE); + + var values = new ArrayList(); + + partition(readValueIds, partitionSize) + .forEach( + partitionList -> { + try { + ReadResponse response = client.read(0.0, TimestampsToReturn.Neither, partitionList); + DataValue[] results = response.getResults(); + Collections.addAll(values, requireNonNull(results)); + } catch (UaException e) { + LOGGER.debug("Read failed: {}", e.getMessage(), e); + var value = new DataValue(e.getStatusCode()); + values.addAll(Collections.nCopies(partitionList.size(), value)); + } + }); + + return values; + } + + /** + * Browse with operation limits, partitioning requests as necessary. + * + * @param client the OPC UA client. + * @param browseDescriptions the list of BrowseDescriptions. + * @param limits the operation limits from the server. + * @return the list of reference description lists corresponding to each browse request. + */ + static List> browseWithOperationLimits( + OpcUaClient client, List browseDescriptions, OperationLimits limits) { + + if (browseDescriptions.isEmpty()) { + return List.of(); + } + + LOGGER.debug("browseWithOperationLimits: {}", browseDescriptions.size()); + + int partitionSize = + limits + .maxNodesPerBrowse() + .map(UInteger::intValue) + .filter(v -> v > 0) + .orElse(Integer.MAX_VALUE); + + var references = new ArrayList>(); + + partition(browseDescriptions, partitionSize) + .forEach(partitionList -> references.addAll(browse(client, partitionList))); + + return references; + } + + /** + * Browse a list of nodes and return all reference descriptions, handling continuation points. + * + * @param client the OPC UA client. + * @param browseDescriptions the list of BrowseDescriptions. + * @return a list of reference description lists, one per browse description. + */ + static List> browse( + OpcUaClient client, List browseDescriptions) { + + if (browseDescriptions.isEmpty()) { + return List.of(); + } + + final var referenceDescriptionLists = new ArrayList>(); + + try { + client + .browse(browseDescriptions) + .forEach( + result -> { + if (result.getStatusCode().isGood()) { + var references = new ArrayList(); + + ReferenceDescription[] refs = + requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); + Collections.addAll(references, refs); + + ByteString continuationPoint = result.getContinuationPoint(); + List nextRefs = maybeBrowseNext(client, continuationPoint); + references.addAll(nextRefs); + + referenceDescriptionLists.add(references); + } else { + referenceDescriptionLists.add(List.of()); + } + }); + } catch (UaException e) { + referenceDescriptionLists.addAll(Collections.nCopies(browseDescriptions.size(), List.of())); + } + + return referenceDescriptionLists; + } + + /** + * Continue browsing using a continuation point until all references are retrieved. + * + * @param client the OPC UA client. + * @param continuationPoint the continuation point from a previous browse. + * @return the list of additional reference descriptions. + */ + static List maybeBrowseNext( + OpcUaClient client, ByteString continuationPoint) { + + var references = new ArrayList(); + + while (continuationPoint != null && continuationPoint.isNotNull()) { + try { + BrowseNextResponse response = client.browseNext(false, List.of(continuationPoint)); + + BrowseResult result = requireNonNull(response.getResults())[0]; + + ReferenceDescription[] rds = + requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); + + references.addAll(List.of(rds)); + + continuationPoint = result.getContinuationPoint(); + } catch (Exception e) { + LOGGER.warn("BrowseNext failed: {}", e.getMessage(), e); + return references; + } + } + + return references; + } +} diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeBuilder.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeBuilder.java index bf7ccd157..41f26b08a 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeBuilder.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeBuilder.java @@ -10,19 +10,16 @@ package org.eclipse.milo.opcua.sdk.client.typetree; -import static java.util.Objects.requireNonNull; -import static java.util.Objects.requireNonNullElse; import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; -import static org.eclipse.milo.opcua.stack.core.util.Lists.partition; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.stream.Collectors; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.OperationLimits; import org.eclipse.milo.opcua.sdk.core.typetree.DataType; import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; import org.eclipse.milo.opcua.stack.core.AttributeId; @@ -30,13 +27,17 @@ import org.eclipse.milo.opcua.stack.core.NodeIds; import org.eclipse.milo.opcua.stack.core.UaException; import org.eclipse.milo.opcua.stack.core.types.DataTypeEncoding; -import org.eclipse.milo.opcua.stack.core.types.builtin.*; -import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; -import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; -import org.eclipse.milo.opcua.stack.core.types.structured.*; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.DataTypeDefinition; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; +import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; import org.eclipse.milo.opcua.stack.core.util.Tree; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -72,11 +73,9 @@ public static DataTypeTree build(OpcUaClient client) throws UaException { NamespaceTable namespaceTable = client.readNamespaceTable(); - UInteger[] operationLimits = readOperationLimits(client); - UInteger maxNodesPerBrowse = operationLimits[0]; - UInteger maxNodesPerRead = operationLimits[1]; + OperationLimits operationLimits = ClientBrowseUtils.getOperationLimits(client); - addChildren(List.of(root), client, namespaceTable, maxNodesPerBrowse, maxNodesPerRead); + addChildren(List.of(root), client, namespaceTable, operationLimits); return new DataTypeTree(root); } @@ -105,11 +104,10 @@ private static void addChildren( List> parentTypes, OpcUaClient client, NamespaceTable namespaceTable, - UInteger maxNodesPerBrowse, - UInteger maxNodesPerRead) { + OperationLimits operationLimits) { List> parentSubtypes = - browseWithOperationLimits( + ClientBrowseUtils.browseWithOperationLimits( client, parentTypes.stream() .map( @@ -122,7 +120,7 @@ private static void addChildren( uint(NodeClass.DataType.getValue()), uint(BrowseResultMask.All.getValue()))) .collect(Collectors.toList()), - maxNodesPerBrowse); + operationLimits); var childTypes = new ArrayList>(); @@ -138,10 +136,10 @@ private static void addChildren( .collect(Collectors.toList()); List> encodingReferences = - browseEncodings(client, dataTypeIds, maxNodesPerBrowse); + browseEncodings(client, dataTypeIds, operationLimits); List dataTypeAttributes = - readDataTypeAttributes(client, dataTypeIds, maxNodesPerRead); + readDataTypeAttributes(client, dataTypeIds, operationLimits); assert subtypes.size() == dataTypeIds.size() && subtypes.size() == encodingReferences.size() @@ -202,75 +200,12 @@ private static void addChildren( } if (!childTypes.isEmpty()) { - addChildren(childTypes, client, namespaceTable, maxNodesPerBrowse, maxNodesPerRead); + addChildren(childTypes, client, namespaceTable, operationLimits); } } - private static List> browse( - OpcUaClient client, List browseDescriptions) { - - if (browseDescriptions.isEmpty()) { - return List.of(); - } - - final var referenceDescriptionLists = new ArrayList>(); - - try { - client - .browse(browseDescriptions) - .forEach( - result -> { - if (result.getStatusCode().isGood()) { - var references = new ArrayList(); - - ReferenceDescription[] refs = - requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); - Collections.addAll(references, refs); - - ByteString continuationPoint = result.getContinuationPoint(); - List nextRefs = maybeBrowseNext(client, continuationPoint); - references.addAll(nextRefs); - - referenceDescriptionLists.add(references); - } else { - referenceDescriptionLists.add(List.of()); - } - }); - } catch (UaException e) { - referenceDescriptionLists.addAll(Collections.nCopies(browseDescriptions.size(), List.of())); - } - - return referenceDescriptionLists; - } - - private static List maybeBrowseNext( - OpcUaClient client, ByteString continuationPoint) { - - var references = new ArrayList(); - - while (continuationPoint != null && continuationPoint.isNotNull()) { - try { - BrowseNextResponse response = client.browseNext(false, List.of(continuationPoint)); - - BrowseResult result = requireNonNull(response.getResults())[0]; - - ReferenceDescription[] rds = - requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); - - references.addAll(List.of(rds)); - - continuationPoint = result.getContinuationPoint(); - } catch (Exception e) { - LOGGER.warn("BrowseNext failed: {}", e.getMessage(), e); - return references; - } - } - - return references; - } - private static List> browseEncodings( - OpcUaClient client, List dataTypeIds, UInteger maxNodesPerBrowse) { + OpcUaClient client, List dataTypeIds, OperationLimits operationLimits) { List browseDescriptions = dataTypeIds.stream() @@ -285,11 +220,11 @@ private static List> browseEncodings( uint(BrowseResultMask.All.getValue()))) .collect(Collectors.toList()); - return browseWithOperationLimits(client, browseDescriptions, maxNodesPerBrowse); + return ClientBrowseUtils.browseWithOperationLimits(client, browseDescriptions, operationLimits); } private static List<@Nullable Attributes> readDataTypeAttributes( - OpcUaClient client, List dataTypeIds, UInteger maxNodesPerRead) { + OpcUaClient client, List dataTypeIds, OperationLimits operationLimits) { if (dataTypeIds.isEmpty()) { return List.of(); @@ -308,7 +243,8 @@ private static List> browseEncodings( var attributes = new ArrayList(); - List values = readWithOperationLimits(client, readValueIds, maxNodesPerRead); + List values = + ClientBrowseUtils.readWithOperationLimits(client, readValueIds, operationLimits); for (int i = 0; i < values.size(); i += 2) { DataValue isAbstractValue = values.get(i); @@ -349,96 +285,4 @@ private Attributes(Boolean isAbstract, DataTypeDefinition definition) { this.definition = definition; } } - - private static UInteger[] readOperationLimits(OpcUaClient client) throws UaException { - UInteger[] operationLimits = new UInteger[2]; - operationLimits[0] = uint(10); - operationLimits[1] = uint(100); - - List dataValues = - client.readValues( - 0.0, - TimestampsToReturn.Neither, - List.of( - NodeIds.OperationLimitsType_MaxNodesPerBrowse, - NodeIds.OperationLimitsType_MaxNodesPerRead)); - - DataValue maxNodesPerBrowse = dataValues.get(0); - if (maxNodesPerBrowse.statusCode().isGood() - && maxNodesPerBrowse.value().value() instanceof UInteger) { - - operationLimits[0] = (UInteger) maxNodesPerBrowse.value().value(); - } - - DataValue maxNodesPerRead = dataValues.get(1); - if (maxNodesPerRead.statusCode().isGood() - && dataValues.get(1).value().value() instanceof UInteger) { - - operationLimits[1] = (UInteger) maxNodesPerRead.value().value(); - } - - return operationLimits; - } - - private static List readWithOperationLimits( - OpcUaClient client, List readValueIds, UInteger maxNodesPerRead) { - - if (readValueIds.isEmpty()) { - return List.of(); - } - - LOGGER.debug("readWithOperationLimits: {}", readValueIds.size()); - - int partitionSize = - maxNodesPerRead.longValue() > Integer.MAX_VALUE - ? Integer.MAX_VALUE - : maxNodesPerRead.intValue(); - - if (partitionSize == 0) { - partitionSize = Integer.MAX_VALUE; - } - - var values = new ArrayList(); - - partition(readValueIds, partitionSize) - .forEach( - partition -> { - try { - ReadResponse response = client.read(0.0, TimestampsToReturn.Neither, partition); - DataValue[] results = response.getResults(); - Collections.addAll(values, requireNonNull(results)); - } catch (UaException e) { - var value = new DataValue(e.getStatusCode()); - values.addAll(Collections.nCopies(partition.size(), value)); - } - }); - - return values; - } - - private static List> browseWithOperationLimits( - OpcUaClient client, List browseDescriptions, UInteger maxNodesPerBrowse) { - - if (browseDescriptions.isEmpty()) { - return List.of(); - } - - LOGGER.debug("browseWithOperationLimits: {}", browseDescriptions.size()); - - int partitionSize = - maxNodesPerBrowse.longValue() > Integer.MAX_VALUE - ? Integer.MAX_VALUE - : maxNodesPerBrowse.intValue(); - - if (partitionSize == 0) { - partitionSize = Integer.MAX_VALUE; - } - - var references = new ArrayList>(); - - partition(browseDescriptions, partitionSize) - .forEach(partition -> references.addAll(browse(client, partition))); - - return references; - } } diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java index 7151e9af9..35a93a66a 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java @@ -10,13 +10,9 @@ package org.eclipse.milo.opcua.sdk.client.typetree; -import static java.util.Objects.requireNonNull; -import static java.util.Objects.requireNonNullElse; import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; -import static org.eclipse.milo.opcua.stack.core.util.Lists.partition; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Set; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; @@ -24,18 +20,13 @@ import org.eclipse.milo.opcua.stack.core.NamespaceTable; import org.eclipse.milo.opcua.stack.core.NodeIds; import org.eclipse.milo.opcua.stack.core.UaException; -import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString; import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; -import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; -import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; -import org.eclipse.milo.opcua.stack.core.types.structured.BrowseNextResponse; import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult; -import org.eclipse.milo.opcua.stack.core.types.structured.ReadResponse; import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; import org.jspecify.annotations.Nullable; @@ -125,35 +116,7 @@ static List browseInverseUntilKnown( static List readWithOperationLimits( OpcUaClient client, List readValueIds, OperationLimits limits) { - if (readValueIds.isEmpty()) { - return List.of(); - } - - LOGGER.debug("readWithOperationLimits: {}", readValueIds.size()); - - int partitionSize = - limits - .maxNodesPerRead() - .map(UInteger::intValue) - .filter(v -> v > 0) - .orElse(Integer.MAX_VALUE); - - var values = new ArrayList(); - - partition(readValueIds, partitionSize) - .forEach( - partitionList -> { - try { - ReadResponse response = client.read(0.0, TimestampsToReturn.Neither, partitionList); - DataValue[] results = response.getResults(); - Collections.addAll(values, requireNonNull(results)); - } catch (UaException e) { - var value = new DataValue(e.getStatusCode()); - values.addAll(Collections.nCopies(partitionList.size(), value)); - } - }); - - return values; + return ClientBrowseUtils.readWithOperationLimits(client, readValueIds, limits); } /** @@ -167,87 +130,6 @@ static List readWithOperationLimits( static List> browseWithOperationLimits( OpcUaClient client, List browseDescriptions, OperationLimits limits) { - if (browseDescriptions.isEmpty()) { - return List.of(); - } - - LOGGER.debug("browseWithOperationLimits: {}", browseDescriptions.size()); - - int partitionSize = - limits - .maxNodesPerBrowse() - .map(UInteger::intValue) - .filter(v -> v > 0) - .orElse(Integer.MAX_VALUE); - - var references = new ArrayList>(); - - partition(browseDescriptions, partitionSize) - .forEach(partitionList -> references.addAll(browse(client, partitionList))); - - return references; - } - - private static List> browse( - OpcUaClient client, List browseDescriptions) { - - if (browseDescriptions.isEmpty()) { - return List.of(); - } - - final var referenceDescriptionLists = new ArrayList>(); - - try { - client - .browse(browseDescriptions) - .forEach( - result -> { - if (result.getStatusCode().isGood()) { - var references = new ArrayList(); - - ReferenceDescription[] refs = - requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); - Collections.addAll(references, refs); - - ByteString continuationPoint = result.getContinuationPoint(); - List nextRefs = maybeBrowseNext(client, continuationPoint); - references.addAll(nextRefs); - - referenceDescriptionLists.add(references); - } else { - referenceDescriptionLists.add(List.of()); - } - }); - } catch (UaException e) { - referenceDescriptionLists.addAll(Collections.nCopies(browseDescriptions.size(), List.of())); - } - - return referenceDescriptionLists; - } - - private static List maybeBrowseNext( - OpcUaClient client, ByteString continuationPoint) { - - var references = new ArrayList(); - - while (continuationPoint != null && continuationPoint.isNotNull()) { - try { - BrowseNextResponse response = client.browseNext(false, List.of(continuationPoint)); - - BrowseResult result = requireNonNull(response.getResults())[0]; - - ReferenceDescription[] rds = - requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); - - references.addAll(List.of(rds)); - - continuationPoint = result.getContinuationPoint(); - } catch (Exception e) { - LOGGER.warn("BrowseNext failed: {}", e.getMessage(), e); - return references; - } - } - - return references; + return ClientBrowseUtils.browseWithOperationLimits(client, browseDescriptions, limits); } } diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ObjectTypeTreeBuilder.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ObjectTypeTreeBuilder.java index 01522001e..390bad4ca 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ObjectTypeTreeBuilder.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ObjectTypeTreeBuilder.java @@ -10,31 +10,30 @@ package org.eclipse.milo.opcua.sdk.client.typetree; -import static java.util.Objects.requireNonNull; -import static java.util.Objects.requireNonNullElse; import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; -import static org.eclipse.milo.opcua.stack.core.util.Lists.partition; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.stream.Collectors; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.OperationLimits; import org.eclipse.milo.opcua.sdk.core.typetree.ObjectType; import org.eclipse.milo.opcua.sdk.core.typetree.ObjectTypeTree; import org.eclipse.milo.opcua.stack.core.AttributeId; import org.eclipse.milo.opcua.stack.core.NamespaceTable; import org.eclipse.milo.opcua.stack.core.NodeIds; import org.eclipse.milo.opcua.stack.core.UaException; -import org.eclipse.milo.opcua.stack.core.types.builtin.*; -import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; -import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; -import org.eclipse.milo.opcua.stack.core.types.structured.*; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; +import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; import org.eclipse.milo.opcua.stack.core.util.Tree; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,11 +62,9 @@ public static ObjectTypeTree build(OpcUaClient client) throws UaException { NamespaceTable namespaceTable = client.readNamespaceTable(); - UInteger[] operationLimits = readOperationLimits(client); - UInteger maxNodesPerBrowse = operationLimits[0]; - UInteger maxNodesPerRead = operationLimits[1]; + OperationLimits operationLimits = ClientBrowseUtils.getOperationLimits(client); - addChildren(List.of(root), client, namespaceTable, maxNodesPerBrowse, maxNodesPerRead); + addChildren(List.of(root), client, namespaceTable, operationLimits); return new ObjectTypeTree(root); } @@ -96,11 +93,10 @@ private static void addChildren( List> parentTypes, OpcUaClient client, NamespaceTable namespaceTable, - UInteger maxNodesPerBrowse, - UInteger maxNodesPerRead) { + OperationLimits operationLimits) { List> parentSubtypes = - browseWithOperationLimits( + ClientBrowseUtils.browseWithOperationLimits( client, parentTypes.stream() .map( @@ -113,7 +109,7 @@ private static void addChildren( uint(NodeClass.ObjectType.getValue()), uint(BrowseResultMask.All.getValue()))) .collect(Collectors.toList()), - maxNodesPerBrowse); + operationLimits); var childTypes = new ArrayList>(); @@ -129,7 +125,7 @@ private static void addChildren( .collect(Collectors.toList()); List isAbstractValues = - readIsAbstractAttributes(client, objectTypeIds, maxNodesPerRead); + readIsAbstractAttributes(client, objectTypeIds, operationLimits); assert subtypes.size() == objectTypeIds.size() && subtypes.size() == isAbstractValues.size(); @@ -155,12 +151,12 @@ private static void addChildren( } if (!childTypes.isEmpty()) { - addChildren(childTypes, client, namespaceTable, maxNodesPerBrowse, maxNodesPerRead); + addChildren(childTypes, client, namespaceTable, operationLimits); } } private static List readIsAbstractAttributes( - OpcUaClient client, List objectTypeIds, UInteger maxNodesPerRead) { + OpcUaClient client, List objectTypeIds, OperationLimits operationLimits) { if (objectTypeIds.isEmpty()) { return List.of(); @@ -176,7 +172,8 @@ private static List readIsAbstractAttributes( var isAbstractValues = new ArrayList(); - List values = readWithOperationLimits(client, readValueIds, maxNodesPerRead); + List values = + ClientBrowseUtils.readWithOperationLimits(client, readValueIds, operationLimits); for (DataValue value : values) { Boolean isAbstract = false; @@ -190,159 +187,4 @@ private static List readIsAbstractAttributes( return isAbstractValues; } - - private static List> browse( - OpcUaClient client, List browseDescriptions) { - - if (browseDescriptions.isEmpty()) { - return List.of(); - } - - final var referenceDescriptionLists = new ArrayList>(); - - try { - client - .browse(browseDescriptions) - .forEach( - result -> { - if (result.getStatusCode().isGood()) { - var references = new ArrayList(); - - ReferenceDescription[] refs = - requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); - Collections.addAll(references, refs); - - ByteString continuationPoint = result.getContinuationPoint(); - List nextRefs = maybeBrowseNext(client, continuationPoint); - references.addAll(nextRefs); - - referenceDescriptionLists.add(references); - } else { - referenceDescriptionLists.add(List.of()); - } - }); - } catch (UaException e) { - referenceDescriptionLists.addAll(Collections.nCopies(browseDescriptions.size(), List.of())); - } - - return referenceDescriptionLists; - } - - private static List maybeBrowseNext( - OpcUaClient client, ByteString continuationPoint) { - - var references = new ArrayList(); - - while (continuationPoint != null && continuationPoint.isNotNull()) { - try { - BrowseNextResponse response = client.browseNext(false, List.of(continuationPoint)); - - BrowseResult result = requireNonNull(response.getResults())[0]; - - ReferenceDescription[] rds = - requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); - - references.addAll(List.of(rds)); - - continuationPoint = result.getContinuationPoint(); - } catch (Exception e) { - LOGGER.warn("BrowseNext failed: {}", e.getMessage(), e); - return references; - } - } - - return references; - } - - private static UInteger[] readOperationLimits(OpcUaClient client) throws UaException { - UInteger[] operationLimits = new UInteger[2]; - operationLimits[0] = uint(10); - operationLimits[1] = uint(100); - - List dataValues = - client.readValues( - 0.0, - TimestampsToReturn.Neither, - List.of( - NodeIds.OperationLimitsType_MaxNodesPerBrowse, - NodeIds.OperationLimitsType_MaxNodesPerRead)); - - DataValue maxNodesPerBrowse = dataValues.get(0); - if (maxNodesPerBrowse.statusCode().isGood() - && maxNodesPerBrowse.value().value() instanceof UInteger) { - - operationLimits[0] = (UInteger) maxNodesPerBrowse.value().value(); - } - - DataValue maxNodesPerRead = dataValues.get(1); - if (maxNodesPerRead.statusCode().isGood() - && dataValues.get(1).value().value() instanceof UInteger) { - - operationLimits[1] = (UInteger) maxNodesPerRead.value().value(); - } - - return operationLimits; - } - - private static List readWithOperationLimits( - OpcUaClient client, List readValueIds, UInteger maxNodesPerRead) { - - if (readValueIds.isEmpty()) { - return List.of(); - } - - LOGGER.debug("readWithOperationLimits: {}", readValueIds.size()); - - int partitionSize = - maxNodesPerRead.longValue() > Integer.MAX_VALUE - ? Integer.MAX_VALUE - : maxNodesPerRead.intValue(); - - if (partitionSize == 0) { - partitionSize = Integer.MAX_VALUE; - } - - var values = new ArrayList(); - - partition(readValueIds, partitionSize) - .forEach( - partition -> { - try { - ReadResponse response = client.read(0.0, TimestampsToReturn.Neither, partition); - DataValue[] results = response.getResults(); - Collections.addAll(values, requireNonNull(results)); - } catch (UaException e) { - var value = new DataValue(e.getStatusCode()); - values.addAll(Collections.nCopies(partition.size(), value)); - } - }); - - return values; - } - - private static List> browseWithOperationLimits( - OpcUaClient client, List browseDescriptions, UInteger maxNodesPerBrowse) { - - if (browseDescriptions.isEmpty()) { - return List.of(); - } - - LOGGER.debug("browseWithOperationLimits: {}", browseDescriptions.size()); - - int partitionSize = - maxNodesPerBrowse.longValue() > Integer.MAX_VALUE - ? Integer.MAX_VALUE - : maxNodesPerBrowse.intValue(); - - if (partitionSize == 0) { - partitionSize = Integer.MAX_VALUE; - } - - var references = new ArrayList>(); - - partition(browseDescriptions, partitionSize) - .forEach(partition -> references.addAll(browse(client, partition))); - - return references; - } } diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/VariableTypeTreeBuilder.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/VariableTypeTreeBuilder.java index dcc16f874..7b67153d4 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/VariableTypeTreeBuilder.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/VariableTypeTreeBuilder.java @@ -10,18 +10,15 @@ package org.eclipse.milo.opcua.sdk.client.typetree; -import static java.util.Objects.requireNonNull; -import static java.util.Objects.requireNonNullElse; import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; -import static org.eclipse.milo.opcua.stack.core.util.Lists.partition; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.stream.Collectors; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.OperationLimits; import org.eclipse.milo.opcua.sdk.core.ValueRanks; import org.eclipse.milo.opcua.sdk.core.typetree.VariableType; import org.eclipse.milo.opcua.sdk.core.typetree.VariableTypeTree; @@ -29,13 +26,17 @@ import org.eclipse.milo.opcua.stack.core.NamespaceTable; import org.eclipse.milo.opcua.stack.core.NodeIds; import org.eclipse.milo.opcua.stack.core.UaException; -import org.eclipse.milo.opcua.stack.core.types.builtin.*; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; +import org.eclipse.milo.opcua.stack.core.types.builtin.Variant; import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; -import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; -import org.eclipse.milo.opcua.stack.core.types.structured.*; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; +import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; import org.eclipse.milo.opcua.stack.core.util.Tree; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -71,11 +72,9 @@ public static VariableTypeTree build(OpcUaClient client) throws UaException { NamespaceTable namespaceTable = client.readNamespaceTable(); - UInteger[] operationLimits = readOperationLimits(client); - UInteger maxNodesPerBrowse = operationLimits[0]; - UInteger maxNodesPerRead = operationLimits[1]; + OperationLimits operationLimits = ClientBrowseUtils.getOperationLimits(client); - addChildren(List.of(root), client, namespaceTable, maxNodesPerBrowse, maxNodesPerRead); + addChildren(List.of(root), client, namespaceTable, operationLimits); return new VariableTypeTree(root); } @@ -104,11 +103,10 @@ private static void addChildren( List> parentTypes, OpcUaClient client, NamespaceTable namespaceTable, - UInteger maxNodesPerBrowse, - UInteger maxNodesPerRead) { + OperationLimits operationLimits) { List> parentSubtypes = - browseWithOperationLimits( + ClientBrowseUtils.browseWithOperationLimits( client, parentTypes.stream() .map( @@ -121,7 +119,7 @@ private static void addChildren( uint(NodeClass.VariableType.getValue()), uint(BrowseResultMask.All.getValue()))) .collect(Collectors.toList()), - maxNodesPerBrowse); + operationLimits); var childTypes = new ArrayList>(); @@ -137,7 +135,7 @@ private static void addChildren( .collect(Collectors.toList()); List variableTypeAttributes = - readVariableTypeAttributes(client, variableTypeIds, maxNodesPerRead); + readVariableTypeAttributes(client, variableTypeIds, operationLimits); assert subtypes.size() == variableTypeIds.size() && subtypes.size() == variableTypeAttributes.size(); @@ -172,12 +170,12 @@ private static void addChildren( } if (!childTypes.isEmpty()) { - addChildren(childTypes, client, namespaceTable, maxNodesPerBrowse, maxNodesPerRead); + addChildren(childTypes, client, namespaceTable, operationLimits); } } private static List readVariableTypeAttributes( - OpcUaClient client, List variableTypeIds, UInteger maxNodesPerRead) { + OpcUaClient client, List variableTypeIds, OperationLimits operationLimits) { if (variableTypeIds.isEmpty()) { return List.of(); @@ -204,7 +202,8 @@ private static List readVariableTypeAttributes( var attributes = new ArrayList(); - List values = readWithOperationLimits(client, readValueIds, maxNodesPerRead); + List values = + ClientBrowseUtils.readWithOperationLimits(client, readValueIds, operationLimits); for (int i = 0; i < values.size(); i += 5) { DataValue isAbstractValue = values.get(i); @@ -245,180 +244,10 @@ private static List readVariableTypeAttributes( return attributes; } - private static class Attributes { - final Boolean isAbstract; - final DataValue value; - final NodeId dataType; - final Integer valueRank; - final @Nullable UInteger[] arrayDimensions; - - private Attributes( - Boolean isAbstract, - DataValue value, - NodeId dataType, - Integer valueRank, - @Nullable UInteger[] arrayDimensions) { - - this.isAbstract = isAbstract; - this.value = value; - this.dataType = dataType; - this.valueRank = valueRank; - this.arrayDimensions = arrayDimensions; - } - } - - private static List> browse( - OpcUaClient client, List browseDescriptions) { - - if (browseDescriptions.isEmpty()) { - return List.of(); - } - - final var referenceDescriptionLists = new ArrayList>(); - - try { - client - .browse(browseDescriptions) - .forEach( - result -> { - if (result.getStatusCode().isGood()) { - var references = new ArrayList(); - - ReferenceDescription[] refs = - requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); - Collections.addAll(references, refs); - - ByteString continuationPoint = result.getContinuationPoint(); - List nextRefs = maybeBrowseNext(client, continuationPoint); - references.addAll(nextRefs); - - referenceDescriptionLists.add(references); - } else { - referenceDescriptionLists.add(List.of()); - } - }); - } catch (UaException e) { - referenceDescriptionLists.addAll(Collections.nCopies(browseDescriptions.size(), List.of())); - } - - return referenceDescriptionLists; - } - - private static List maybeBrowseNext( - OpcUaClient client, ByteString continuationPoint) { - - var references = new ArrayList(); - - while (continuationPoint != null && continuationPoint.isNotNull()) { - try { - BrowseNextResponse response = client.browseNext(false, List.of(continuationPoint)); - - BrowseResult result = requireNonNull(response.getResults())[0]; - - ReferenceDescription[] rds = - requireNonNullElse(result.getReferences(), new ReferenceDescription[0]); - - references.addAll(List.of(rds)); - - continuationPoint = result.getContinuationPoint(); - } catch (Exception e) { - LOGGER.warn("BrowseNext failed: {}", e.getMessage(), e); - return references; - } - } - - return references; - } - - private static UInteger[] readOperationLimits(OpcUaClient client) throws UaException { - UInteger[] operationLimits = new UInteger[2]; - operationLimits[0] = uint(10); - operationLimits[1] = uint(100); - - List dataValues = - client.readValues( - 0.0, - TimestampsToReturn.Neither, - List.of( - NodeIds.OperationLimitsType_MaxNodesPerBrowse, - NodeIds.OperationLimitsType_MaxNodesPerRead)); - - DataValue maxNodesPerBrowse = dataValues.get(0); - if (maxNodesPerBrowse.statusCode().isGood() - && maxNodesPerBrowse.value().value() instanceof UInteger) { - - operationLimits[0] = (UInteger) maxNodesPerBrowse.value().value(); - } - - DataValue maxNodesPerRead = dataValues.get(1); - if (maxNodesPerRead.statusCode().isGood() - && dataValues.get(1).value().value() instanceof UInteger) { - - operationLimits[1] = (UInteger) maxNodesPerRead.value().value(); - } - - return operationLimits; - } - - private static List readWithOperationLimits( - OpcUaClient client, List readValueIds, UInteger maxNodesPerRead) { - - if (readValueIds.isEmpty()) { - return List.of(); - } - - LOGGER.debug("readWithOperationLimits: {}", readValueIds.size()); - - int partitionSize = - maxNodesPerRead.longValue() > Integer.MAX_VALUE - ? Integer.MAX_VALUE - : maxNodesPerRead.intValue(); - - if (partitionSize == 0) { - partitionSize = Integer.MAX_VALUE; - } - - var values = new ArrayList(); - - partition(readValueIds, partitionSize) - .forEach( - partition -> { - try { - ReadResponse response = client.read(0.0, TimestampsToReturn.Neither, partition); - DataValue[] results = response.getResults(); - Collections.addAll(values, requireNonNull(results)); - } catch (UaException e) { - var value = new DataValue(e.getStatusCode()); - values.addAll(Collections.nCopies(partition.size(), value)); - } - }); - - return values; - } - - private static List> browseWithOperationLimits( - OpcUaClient client, List browseDescriptions, UInteger maxNodesPerBrowse) { - - if (browseDescriptions.isEmpty()) { - return List.of(); - } - - LOGGER.debug("browseWithOperationLimits: {}", browseDescriptions.size()); - - int partitionSize = - maxNodesPerBrowse.longValue() > Integer.MAX_VALUE - ? Integer.MAX_VALUE - : maxNodesPerBrowse.intValue(); - - if (partitionSize == 0) { - partitionSize = Integer.MAX_VALUE; - } - - var references = new ArrayList>(); - - partition(browseDescriptions, partitionSize) - .forEach(partition -> references.addAll(browse(client, partition))); - - return references; - } + private record Attributes( + Boolean isAbstract, + DataValue value, + NodeId dataType, + Integer valueRank, + @Nullable UInteger[] arrayDimensions) {} } From 80e15bec5019ca02c1785f3e7f4a595996e865b7 Mon Sep 17 00:00:00 2001 From: Kevin Herron Date: Wed, 10 Dec 2025 17:25:04 -0800 Subject: [PATCH 3/8] Remove unnecessary getOperationLimits wrapper in ClientBrowseUtils - Call client.getOperationLimits() directly in tree builders - Delete redundant wrapper method from ClientBrowseUtils --- .../opcua/sdk/client/typetree/ClientBrowseUtils.java | 11 ----------- .../sdk/client/typetree/DataTypeTreeBuilder.java | 2 +- .../sdk/client/typetree/ObjectTypeTreeBuilder.java | 2 +- .../sdk/client/typetree/VariableTypeTreeBuilder.java | 2 +- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ClientBrowseUtils.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ClientBrowseUtils.java index 8bd0ee6b0..74b894155 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ClientBrowseUtils.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ClientBrowseUtils.java @@ -42,17 +42,6 @@ final class ClientBrowseUtils { private ClientBrowseUtils() {} - /** - * Get the server's operation limits from the client. - * - * @param client the OPC UA client. - * @return the operation limits. - * @throws UaException if fetching operation limits fails. - */ - static OperationLimits getOperationLimits(OpcUaClient client) throws UaException { - return client.getOperationLimits(); - } - /** * Read values with operation limits, partitioning requests as necessary. * diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeBuilder.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeBuilder.java index 41f26b08a..f5385a3a2 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeBuilder.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeTreeBuilder.java @@ -73,7 +73,7 @@ public static DataTypeTree build(OpcUaClient client) throws UaException { NamespaceTable namespaceTable = client.readNamespaceTable(); - OperationLimits operationLimits = ClientBrowseUtils.getOperationLimits(client); + OperationLimits operationLimits = client.getOperationLimits(); addChildren(List.of(root), client, namespaceTable, operationLimits); diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ObjectTypeTreeBuilder.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ObjectTypeTreeBuilder.java index 390bad4ca..8cc783e5b 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ObjectTypeTreeBuilder.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/ObjectTypeTreeBuilder.java @@ -62,7 +62,7 @@ public static ObjectTypeTree build(OpcUaClient client) throws UaException { NamespaceTable namespaceTable = client.readNamespaceTable(); - OperationLimits operationLimits = ClientBrowseUtils.getOperationLimits(client); + OperationLimits operationLimits = client.getOperationLimits(); addChildren(List.of(root), client, namespaceTable, operationLimits); diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/VariableTypeTreeBuilder.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/VariableTypeTreeBuilder.java index 7b67153d4..0b54c330b 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/VariableTypeTreeBuilder.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/VariableTypeTreeBuilder.java @@ -72,7 +72,7 @@ public static VariableTypeTree build(OpcUaClient client) throws UaException { NamespaceTable namespaceTable = client.readNamespaceTable(); - OperationLimits operationLimits = ClientBrowseUtils.getOperationLimits(client); + OperationLimits operationLimits = client.getOperationLimits(); addChildren(List.of(root), client, namespaceTable, operationLimits); From 94b3391c04f4df8d01dcc558e9de592d66d88f31 Mon Sep 17 00:00:00 2001 From: Kevin Herron Date: Wed, 10 Dec 2025 19:26:19 -0800 Subject: [PATCH 4/8] Add seed tree for LazyClientDataTypeTree - Add LazyClientDataTypeTreeSeed with pre-populated primitive types and their subtypes (String, DateTime, ByteString, Number, etc.) - Structure and Enumeration base nodes are seeded without subtypes - Add SeededLazyClientDataTypeTreeTest to verify seeded tree behavior --- .../SeededLazyClientDataTypeTreeTest.java | 311 +++++++++++ .../typetree/LazyClientDataTypeTreeSeed.java | 509 ++++++++++++++++++ 2 files changed, 820 insertions(+) create mode 100644 opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/SeededLazyClientDataTypeTreeTest.java create mode 100644 opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java diff --git a/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/SeededLazyClientDataTypeTreeTest.java b/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/SeededLazyClientDataTypeTreeTest.java new file mode 100644 index 000000000..62cf4e4f1 --- /dev/null +++ b/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/SeededLazyClientDataTypeTreeTest.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.milo.opcua.sdk.core.typetree.AbstractDataTypeTreeTest; +import org.eclipse.milo.opcua.sdk.core.typetree.DataType; +import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; +import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.eclipse.milo.opcua.stack.core.OpcUaDataType; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.util.Tree; +import org.junit.jupiter.api.Test; + +/** + * Integration tests for {@link LazyClientDataTypeTree} using a pre-seeded tree. + * + *

Extends {@link AbstractDataTypeTreeTest} to inherit all standard DataTypeTree tests. Unlike + * {@link LazyClientDataTypeTreeTest}, this version uses the seed from {@link + * LazyClientDataTypeTreeSeed} which pre-populates non-structure types, so they are immediately + * resolvable without lazy browsing. + */ +public class SeededLazyClientDataTypeTreeTest extends AbstractDataTypeTreeTest { + + @Override + protected DataTypeTree getDataTypeTree() { + return new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + } + + @Test + void seededTypesAreImmediatelyResolved() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // All types from the seed should be resolved immediately + assertTrue(seededTree.isResolved(NodeIds.BaseDataType)); + assertTrue(seededTree.isResolved(NodeIds.Boolean)); + assertTrue(seededTree.isResolved(NodeIds.String)); + assertTrue(seededTree.isResolved(NodeIds.Int32)); + assertTrue(seededTree.isResolved(NodeIds.Double)); + assertTrue(seededTree.isResolved(NodeIds.DateTime)); + assertTrue(seededTree.isResolved(NodeIds.ByteString)); + assertTrue(seededTree.isResolved(NodeIds.Number)); + assertTrue(seededTree.isResolved(NodeIds.Integer)); + assertTrue(seededTree.isResolved(NodeIds.UInteger)); + assertTrue(seededTree.isResolved(NodeIds.Enumeration)); + } + + @Test + void primitiveTypesAvailableWithoutResolution() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Query primitive types - should return immediately without server browsing + DataType int32Type = seededTree.getDataType(NodeIds.Int32); + assertNotNull(int32Type); + assertEquals("Int32", int32Type.getBrowseName().name()); + + DataType stringType = seededTree.getDataType(NodeIds.String); + assertNotNull(stringType); + assertEquals("String", stringType.getBrowseName().name()); + + DataType doubleType = seededTree.getDataType(NodeIds.Double); + assertNotNull(doubleType); + assertEquals("Double", doubleType.getBrowseName().name()); + } + + @Test + void subTypesAreAvailable() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // String subtypes from the seed + assertTrue(seededTree.isResolved(NodeIds.NumericRange)); + assertTrue(seededTree.isResolved(NodeIds.LocaleId)); + + // ByteString subtypes from the seed + assertTrue(seededTree.isResolved(NodeIds.Image)); + assertTrue(seededTree.isResolved(NodeIds.ImageBMP)); + + // Number subtypes from the seed + assertTrue(seededTree.isResolved(NodeIds.Integer)); + assertTrue(seededTree.isResolved(NodeIds.UInteger)); + assertTrue(seededTree.isResolved(NodeIds.Float)); + } + + @Test + void isSubtypeOfWorksForSeededTypes() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Int32 -> Integer -> Number -> BaseDataType + assertTrue(seededTree.isSubtypeOf(NodeIds.Int32, NodeIds.Integer)); + assertTrue(seededTree.isSubtypeOf(NodeIds.Int32, NodeIds.Number)); + assertTrue(seededTree.isSubtypeOf(NodeIds.Int32, NodeIds.BaseDataType)); + + // String -> BaseDataType + assertTrue(seededTree.isSubtypeOf(NodeIds.String, NodeIds.BaseDataType)); + + // LocaleId -> String -> BaseDataType + assertTrue(seededTree.isSubtypeOf(NodeIds.LocaleId, NodeIds.String)); + assertTrue(seededTree.isSubtypeOf(NodeIds.LocaleId, NodeIds.BaseDataType)); + + // Int32 is not a subtype of String + assertFalse(seededTree.isSubtypeOf(NodeIds.Int32, NodeIds.String)); + } + + @Test + void enumerationBaseTypeIsSeeded() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Enumeration base type is in the seed + assertTrue(seededTree.isResolved(NodeIds.Enumeration)); + + // Enumeration subtypes are NOT seeded - they require lazy resolution + assertFalse(seededTree.isResolved(NodeIds.NodeClass)); + assertFalse(seededTree.isResolved(NodeIds.ServerState)); + assertFalse(seededTree.isResolved(NodeIds.RedundancySupport)); + } + + @Test + void enumerationSubtypesRequireLazyResolution() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Enumeration is in the seed, but NodeClass (a concrete enum subtype) is not + assertTrue(seededTree.isResolved(NodeIds.Enumeration)); + assertFalse(seededTree.isResolved(NodeIds.NodeClass)); + + // Querying NodeClass should trigger lazy resolution + DataType nodeClassType = seededTree.getDataType(NodeIds.NodeClass); + assertNotNull(nodeClassType); + assertEquals("NodeClass", nodeClassType.getBrowseName().name()); + + // Now NodeClass should be resolved + assertTrue(seededTree.isResolved(NodeIds.NodeClass)); + + // Should have DataTypeDefinition from resolution (enums have EnumDefinition) + assertNotNull(nodeClassType.getDataTypeDefinition()); + } + + @Test + void structureSubtypesRequireLazyResolution() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Structure is in the seed, but XVType (a concrete structure subtype) is not + assertTrue(seededTree.isResolved(NodeIds.Structure)); + assertFalse(seededTree.isResolved(NodeIds.XVType)); + + // Querying XVType should trigger lazy resolution + DataType xvType = seededTree.getDataType(NodeIds.XVType); + assertNotNull(xvType); + assertEquals("XVType", xvType.getBrowseName().name()); + + // Now XVType should be resolved + assertTrue(seededTree.isResolved(NodeIds.XVType)); + + // Should have encoding IDs and DataTypeDefinition from resolution + assertNotNull(xvType.getBinaryEncodingId()); + assertNotNull(xvType.getDataTypeDefinition()); + } + + @Test + void seededTreeMatchesEagerTreeForCommonTypes() throws UaException { + DataTypeTree eagerTree = DataTypeTreeBuilder.build(client); + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Test types that are in the seed + NodeId[] seededTypes = { + NodeIds.Int32, + NodeIds.String, + NodeIds.Double, + NodeIds.DateTime, + NodeIds.ByteString, + NodeIds.Boolean, + NodeIds.Guid, + NodeIds.Number, + NodeIds.Integer, + NodeIds.UInteger, + NodeIds.Enumeration + }; + + for (NodeId typeId : seededTypes) { + DataType eagerType = eagerTree.getDataType(typeId); + DataType seededType = seededTree.getDataType(typeId); + + if (eagerType != null) { + assertNotNull(seededType, "Seeded tree should have type: " + typeId); + assertEquals( + eagerType.getBrowseName(), + seededType.getBrowseName(), + "BrowseName mismatch for " + typeId); + assertEquals( + eagerType.isAbstract(), seededType.isAbstract(), "IsAbstract mismatch for " + typeId); + } + } + } + + @Test + void getRootContainsAllSeededTypes() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + Tree root = seededTree.getRoot(); + var count = new AtomicInteger(0); + root.traverseNodes(node -> count.incrementAndGet()); + + // The seed tree should contain many types (all the primitives, enums, etc.) + assertTrue(count.get() > 50, "Seeded tree should contain many pre-loaded types"); + } + + @Test + void clearFailedResolutionsAllowsRetry() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Try to resolve a non-existent type + NodeId fakeTypeId = new NodeId(999, "FakeDataType"); + DataType result = seededTree.getDataType(fakeTypeId); + + // Should return null + assertTrue(result == null || !seededTree.isResolved(fakeTypeId)); + + // Clear failed resolutions + seededTree.clearFailedResolutions(); + + // Now it can be attempted again + result = seededTree.getDataType(fakeTypeId); + assertTrue(result == null || !seededTree.isResolved(fakeTypeId)); + } + + @Test + void containsTypeReturnsTrueForSeededTypes() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // These should return true immediately without triggering resolution + assertTrue(seededTree.containsType(NodeIds.Int32)); + assertTrue(seededTree.containsType(NodeIds.String)); + assertTrue(seededTree.containsType(NodeIds.Double)); + assertTrue(seededTree.containsType(NodeIds.Enumeration)); + assertTrue(seededTree.containsType(NodeIds.Boolean)); + } + + @Test + void getBuiltinTypeWorksForSeededTypes() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Builtin type resolution should work for seeded types + assertEquals(OpcUaDataType.Int32, seededTree.getBuiltinType(NodeIds.Int32)); + assertEquals(OpcUaDataType.String, seededTree.getBuiltinType(NodeIds.String)); + assertEquals(OpcUaDataType.Double, seededTree.getBuiltinType(NodeIds.Double)); + assertEquals(OpcUaDataType.Boolean, seededTree.getBuiltinType(NodeIds.Boolean)); + } + + @Test + void isEnumTypeWorksWithLazyResolution() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Enumeration subtypes are not seeded but isEnumType triggers lazy resolution + assertTrue(seededTree.isEnumType(NodeIds.NodeClass)); + assertTrue(seededTree.isEnumType(NodeIds.ServerState)); + assertTrue(seededTree.isEnumType(NodeIds.RedundancySupport)); + + // Non-enum types (which are seeded) should not be recognized as enums + assertFalse(seededTree.isEnumType(NodeIds.Int32)); + assertFalse(seededTree.isEnumType(NodeIds.String)); + } + + @Test + void isStructTypeWorksForSeededTypes() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // Structure is in the seed + assertTrue(seededTree.isResolved(NodeIds.Structure)); + + // Note: isStructType uses isSubtypeOf, so Structure itself is NOT a struct type + // (a type is not a subtype of itself) + assertFalse(seededTree.isStructType(NodeIds.Structure)); + + // Primitive types (which are seeded) are not structs + assertFalse(seededTree.isStructType(NodeIds.Int32)); + assertFalse(seededTree.isStructType(NodeIds.String)); + assertFalse(seededTree.isStructType(NodeIds.Boolean)); + + // Lazily resolve a concrete struct type and verify isStructType works + DataType xvType = seededTree.getDataType(NodeIds.XVType); + assertNotNull(xvType); + assertTrue(seededTree.isStructType(NodeIds.XVType)); + } +} diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java new file mode 100644 index 000000000..741b29445 --- /dev/null +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java @@ -0,0 +1,509 @@ +package org.eclipse.milo.opcua.sdk.client.typetree; + +import org.eclipse.milo.opcua.sdk.core.typetree.DataType; +import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; +import org.eclipse.milo.opcua.stack.core.util.Tree; + +public final class LazyClientDataTypeTreeSeed { + private LazyClientDataTypeTreeSeed() {} + + public static Tree createSeedTree() { + Tree root = + new Tree<>( + null, + new ClientDataType( + QualifiedName.parse("0:BaseDataType"), + NodeIds.BaseDataType, + null, + null, + null, + null, + true)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Boolean"), NodeIds.Boolean, null, null, null, null, false)); + Tree stringType = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:String"), NodeIds.String, null, null, null, null, false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:NumericRange"), + NodeIds.NumericRange, + null, + null, + null, + null, + false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:LocaleId"), NodeIds.LocaleId, null, null, null, null, false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:NormalizedString"), + NodeIds.NormalizedString, + null, + null, + null, + null, + false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:DecimalString"), + NodeIds.DecimalString, + null, + null, + null, + null, + false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:DurationString"), + NodeIds.DurationString, + null, + null, + null, + null, + false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:TimeString"), + NodeIds.TimeString, + null, + null, + null, + null, + false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:DateString"), + NodeIds.DateString, + null, + null, + null, + null, + false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:UriString"), NodeIds.UriString, null, null, null, null, false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:SemanticVersionString"), + NodeIds.SemanticVersionString, + null, + null, + null, + null, + false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:EncodedTicket"), + NodeIds.EncodedTicket, + null, + null, + null, + null, + false)); + stringType.addChild( + new ClientDataType( + QualifiedName.parse("0:TrimmedString"), + NodeIds.TrimmedString, + null, + null, + null, + null, + false)); + Tree dateTime = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:DateTime"), + NodeIds.DateTime, + null, + null, + null, + null, + false)); + dateTime.addChild( + new ClientDataType( + QualifiedName.parse("0:UtcTime"), NodeIds.UtcTime, null, null, null, null, false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Guid"), NodeIds.Guid, null, null, null, null, false)); + Tree byteString = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:ByteString"), + NodeIds.ByteString, + null, + null, + null, + null, + false)); + Tree image = + byteString.addChild( + new ClientDataType( + QualifiedName.parse("0:Image"), NodeIds.Image, null, null, null, null, true)); + image.addChild( + new ClientDataType( + QualifiedName.parse("0:ImageBMP"), NodeIds.ImageBMP, null, null, null, null, false)); + image.addChild( + new ClientDataType( + QualifiedName.parse("0:ImageGIF"), NodeIds.ImageGIF, null, null, null, null, false)); + image.addChild( + new ClientDataType( + QualifiedName.parse("0:ImageJPG"), NodeIds.ImageJPG, null, null, null, null, false)); + image.addChild( + new ClientDataType( + QualifiedName.parse("0:ImagePNG"), NodeIds.ImagePNG, null, null, null, null, false)); + byteString.addChild( + new ClientDataType( + QualifiedName.parse("0:ApplicationInstanceCertificate"), + NodeIds.ApplicationInstanceCertificate, + null, + null, + null, + null, + false)); + byteString.addChild( + new ClientDataType( + QualifiedName.parse("0:ContinuationPoint"), + NodeIds.ContinuationPoint, + null, + null, + null, + null, + false)); + byteString.addChild( + new ClientDataType( + QualifiedName.parse("0:AudioDataType"), + NodeIds.AudioDataType, + null, + null, + null, + null, + false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:XmlElement"), + NodeIds.XmlElement, + null, + null, + null, + null, + false)); + Tree nodeId = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:NodeId"), NodeIds.NodeId, null, null, null, null, false)); + nodeId.addChild( + new ClientDataType( + QualifiedName.parse("0:SessionAuthenticationToken"), + NodeIds.SessionAuthenticationToken, + null, + null, + null, + null, + false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:ExpandedNodeId"), + NodeIds.ExpandedNodeId, + null, + null, + null, + null, + false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:StatusCode"), + NodeIds.StatusCode, + null, + null, + null, + null, + false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:QualifiedName"), + NodeIds.QualifiedName, + null, + null, + null, + null, + false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:LocalizedText"), + NodeIds.LocalizedText, + null, + null, + null, + null, + false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Structure"), NodeIds.Structure, null, null, null, null, true)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:DataValue"), NodeIds.DataValue, null, null, null, null, false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:DiagnosticInfo"), + NodeIds.DiagnosticInfo, + null, + null, + null, + null, + false)); + Tree numberType = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Number"), NodeIds.Number, null, null, null, null, true)); + numberType.addChild( + new ClientDataType( + QualifiedName.parse("0:Float"), NodeIds.Float, null, null, null, null, false)); + Tree doubleType = + numberType.addChild( + new ClientDataType( + QualifiedName.parse("0:Double"), NodeIds.Double, null, null, null, null, false)); + doubleType.addChild( + new ClientDataType( + QualifiedName.parse("0:Duration"), NodeIds.Duration, null, null, null, null, false)); + Tree integerType = + numberType.addChild( + new ClientDataType( + QualifiedName.parse("0:Integer"), NodeIds.Integer, null, null, null, null, true)); + integerType.addChild( + new ClientDataType( + QualifiedName.parse("0:SByte"), NodeIds.SByte, null, null, null, null, false)); + integerType.addChild( + new ClientDataType( + QualifiedName.parse("0:Int16"), NodeIds.Int16, null, null, null, null, false)); + integerType.addChild( + new ClientDataType( + QualifiedName.parse("0:Int32"), NodeIds.Int32, null, null, null, null, false)); + integerType.addChild( + new ClientDataType( + QualifiedName.parse("0:Int64"), NodeIds.Int64, null, null, null, null, false)); + Tree uInteger = + numberType.addChild( + new ClientDataType( + QualifiedName.parse("0:UInteger"), NodeIds.UInteger, null, null, null, null, true)); + Tree byteType = + uInteger.addChild( + new ClientDataType( + QualifiedName.parse("0:Byte"), NodeIds.Byte, null, null, null, null, false)); + byteType.addChild( + new ClientDataType( + QualifiedName.parse("0:AccessLevelType"), + NodeIds.AccessLevelType, + null, + null, + null, + null, + false)); + byteType.addChild( + new ClientDataType( + QualifiedName.parse("0:EventNotifierType"), + NodeIds.EventNotifierType, + null, + null, + null, + null, + false)); + Tree uInt16 = + uInteger.addChild( + new ClientDataType( + QualifiedName.parse("0:UInt16"), NodeIds.UInt16, null, null, null, null, false)); + uInt16.addChild( + new ClientDataType( + QualifiedName.parse("0:AccessRestrictionType"), + NodeIds.AccessRestrictionType, + null, + null, + null, + null, + false)); + uInt16.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetFieldFlags"), + NodeIds.DataSetFieldFlags, + null, + null, + null, + null, + false)); + uInt16.addChild( + new ClientDataType( + QualifiedName.parse("0:AlarmMask"), NodeIds.AlarmMask, null, null, null, null, false)); + Tree uInt32 = + uInteger.addChild( + new ClientDataType( + QualifiedName.parse("0:UInt32"), NodeIds.UInt32, null, null, null, null, false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:PermissionType"), + NodeIds.PermissionType, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:IntegerId"), NodeIds.IntegerId, null, null, null, null, false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:Counter"), NodeIds.Counter, null, null, null, null, false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:AttributeWriteMask"), + NodeIds.AttributeWriteMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:AccessLevelExType"), + NodeIds.AccessLevelExType, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetFieldContentMask"), + NodeIds.DataSetFieldContentMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:UadpNetworkMessageContentMask"), + NodeIds.UadpNetworkMessageContentMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:UadpDataSetMessageContentMask"), + NodeIds.UadpDataSetMessageContentMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:JsonNetworkMessageContentMask"), + NodeIds.JsonNetworkMessageContentMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:JsonDataSetMessageContentMask"), + NodeIds.JsonDataSetMessageContentMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:Index"), NodeIds.Index, null, null, null, null, false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:LldpSystemCapabilitiesMap"), + NodeIds.LldpSystemCapabilitiesMap, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:VersionTime"), + NodeIds.VersionTime, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:TrustListValidationOptions"), + NodeIds.TrustListValidationOptions, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:PasswordOptionsMask"), + NodeIds.PasswordOptionsMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:UserConfigurationMask"), + NodeIds.UserConfigurationMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubConfigurationRefMask"), + NodeIds.PubSubConfigurationRefMask, + null, + null, + null, + null, + false)); + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:Handle"), NodeIds.Handle, null, null, null, null, false)); + Tree uInt64 = + uInteger.addChild( + new ClientDataType( + QualifiedName.parse("0:UInt64"), NodeIds.UInt64, null, null, null, null, false)); + uInt64.addChild( + new ClientDataType( + QualifiedName.parse("0:BitFieldMaskDataType"), + NodeIds.BitFieldMaskDataType, + null, + null, + null, + null, + false)); + numberType.addChild( + new ClientDataType( + QualifiedName.parse("0:Decimal"), NodeIds.Decimal, null, null, null, null, false)); + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Enumeration"), + NodeIds.Enumeration, + null, + null, + null, + null, + true)); + return root; + } +} From 1e3cfcb3a6609af5dcd166b0d2c214a9b8da8fef Mon Sep 17 00:00:00 2001 From: Kevin Herron Date: Thu, 11 Dec 2025 07:49:14 -0800 Subject: [PATCH 5/8] Seed structures and enumerations in LazyClientDataTypeTreeSeed --- .../SeededLazyClientDataTypeTreeTest.java | 66 +- .../typetree/LazyClientDataTypeTreeSeed.java | 11633 +++++++++++++++- 2 files changed, 11231 insertions(+), 468 deletions(-) diff --git a/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/SeededLazyClientDataTypeTreeTest.java b/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/SeededLazyClientDataTypeTreeTest.java index 62cf4e4f1..e57a9fad7 100644 --- a/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/SeededLazyClientDataTypeTreeTest.java +++ b/opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/typetree/SeededLazyClientDataTypeTreeTest.java @@ -120,60 +120,67 @@ void isSubtypeOfWorksForSeededTypes() { } @Test - void enumerationBaseTypeIsSeeded() { + void enumerationSubtypesAreSeeded() { var seededTree = new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); - // Enumeration base type is in the seed + // Enumeration and its subtypes are in the seed assertTrue(seededTree.isResolved(NodeIds.Enumeration)); - - // Enumeration subtypes are NOT seeded - they require lazy resolution - assertFalse(seededTree.isResolved(NodeIds.NodeClass)); - assertFalse(seededTree.isResolved(NodeIds.ServerState)); - assertFalse(seededTree.isResolved(NodeIds.RedundancySupport)); + assertTrue(seededTree.isResolved(NodeIds.NodeClass)); + assertTrue(seededTree.isResolved(NodeIds.ServerState)); + assertTrue(seededTree.isResolved(NodeIds.RedundancySupport)); } @Test - void enumerationSubtypesRequireLazyResolution() { + void seededEnumerationSubtypesHaveDefinitions() { var seededTree = new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); - // Enumeration is in the seed, but NodeClass (a concrete enum subtype) is not - assertTrue(seededTree.isResolved(NodeIds.Enumeration)); - assertFalse(seededTree.isResolved(NodeIds.NodeClass)); - - // Querying NodeClass should trigger lazy resolution + // NodeClass is a seeded enum subtype with an EnumDefinition DataType nodeClassType = seededTree.getDataType(NodeIds.NodeClass); assertNotNull(nodeClassType); assertEquals("NodeClass", nodeClassType.getBrowseName().name()); - - // Now NodeClass should be resolved assertTrue(seededTree.isResolved(NodeIds.NodeClass)); - - // Should have DataTypeDefinition from resolution (enums have EnumDefinition) assertNotNull(nodeClassType.getDataTypeDefinition()); + + // ServerState is a seeded enum subtype with an EnumDefinition + DataType serverStateType = seededTree.getDataType(NodeIds.ServerState); + assertNotNull(serverStateType); + assertEquals("ServerState", serverStateType.getBrowseName().name()); + assertNotNull(serverStateType.getDataTypeDefinition()); } @Test - void structureSubtypesRequireLazyResolution() { + void structureSubtypesAreSeeded() { var seededTree = new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); - // Structure is in the seed, but XVType (a concrete structure subtype) is not + // Structure and its subtypes are in the seed assertTrue(seededTree.isResolved(NodeIds.Structure)); - assertFalse(seededTree.isResolved(NodeIds.XVType)); + assertTrue(seededTree.isResolved(NodeIds.XVType)); + assertTrue(seededTree.isResolved(NodeIds.RolePermissionType)); + assertTrue(seededTree.isResolved(NodeIds.StructureDefinition)); + } - // Querying XVType should trigger lazy resolution + @Test + void seededStructureSubtypesHaveEncodingIdsAndDefinitions() { + var seededTree = + new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); + + // XVType is a seeded structure subtype with encoding IDs and definition DataType xvType = seededTree.getDataType(NodeIds.XVType); assertNotNull(xvType); assertEquals("XVType", xvType.getBrowseName().name()); - - // Now XVType should be resolved assertTrue(seededTree.isResolved(NodeIds.XVType)); - - // Should have encoding IDs and DataTypeDefinition from resolution assertNotNull(xvType.getBinaryEncodingId()); assertNotNull(xvType.getDataTypeDefinition()); + + // RolePermissionType is a seeded structure subtype with encoding IDs and definition + DataType rolePermType = seededTree.getDataType(NodeIds.RolePermissionType); + assertNotNull(rolePermType); + assertEquals("RolePermissionType", rolePermType.getBrowseName().name()); + assertNotNull(rolePermType.getBinaryEncodingId()); + assertNotNull(rolePermType.getDataTypeDefinition()); } @Test @@ -272,11 +279,11 @@ void getBuiltinTypeWorksForSeededTypes() { } @Test - void isEnumTypeWorksWithLazyResolution() { + void isEnumTypeWorksForSeededTypes() { var seededTree = new LazyClientDataTypeTree(client, LazyClientDataTypeTreeSeed.createSeedTree()); - // Enumeration subtypes are not seeded but isEnumType triggers lazy resolution + // Enumeration subtypes are seeded and isEnumType works immediately assertTrue(seededTree.isEnumType(NodeIds.NodeClass)); assertTrue(seededTree.isEnumType(NodeIds.ServerState)); assertTrue(seededTree.isEnumType(NodeIds.RedundancySupport)); @@ -303,9 +310,8 @@ void isStructTypeWorksForSeededTypes() { assertFalse(seededTree.isStructType(NodeIds.String)); assertFalse(seededTree.isStructType(NodeIds.Boolean)); - // Lazily resolve a concrete struct type and verify isStructType works - DataType xvType = seededTree.getDataType(NodeIds.XVType); - assertNotNull(xvType); + // Seeded structure subtypes can be verified with isStructType immediately assertTrue(seededTree.isStructType(NodeIds.XVType)); + assertTrue(seededTree.isStructType(NodeIds.RolePermissionType)); } } diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java index 741b29445..7a5180540 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java @@ -1,13 +1,31 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + package org.eclipse.milo.opcua.sdk.client.typetree; import org.eclipse.milo.opcua.sdk.core.typetree.DataType; import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText; import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; +import org.eclipse.milo.opcua.stack.core.types.enumerated.StructureType; +import org.eclipse.milo.opcua.stack.core.types.structured.EnumDefinition; +import org.eclipse.milo.opcua.stack.core.types.structured.EnumField; +import org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition; +import org.eclipse.milo.opcua.stack.core.types.structured.StructureField; import org.eclipse.milo.opcua.stack.core.util.Tree; public final class LazyClientDataTypeTreeSeed { private LazyClientDataTypeTreeSeed() {} + @SuppressWarnings("unused") public static Tree createSeedTree() { Tree root = new Tree<>( @@ -20,100 +38,124 @@ public static Tree createSeedTree() { null, null, true)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:Boolean"), NodeIds.Boolean, null, null, null, null, false)); - Tree stringType = + Tree booleanType = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Boolean"), NodeIds.Boolean, null, null, null, null, false)); + Tree string = root.addChild( new ClientDataType( QualifiedName.parse("0:String"), NodeIds.String, null, null, null, null, false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:NumericRange"), - NodeIds.NumericRange, - null, - null, - null, - null, - false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:LocaleId"), NodeIds.LocaleId, null, null, null, null, false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:NormalizedString"), - NodeIds.NormalizedString, - null, - null, - null, - null, - false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:DecimalString"), - NodeIds.DecimalString, - null, - null, - null, - null, - false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:DurationString"), - NodeIds.DurationString, - null, - null, - null, - null, - false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:TimeString"), - NodeIds.TimeString, - null, - null, - null, - null, - false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:DateString"), - NodeIds.DateString, - null, - null, - null, - null, - false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:UriString"), NodeIds.UriString, null, null, null, null, false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:SemanticVersionString"), - NodeIds.SemanticVersionString, - null, - null, - null, - null, - false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:EncodedTicket"), - NodeIds.EncodedTicket, - null, - null, - null, - null, - false)); - stringType.addChild( - new ClientDataType( - QualifiedName.parse("0:TrimmedString"), - NodeIds.TrimmedString, - null, - null, - null, - null, - false)); + Tree numericRange = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:NumericRange"), + NodeIds.NumericRange, + null, + null, + null, + null, + false)); + Tree localeId = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:LocaleId"), + NodeIds.LocaleId, + null, + null, + null, + null, + false)); + Tree normalizedString = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:NormalizedString"), + NodeIds.NormalizedString, + null, + null, + null, + null, + false)); + Tree decimalString = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:DecimalString"), + NodeIds.DecimalString, + null, + null, + null, + null, + false)); + Tree durationString = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:DurationString"), + NodeIds.DurationString, + null, + null, + null, + null, + false)); + Tree timeString = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:TimeString"), + NodeIds.TimeString, + null, + null, + null, + null, + false)); + Tree dateString = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:DateString"), + NodeIds.DateString, + null, + null, + null, + null, + false)); + Tree uriString = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:UriString"), + NodeIds.UriString, + null, + null, + null, + null, + false)); + Tree semanticVersionString = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:SemanticVersionString"), + NodeIds.SemanticVersionString, + null, + null, + null, + null, + false)); + Tree encodedTicket = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:EncodedTicket"), + NodeIds.EncodedTicket, + null, + null, + null, + null, + false)); + Tree trimmedString = + string.addChild( + new ClientDataType( + QualifiedName.parse("0:TrimmedString"), + NodeIds.TrimmedString, + null, + null, + null, + null, + false)); Tree dateTime = root.addChild( new ClientDataType( @@ -124,12 +166,14 @@ public static Tree createSeedTree() { null, null, false)); - dateTime.addChild( - new ClientDataType( - QualifiedName.parse("0:UtcTime"), NodeIds.UtcTime, null, null, null, null, false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:Guid"), NodeIds.Guid, null, null, null, null, false)); + Tree utcTime = + dateTime.addChild( + new ClientDataType( + QualifiedName.parse("0:UtcTime"), NodeIds.UtcTime, null, null, null, null, false)); + Tree guid = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Guid"), NodeIds.Guid, null, null, null, null, false)); Tree byteString = root.addChild( new ClientDataType( @@ -144,366 +188,11079 @@ public static Tree createSeedTree() { byteString.addChild( new ClientDataType( QualifiedName.parse("0:Image"), NodeIds.Image, null, null, null, null, true)); - image.addChild( - new ClientDataType( - QualifiedName.parse("0:ImageBMP"), NodeIds.ImageBMP, null, null, null, null, false)); - image.addChild( - new ClientDataType( - QualifiedName.parse("0:ImageGIF"), NodeIds.ImageGIF, null, null, null, null, false)); - image.addChild( - new ClientDataType( - QualifiedName.parse("0:ImageJPG"), NodeIds.ImageJPG, null, null, null, null, false)); - image.addChild( - new ClientDataType( - QualifiedName.parse("0:ImagePNG"), NodeIds.ImagePNG, null, null, null, null, false)); - byteString.addChild( - new ClientDataType( - QualifiedName.parse("0:ApplicationInstanceCertificate"), - NodeIds.ApplicationInstanceCertificate, - null, - null, - null, - null, - false)); - byteString.addChild( - new ClientDataType( - QualifiedName.parse("0:ContinuationPoint"), - NodeIds.ContinuationPoint, - null, - null, - null, - null, - false)); - byteString.addChild( - new ClientDataType( - QualifiedName.parse("0:AudioDataType"), - NodeIds.AudioDataType, - null, - null, - null, - null, - false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:XmlElement"), - NodeIds.XmlElement, - null, - null, - null, - null, - false)); + Tree imageBMP = + image.addChild( + new ClientDataType( + QualifiedName.parse("0:ImageBMP"), + NodeIds.ImageBMP, + null, + null, + null, + null, + false)); + Tree imageGIF = + image.addChild( + new ClientDataType( + QualifiedName.parse("0:ImageGIF"), + NodeIds.ImageGIF, + null, + null, + null, + null, + false)); + Tree imageJPG = + image.addChild( + new ClientDataType( + QualifiedName.parse("0:ImageJPG"), + NodeIds.ImageJPG, + null, + null, + null, + null, + false)); + Tree imagePNG = + image.addChild( + new ClientDataType( + QualifiedName.parse("0:ImagePNG"), + NodeIds.ImagePNG, + null, + null, + null, + null, + false)); + Tree applicationInstanceCertificate = + byteString.addChild( + new ClientDataType( + QualifiedName.parse("0:ApplicationInstanceCertificate"), + NodeIds.ApplicationInstanceCertificate, + null, + null, + null, + null, + false)); + Tree continuationPoint = + byteString.addChild( + new ClientDataType( + QualifiedName.parse("0:ContinuationPoint"), + NodeIds.ContinuationPoint, + null, + null, + null, + null, + false)); + Tree audioDataType = + byteString.addChild( + new ClientDataType( + QualifiedName.parse("0:AudioDataType"), + NodeIds.AudioDataType, + null, + null, + null, + null, + false)); + Tree xmlElement = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:XmlElement"), + NodeIds.XmlElement, + null, + null, + null, + null, + false)); Tree nodeId = root.addChild( new ClientDataType( QualifiedName.parse("0:NodeId"), NodeIds.NodeId, null, null, null, null, false)); - nodeId.addChild( - new ClientDataType( - QualifiedName.parse("0:SessionAuthenticationToken"), - NodeIds.SessionAuthenticationToken, - null, - null, - null, - null, - false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:ExpandedNodeId"), - NodeIds.ExpandedNodeId, - null, - null, - null, - null, - false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:StatusCode"), - NodeIds.StatusCode, - null, - null, - null, - null, - false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:QualifiedName"), - NodeIds.QualifiedName, - null, - null, - null, - null, - false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:LocalizedText"), - NodeIds.LocalizedText, - null, - null, - null, - null, - false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:Structure"), NodeIds.Structure, null, null, null, null, true)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:DataValue"), NodeIds.DataValue, null, null, null, null, false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:DiagnosticInfo"), - NodeIds.DiagnosticInfo, - null, - null, - null, - null, - false)); - Tree numberType = + Tree sessionAuthenticationToken = + nodeId.addChild( + new ClientDataType( + QualifiedName.parse("0:SessionAuthenticationToken"), + NodeIds.SessionAuthenticationToken, + null, + null, + null, + null, + false)); + Tree expandedNodeId = root.addChild( new ClientDataType( - QualifiedName.parse("0:Number"), NodeIds.Number, null, null, null, null, true)); - numberType.addChild( - new ClientDataType( - QualifiedName.parse("0:Float"), NodeIds.Float, null, null, null, null, false)); - Tree doubleType = - numberType.addChild( + QualifiedName.parse("0:ExpandedNodeId"), + NodeIds.ExpandedNodeId, + null, + null, + null, + null, + false)); + Tree statusCode = + root.addChild( new ClientDataType( - QualifiedName.parse("0:Double"), NodeIds.Double, null, null, null, null, false)); - doubleType.addChild( - new ClientDataType( - QualifiedName.parse("0:Duration"), NodeIds.Duration, null, null, null, null, false)); - Tree integerType = - numberType.addChild( + QualifiedName.parse("0:StatusCode"), + NodeIds.StatusCode, + null, + null, + null, + null, + false)); + Tree qualifiedName = + root.addChild( new ClientDataType( - QualifiedName.parse("0:Integer"), NodeIds.Integer, null, null, null, null, true)); - integerType.addChild( - new ClientDataType( - QualifiedName.parse("0:SByte"), NodeIds.SByte, null, null, null, null, false)); - integerType.addChild( - new ClientDataType( - QualifiedName.parse("0:Int16"), NodeIds.Int16, null, null, null, null, false)); - integerType.addChild( - new ClientDataType( - QualifiedName.parse("0:Int32"), NodeIds.Int32, null, null, null, null, false)); - integerType.addChild( - new ClientDataType( - QualifiedName.parse("0:Int64"), NodeIds.Int64, null, null, null, null, false)); - Tree uInteger = - numberType.addChild( + QualifiedName.parse("0:QualifiedName"), + NodeIds.QualifiedName, + null, + null, + null, + null, + false)); + Tree localizedText = + root.addChild( new ClientDataType( - QualifiedName.parse("0:UInteger"), NodeIds.UInteger, null, null, null, null, true)); - Tree byteType = - uInteger.addChild( + QualifiedName.parse("0:LocalizedText"), + NodeIds.LocalizedText, + null, + null, + null, + null, + false)); + Tree structure = + root.addChild( new ClientDataType( - QualifiedName.parse("0:Byte"), NodeIds.Byte, null, null, null, null, false)); - byteType.addChild( - new ClientDataType( - QualifiedName.parse("0:AccessLevelType"), - NodeIds.AccessLevelType, - null, - null, - null, - null, - false)); - byteType.addChild( - new ClientDataType( - QualifiedName.parse("0:EventNotifierType"), - NodeIds.EventNotifierType, - null, - null, - null, - null, - false)); - Tree uInt16 = - uInteger.addChild( + QualifiedName.parse("0:Structure"), + NodeIds.Structure, + null, + null, + null, + null, + true)); + createStructureNodes(structure); + Tree dataValue = + root.addChild( new ClientDataType( - QualifiedName.parse("0:UInt16"), NodeIds.UInt16, null, null, null, null, false)); - uInt16.addChild( - new ClientDataType( - QualifiedName.parse("0:AccessRestrictionType"), - NodeIds.AccessRestrictionType, - null, - null, - null, - null, - false)); - uInt16.addChild( - new ClientDataType( - QualifiedName.parse("0:DataSetFieldFlags"), - NodeIds.DataSetFieldFlags, - null, - null, - null, - null, - false)); - uInt16.addChild( - new ClientDataType( - QualifiedName.parse("0:AlarmMask"), NodeIds.AlarmMask, null, null, null, null, false)); + QualifiedName.parse("0:DataValue"), + NodeIds.DataValue, + null, + null, + null, + null, + false)); + Tree diagnosticInfo = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:DiagnosticInfo"), + NodeIds.DiagnosticInfo, + null, + null, + null, + null, + false)); + Tree number = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Number"), NodeIds.Number, null, null, null, null, true)); + Tree floatType = + number.addChild( + new ClientDataType( + QualifiedName.parse("0:Float"), NodeIds.Float, null, null, null, null, false)); + Tree doubleType = + number.addChild( + new ClientDataType( + QualifiedName.parse("0:Double"), NodeIds.Double, null, null, null, null, false)); + Tree duration = + doubleType.addChild( + new ClientDataType( + QualifiedName.parse("0:Duration"), + NodeIds.Duration, + null, + null, + null, + null, + false)); + Tree integer = + number.addChild( + new ClientDataType( + QualifiedName.parse("0:Integer"), NodeIds.Integer, null, null, null, null, true)); + Tree sByte = + integer.addChild( + new ClientDataType( + QualifiedName.parse("0:SByte"), NodeIds.SByte, null, null, null, null, false)); + Tree int16 = + integer.addChild( + new ClientDataType( + QualifiedName.parse("0:Int16"), NodeIds.Int16, null, null, null, null, false)); + Tree int32 = + integer.addChild( + new ClientDataType( + QualifiedName.parse("0:Int32"), NodeIds.Int32, null, null, null, null, false)); + Tree int64 = + integer.addChild( + new ClientDataType( + QualifiedName.parse("0:Int64"), NodeIds.Int64, null, null, null, null, false)); + Tree uInteger = + number.addChild( + new ClientDataType( + QualifiedName.parse("0:UInteger"), NodeIds.UInteger, null, null, null, null, true)); + Tree byteType = + uInteger.addChild( + new ClientDataType( + QualifiedName.parse("0:Byte"), NodeIds.Byte, null, null, null, null, false)); + Tree accessLevelType = + byteType.addChild( + new ClientDataType( + QualifiedName.parse("0:AccessLevelType"), + NodeIds.AccessLevelType, + null, + null, + null, + null, + false)); + Tree eventNotifierType = + byteType.addChild( + new ClientDataType( + QualifiedName.parse("0:EventNotifierType"), + NodeIds.EventNotifierType, + null, + null, + null, + null, + false)); + Tree uInt16 = + uInteger.addChild( + new ClientDataType( + QualifiedName.parse("0:UInt16"), NodeIds.UInt16, null, null, null, null, false)); + Tree accessRestrictionType = + uInt16.addChild( + new ClientDataType( + QualifiedName.parse("0:AccessRestrictionType"), + NodeIds.AccessRestrictionType, + null, + null, + null, + null, + false)); + Tree dataSetFieldFlags = + uInt16.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetFieldFlags"), + NodeIds.DataSetFieldFlags, + null, + null, + null, + null, + false)); + Tree alarmMask = + uInt16.addChild( + new ClientDataType( + QualifiedName.parse("0:AlarmMask"), + NodeIds.AlarmMask, + null, + null, + null, + null, + false)); Tree uInt32 = uInteger.addChild( new ClientDataType( QualifiedName.parse("0:UInt32"), NodeIds.UInt32, null, null, null, null, false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:PermissionType"), - NodeIds.PermissionType, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:IntegerId"), NodeIds.IntegerId, null, null, null, null, false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:Counter"), NodeIds.Counter, null, null, null, null, false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:AttributeWriteMask"), - NodeIds.AttributeWriteMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:AccessLevelExType"), - NodeIds.AccessLevelExType, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:DataSetFieldContentMask"), - NodeIds.DataSetFieldContentMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:UadpNetworkMessageContentMask"), - NodeIds.UadpNetworkMessageContentMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:UadpDataSetMessageContentMask"), - NodeIds.UadpDataSetMessageContentMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:JsonNetworkMessageContentMask"), - NodeIds.JsonNetworkMessageContentMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:JsonDataSetMessageContentMask"), - NodeIds.JsonDataSetMessageContentMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:Index"), NodeIds.Index, null, null, null, null, false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:LldpSystemCapabilitiesMap"), - NodeIds.LldpSystemCapabilitiesMap, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:VersionTime"), - NodeIds.VersionTime, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:TrustListValidationOptions"), - NodeIds.TrustListValidationOptions, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:PasswordOptionsMask"), - NodeIds.PasswordOptionsMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:UserConfigurationMask"), - NodeIds.UserConfigurationMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:PubSubConfigurationRefMask"), - NodeIds.PubSubConfigurationRefMask, - null, - null, - null, - null, - false)); - uInt32.addChild( - new ClientDataType( - QualifiedName.parse("0:Handle"), NodeIds.Handle, null, null, null, null, false)); + Tree permissionType = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:PermissionType"), + NodeIds.PermissionType, + null, + null, + null, + null, + false)); + Tree integerId = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:IntegerId"), + NodeIds.IntegerId, + null, + null, + null, + null, + false)); + Tree counter = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:Counter"), NodeIds.Counter, null, null, null, null, false)); + Tree attributeWriteMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:AttributeWriteMask"), + NodeIds.AttributeWriteMask, + null, + null, + null, + null, + false)); + Tree accessLevelExType = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:AccessLevelExType"), + NodeIds.AccessLevelExType, + null, + null, + null, + null, + false)); + Tree dataSetFieldContentMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetFieldContentMask"), + NodeIds.DataSetFieldContentMask, + null, + null, + null, + null, + false)); + Tree uadpNetworkMessageContentMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:UadpNetworkMessageContentMask"), + NodeIds.UadpNetworkMessageContentMask, + null, + null, + null, + null, + false)); + Tree uadpDataSetMessageContentMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:UadpDataSetMessageContentMask"), + NodeIds.UadpDataSetMessageContentMask, + null, + null, + null, + null, + false)); + Tree jsonNetworkMessageContentMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:JsonNetworkMessageContentMask"), + NodeIds.JsonNetworkMessageContentMask, + null, + null, + null, + null, + false)); + Tree jsonDataSetMessageContentMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:JsonDataSetMessageContentMask"), + NodeIds.JsonDataSetMessageContentMask, + null, + null, + null, + null, + false)); + Tree index = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:Index"), NodeIds.Index, null, null, null, null, false)); + Tree lldpSystemCapabilitiesMap = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:LldpSystemCapabilitiesMap"), + NodeIds.LldpSystemCapabilitiesMap, + null, + null, + null, + null, + false)); + Tree versionTime = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:VersionTime"), + NodeIds.VersionTime, + null, + null, + null, + null, + false)); + Tree trustListValidationOptions = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:TrustListValidationOptions"), + NodeIds.TrustListValidationOptions, + null, + null, + null, + null, + false)); + Tree passwordOptionsMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:PasswordOptionsMask"), + NodeIds.PasswordOptionsMask, + null, + null, + null, + null, + false)); + Tree userConfigurationMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:UserConfigurationMask"), + NodeIds.UserConfigurationMask, + null, + null, + null, + null, + false)); + Tree pubSubConfigurationRefMask = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubConfigurationRefMask"), + NodeIds.PubSubConfigurationRefMask, + null, + null, + null, + null, + false)); + Tree handle = + uInt32.addChild( + new ClientDataType( + QualifiedName.parse("0:Handle"), NodeIds.Handle, null, null, null, null, false)); Tree uInt64 = uInteger.addChild( new ClientDataType( QualifiedName.parse("0:UInt64"), NodeIds.UInt64, null, null, null, null, false)); - uInt64.addChild( - new ClientDataType( - QualifiedName.parse("0:BitFieldMaskDataType"), - NodeIds.BitFieldMaskDataType, - null, - null, - null, - null, - false)); - numberType.addChild( - new ClientDataType( - QualifiedName.parse("0:Decimal"), NodeIds.Decimal, null, null, null, null, false)); - root.addChild( - new ClientDataType( - QualifiedName.parse("0:Enumeration"), - NodeIds.Enumeration, - null, - null, - null, - null, - true)); + Tree bitFieldMaskDataType = + uInt64.addChild( + new ClientDataType( + QualifiedName.parse("0:BitFieldMaskDataType"), + NodeIds.BitFieldMaskDataType, + null, + null, + null, + null, + false)); + Tree decimal = + number.addChild( + new ClientDataType( + QualifiedName.parse("0:Decimal"), NodeIds.Decimal, null, null, null, null, false)); + Tree enumeration = + root.addChild( + new ClientDataType( + QualifiedName.parse("0:Enumeration"), + NodeIds.Enumeration, + null, + null, + null, + new EnumDefinition(new EnumField[0]), + true)); + createEnumerationNodes(enumeration); return root; } + + @SuppressWarnings("unused") + private static void createStructureNodes(Tree structure) { + Tree rolePermissionType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:RolePermissionType"), + NodeIds.RolePermissionType, + NodeIds.RolePermissionType_Encoding_DefaultBinary, + NodeIds.RolePermissionType_Encoding_DefaultXml, + NodeIds.RolePermissionType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.RolePermissionType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "RoleId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Permissions", + LocalizedText.NULL_VALUE, + NodeIds.PermissionType, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree dataTypeDefinition = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataTypeDefinition"), + NodeIds.DataTypeDefinition, + NodeIds.DataTypeDefinition_Encoding_DefaultBinary, + NodeIds.DataTypeDefinition_Encoding_DefaultXml, + NodeIds.DataTypeDefinition_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataTypeDefinition_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree structureDefinition = + dataTypeDefinition.addChild( + new ClientDataType( + QualifiedName.parse("0:StructureDefinition"), + NodeIds.StructureDefinition, + NodeIds.StructureDefinition_Encoding_DefaultBinary, + NodeIds.StructureDefinition_Encoding_DefaultXml, + NodeIds.StructureDefinition_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.StructureDefinition_Encoding_DefaultBinary, + NodeIds.DataTypeDefinition, + StructureType.Structure, + new StructureField[] { + new StructureField( + "DefaultEncodingId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BaseDataType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "StructureType", + LocalizedText.NULL_VALUE, + NodeIds.StructureType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Fields", + LocalizedText.NULL_VALUE, + NodeIds.StructureField, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree enumDefinition = + dataTypeDefinition.addChild( + new ClientDataType( + QualifiedName.parse("0:EnumDefinition"), + NodeIds.EnumDefinition, + NodeIds.EnumDefinition_Encoding_DefaultBinary, + NodeIds.EnumDefinition_Encoding_DefaultXml, + NodeIds.EnumDefinition_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EnumDefinition_Encoding_DefaultBinary, + NodeIds.DataTypeDefinition, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Fields", + LocalizedText.NULL_VALUE, + NodeIds.EnumField, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree structureField = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:StructureField"), + NodeIds.StructureField, + NodeIds.StructureField_Encoding_DefaultBinary, + NodeIds.StructureField_Encoding_DefaultXml, + NodeIds.StructureField_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.StructureField_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ValueRank", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ArrayDimensions", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxStringLength", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsOptional", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree node = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:Node"), + NodeIds.Node, + NodeIds.Node_Encoding_DefaultBinary, + NodeIds.Node_Encoding_DefaultXml, + NodeIds.Node_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.Node_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree instanceNode = + node.addChild( + new ClientDataType( + QualifiedName.parse("0:InstanceNode"), + NodeIds.InstanceNode, + NodeIds.InstanceNode_Encoding_DefaultBinary, + NodeIds.InstanceNode_Encoding_DefaultXml, + NodeIds.InstanceNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.InstanceNode_Encoding_DefaultBinary, + NodeIds.Node, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree objectNode = + instanceNode.addChild( + new ClientDataType( + QualifiedName.parse("0:ObjectNode"), + NodeIds.ObjectNode, + NodeIds.ObjectNode_Encoding_DefaultBinary, + NodeIds.ObjectNode_Encoding_DefaultXml, + NodeIds.ObjectNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ObjectNode_Encoding_DefaultBinary, + NodeIds.InstanceNode, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EventNotifier", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree variableNode = + instanceNode.addChild( + new ClientDataType( + QualifiedName.parse("0:VariableNode"), + NodeIds.VariableNode, + NodeIds.VariableNode_Encoding_DefaultBinary, + NodeIds.VariableNode_Encoding_DefaultXml, + NodeIds.VariableNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.VariableNode_Encoding_DefaultBinary, + NodeIds.InstanceNode, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ValueRank", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ArrayDimensions", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessLevel", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserAccessLevel", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MinimumSamplingInterval", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Historizing", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessLevelEx", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree methodNode = + instanceNode.addChild( + new ClientDataType( + QualifiedName.parse("0:MethodNode"), + NodeIds.MethodNode, + NodeIds.MethodNode_Encoding_DefaultBinary, + NodeIds.MethodNode_Encoding_DefaultXml, + NodeIds.MethodNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.MethodNode_Encoding_DefaultBinary, + NodeIds.InstanceNode, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Executable", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserExecutable", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree viewNode = + instanceNode.addChild( + new ClientDataType( + QualifiedName.parse("0:ViewNode"), + NodeIds.ViewNode, + NodeIds.ViewNode_Encoding_DefaultBinary, + NodeIds.ViewNode_Encoding_DefaultXml, + NodeIds.ViewNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ViewNode_Encoding_DefaultBinary, + NodeIds.InstanceNode, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ContainsNoLoops", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EventNotifier", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree typeNode = + node.addChild( + new ClientDataType( + QualifiedName.parse("0:TypeNode"), + NodeIds.TypeNode, + NodeIds.TypeNode_Encoding_DefaultBinary, + NodeIds.TypeNode_Encoding_DefaultXml, + NodeIds.TypeNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.TypeNode_Encoding_DefaultBinary, + NodeIds.Node, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree objectTypeNode = + typeNode.addChild( + new ClientDataType( + QualifiedName.parse("0:ObjectTypeNode"), + NodeIds.ObjectTypeNode, + NodeIds.ObjectTypeNode_Encoding_DefaultBinary, + NodeIds.ObjectTypeNode_Encoding_DefaultXml, + NodeIds.ObjectTypeNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ObjectTypeNode_Encoding_DefaultBinary, + NodeIds.TypeNode, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsAbstract", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree variableTypeNode = + typeNode.addChild( + new ClientDataType( + QualifiedName.parse("0:VariableTypeNode"), + NodeIds.VariableTypeNode, + NodeIds.VariableTypeNode_Encoding_DefaultBinary, + NodeIds.VariableTypeNode_Encoding_DefaultXml, + NodeIds.VariableTypeNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.VariableTypeNode_Encoding_DefaultBinary, + NodeIds.TypeNode, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ValueRank", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ArrayDimensions", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsAbstract", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree referenceTypeNode = + typeNode.addChild( + new ClientDataType( + QualifiedName.parse("0:ReferenceTypeNode"), + NodeIds.ReferenceTypeNode, + NodeIds.ReferenceTypeNode_Encoding_DefaultBinary, + NodeIds.ReferenceTypeNode_Encoding_DefaultXml, + NodeIds.ReferenceTypeNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReferenceTypeNode_Encoding_DefaultBinary, + NodeIds.TypeNode, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsAbstract", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Symmetric", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "InverseName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree dataTypeNode = + typeNode.addChild( + new ClientDataType( + QualifiedName.parse("0:DataTypeNode"), + NodeIds.DataTypeNode, + NodeIds.DataTypeNode_Encoding_DefaultBinary, + NodeIds.DataTypeNode_Encoding_DefaultXml, + NodeIds.DataTypeNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataTypeNode_Encoding_DefaultBinary, + NodeIds.TypeNode, + StructureType.Structure, + new StructureField[] { + new StructureField( + "References", + LocalizedText.NULL_VALUE, + NodeIds.ReferenceNode, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AccessRestrictions", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserRolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserWriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteMask", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsAbstract", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataTypeDefinition", + LocalizedText.NULL_VALUE, + NodeIds.Structure, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree referenceNode = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ReferenceNode"), + NodeIds.ReferenceNode, + NodeIds.ReferenceNode_Encoding_DefaultBinary, + NodeIds.ReferenceNode_Encoding_DefaultXml, + NodeIds.ReferenceNode_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReferenceNode_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ReferenceTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsInverse", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetId", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree argument = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:Argument"), + NodeIds.Argument, + NodeIds.Argument_Encoding_DefaultBinary, + NodeIds.Argument_Encoding_DefaultXml, + NodeIds.Argument_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.Argument_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ValueRank", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ArrayDimensions", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree statusResult = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:StatusResult"), + NodeIds.StatusResult, + NodeIds.StatusResult_Encoding_DefaultBinary, + NodeIds.StatusResult_Encoding_DefaultXml, + NodeIds.StatusResult_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.StatusResult_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "StatusCode", + LocalizedText.NULL_VALUE, + NodeIds.StatusCode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DiagnosticInfo", + LocalizedText.NULL_VALUE, + NodeIds.DiagnosticInfo, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree userTokenPolicy = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:UserTokenPolicy"), + NodeIds.UserTokenPolicy, + NodeIds.UserTokenPolicy_Encoding_DefaultBinary, + NodeIds.UserTokenPolicy_Encoding_DefaultXml, + NodeIds.UserTokenPolicy_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UserTokenPolicy_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PolicyId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TokenType", + LocalizedText.NULL_VALUE, + NodeIds.UserTokenType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IssuedTokenType", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IssuerEndpointUrl", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityPolicyUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree applicationDescription = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ApplicationDescription"), + NodeIds.ApplicationDescription, + NodeIds.ApplicationDescription_Encoding_DefaultBinary, + NodeIds.ApplicationDescription_Encoding_DefaultXml, + NodeIds.ApplicationDescription_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ApplicationDescription_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ApplicationUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ProductUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ApplicationName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ApplicationType", + LocalizedText.NULL_VALUE, + NodeIds.ApplicationType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "GatewayServerUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DiscoveryProfileUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DiscoveryUrls", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree endpointDescription = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:EndpointDescription"), + NodeIds.EndpointDescription, + NodeIds.EndpointDescription_Encoding_DefaultBinary, + NodeIds.EndpointDescription_Encoding_DefaultXml, + NodeIds.EndpointDescription_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EndpointDescription_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "EndpointUrl", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Server", + LocalizedText.NULL_VALUE, + NodeIds.ApplicationDescription, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerCertificate", + LocalizedText.NULL_VALUE, + NodeIds.ApplicationInstanceCertificate, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityMode", + LocalizedText.NULL_VALUE, + NodeIds.MessageSecurityMode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityPolicyUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserIdentityTokens", + LocalizedText.NULL_VALUE, + NodeIds.UserTokenPolicy, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportProfileUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityLevel", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree userIdentityToken = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:UserIdentityToken"), + NodeIds.UserIdentityToken, + NodeIds.UserIdentityToken_Encoding_DefaultBinary, + NodeIds.UserIdentityToken_Encoding_DefaultXml, + NodeIds.UserIdentityToken_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UserIdentityToken_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PolicyId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + true)); + Tree anonymousIdentityToken = + userIdentityToken.addChild( + new ClientDataType( + QualifiedName.parse("0:AnonymousIdentityToken"), + NodeIds.AnonymousIdentityToken, + NodeIds.AnonymousIdentityToken_Encoding_DefaultBinary, + NodeIds.AnonymousIdentityToken_Encoding_DefaultXml, + NodeIds.AnonymousIdentityToken_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AnonymousIdentityToken_Encoding_DefaultBinary, + NodeIds.UserIdentityToken, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PolicyId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree userNameIdentityToken = + userIdentityToken.addChild( + new ClientDataType( + QualifiedName.parse("0:UserNameIdentityToken"), + NodeIds.UserNameIdentityToken, + NodeIds.UserNameIdentityToken_Encoding_DefaultBinary, + NodeIds.UserNameIdentityToken_Encoding_DefaultXml, + NodeIds.UserNameIdentityToken_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UserNameIdentityToken_Encoding_DefaultBinary, + NodeIds.UserIdentityToken, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PolicyId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Password", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EncryptionAlgorithm", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree x509IdentityToken = + userIdentityToken.addChild( + new ClientDataType( + QualifiedName.parse("0:X509IdentityToken"), + NodeIds.X509IdentityToken, + NodeIds.X509IdentityToken_Encoding_DefaultBinary, + NodeIds.X509IdentityToken_Encoding_DefaultXml, + NodeIds.X509IdentityToken_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.X509IdentityToken_Encoding_DefaultBinary, + NodeIds.UserIdentityToken, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PolicyId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CertificateData", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree issuedIdentityToken = + userIdentityToken.addChild( + new ClientDataType( + QualifiedName.parse("0:IssuedIdentityToken"), + NodeIds.IssuedIdentityToken, + NodeIds.IssuedIdentityToken_Encoding_DefaultBinary, + NodeIds.IssuedIdentityToken_Encoding_DefaultXml, + NodeIds.IssuedIdentityToken_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.IssuedIdentityToken_Encoding_DefaultBinary, + NodeIds.UserIdentityToken, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PolicyId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TokenData", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EncryptionAlgorithm", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree endpointConfiguration = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:EndpointConfiguration"), + NodeIds.EndpointConfiguration, + NodeIds.EndpointConfiguration_Encoding_DefaultBinary, + NodeIds.EndpointConfiguration_Encoding_DefaultXml, + NodeIds.EndpointConfiguration_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EndpointConfiguration_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "OperationTimeout", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UseBinaryEncoding", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxStringLength", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxByteStringLength", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxArrayLength", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxMessageSize", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxBufferSize", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ChannelLifetime", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityTokenLifetime", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree buildInfo = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:BuildInfo"), + NodeIds.BuildInfo, + NodeIds.BuildInfo_Encoding_DefaultBinary, + NodeIds.BuildInfo_Encoding_DefaultXml, + NodeIds.BuildInfo_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.BuildInfo_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ProductUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ManufacturerName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ProductName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SoftwareVersion", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BuildNumber", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BuildDate", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree signedSoftwareCertificate = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:SignedSoftwareCertificate"), + NodeIds.SignedSoftwareCertificate, + NodeIds.SignedSoftwareCertificate_Encoding_DefaultBinary, + NodeIds.SignedSoftwareCertificate_Encoding_DefaultXml, + NodeIds.SignedSoftwareCertificate_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SignedSoftwareCertificate_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "CertificateData", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Signature", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree addNodesItem = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:AddNodesItem"), + NodeIds.AddNodesItem, + NodeIds.AddNodesItem_Encoding_DefaultBinary, + NodeIds.AddNodesItem_Encoding_DefaultXml, + NodeIds.AddNodesItem_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AddNodesItem_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ParentNodeId", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReferenceTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RequestedNewNodeId", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NodeAttributes", + LocalizedText.NULL_VALUE, + NodeIds.Structure, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TypeDefinition", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree addReferencesItem = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:AddReferencesItem"), + NodeIds.AddReferencesItem, + NodeIds.AddReferencesItem_Encoding_DefaultBinary, + NodeIds.AddReferencesItem_Encoding_DefaultXml, + NodeIds.AddReferencesItem_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AddReferencesItem_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SourceNodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReferenceTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsForward", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetServerUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetNodeId", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetNodeClass", + LocalizedText.NULL_VALUE, + NodeIds.NodeClass, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree deleteNodesItem = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DeleteNodesItem"), + NodeIds.DeleteNodesItem, + NodeIds.DeleteNodesItem_Encoding_DefaultBinary, + NodeIds.DeleteNodesItem_Encoding_DefaultXml, + NodeIds.DeleteNodesItem_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DeleteNodesItem_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DeleteTargetReferences", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree deleteReferencesItem = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DeleteReferencesItem"), + NodeIds.DeleteReferencesItem, + NodeIds.DeleteReferencesItem_Encoding_DefaultBinary, + NodeIds.DeleteReferencesItem_Encoding_DefaultXml, + NodeIds.DeleteReferencesItem_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DeleteReferencesItem_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SourceNodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReferenceTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsForward", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetNodeId", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DeleteBidirectional", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree registeredServer = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:RegisteredServer"), + NodeIds.RegisteredServer, + NodeIds.RegisteredServer_Encoding_DefaultBinary, + NodeIds.RegisteredServer_Encoding_DefaultXml, + NodeIds.RegisteredServer_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.RegisteredServer_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ServerUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ProductUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerNames", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerType", + LocalizedText.NULL_VALUE, + NodeIds.ApplicationType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "GatewayServerUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DiscoveryUrls", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SemaphoreFilePath", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsOnline", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree relativePathElement = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:RelativePathElement"), + NodeIds.RelativePathElement, + NodeIds.RelativePathElement_Encoding_DefaultBinary, + NodeIds.RelativePathElement_Encoding_DefaultXml, + NodeIds.RelativePathElement_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.RelativePathElement_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ReferenceTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsInverse", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IncludeSubtypes", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree relativePath = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:RelativePath"), + NodeIds.RelativePath, + NodeIds.RelativePath_Encoding_DefaultBinary, + NodeIds.RelativePath_Encoding_DefaultXml, + NodeIds.RelativePath_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.RelativePath_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Elements", + LocalizedText.NULL_VALUE, + NodeIds.RelativePathElement, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree contentFilterElement = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ContentFilterElement"), + NodeIds.ContentFilterElement, + NodeIds.ContentFilterElement_Encoding_DefaultBinary, + NodeIds.ContentFilterElement_Encoding_DefaultXml, + NodeIds.ContentFilterElement_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ContentFilterElement_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "FilterOperator", + LocalizedText.NULL_VALUE, + NodeIds.FilterOperator, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "FilterOperands", + LocalizedText.NULL_VALUE, + NodeIds.Structure, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree contentFilter = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ContentFilter"), + NodeIds.ContentFilter, + NodeIds.ContentFilter_Encoding_DefaultBinary, + NodeIds.ContentFilter_Encoding_DefaultXml, + NodeIds.ContentFilter_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ContentFilter_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Elements", + LocalizedText.NULL_VALUE, + NodeIds.ContentFilterElement, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree filterOperand = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:FilterOperand"), + NodeIds.FilterOperand, + NodeIds.FilterOperand_Encoding_DefaultBinary, + NodeIds.FilterOperand_Encoding_DefaultXml, + NodeIds.FilterOperand_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.FilterOperand_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree elementOperand = + filterOperand.addChild( + new ClientDataType( + QualifiedName.parse("0:ElementOperand"), + NodeIds.ElementOperand, + NodeIds.ElementOperand_Encoding_DefaultBinary, + NodeIds.ElementOperand_Encoding_DefaultXml, + NodeIds.ElementOperand_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ElementOperand_Encoding_DefaultBinary, + NodeIds.FilterOperand, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Index", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree literalOperand = + filterOperand.addChild( + new ClientDataType( + QualifiedName.parse("0:LiteralOperand"), + NodeIds.LiteralOperand, + NodeIds.LiteralOperand_Encoding_DefaultBinary, + NodeIds.LiteralOperand_Encoding_DefaultXml, + NodeIds.LiteralOperand_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.LiteralOperand_Encoding_DefaultBinary, + NodeIds.FilterOperand, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree attributeOperand = + filterOperand.addChild( + new ClientDataType( + QualifiedName.parse("0:AttributeOperand"), + NodeIds.AttributeOperand, + NodeIds.AttributeOperand_Encoding_DefaultBinary, + NodeIds.AttributeOperand_Encoding_DefaultXml, + NodeIds.AttributeOperand_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AttributeOperand_Encoding_DefaultBinary, + NodeIds.FilterOperand, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Alias", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowsePath", + LocalizedText.NULL_VALUE, + NodeIds.RelativePath, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AttributeId", + LocalizedText.NULL_VALUE, + NodeIds.IntegerId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IndexRange", + LocalizedText.NULL_VALUE, + NodeIds.NumericRange, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree simpleAttributeOperand = + filterOperand.addChild( + new ClientDataType( + QualifiedName.parse("0:SimpleAttributeOperand"), + NodeIds.SimpleAttributeOperand, + NodeIds.SimpleAttributeOperand_Encoding_DefaultBinary, + NodeIds.SimpleAttributeOperand_Encoding_DefaultXml, + NodeIds.SimpleAttributeOperand_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SimpleAttributeOperand_Encoding_DefaultBinary, + NodeIds.FilterOperand, + StructureType.Structure, + new StructureField[] { + new StructureField( + "TypeDefinitionId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowsePath", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AttributeId", + LocalizedText.NULL_VALUE, + NodeIds.IntegerId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IndexRange", + LocalizedText.NULL_VALUE, + NodeIds.NumericRange, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree historyEvent = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:HistoryEvent"), + NodeIds.HistoryEvent, + NodeIds.HistoryEvent_Encoding_DefaultBinary, + NodeIds.HistoryEvent_Encoding_DefaultXml, + NodeIds.HistoryEvent_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.HistoryEvent_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Events", + LocalizedText.NULL_VALUE, + NodeIds.HistoryEventFieldList, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree historyModifiedEvent = + historyEvent.addChild( + new ClientDataType( + QualifiedName.parse("0:HistoryModifiedEvent"), + NodeIds.HistoryModifiedEvent, + NodeIds.HistoryModifiedEvent_Encoding_DefaultBinary, + NodeIds.HistoryModifiedEvent_Encoding_DefaultXml, + NodeIds.HistoryModifiedEvent_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.HistoryModifiedEvent_Encoding_DefaultBinary, + NodeIds.HistoryEvent, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Events", + LocalizedText.NULL_VALUE, + NodeIds.HistoryEventFieldList, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ModificationInfos", + LocalizedText.NULL_VALUE, + NodeIds.ModificationInfo, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree monitoringFilter = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:MonitoringFilter"), + NodeIds.MonitoringFilter, + NodeIds.MonitoringFilter_Encoding_DefaultBinary, + NodeIds.MonitoringFilter_Encoding_DefaultXml, + NodeIds.MonitoringFilter_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.MonitoringFilter_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + false)); + Tree eventFilter = + monitoringFilter.addChild( + new ClientDataType( + QualifiedName.parse("0:EventFilter"), + NodeIds.EventFilter, + NodeIds.EventFilter_Encoding_DefaultBinary, + NodeIds.EventFilter_Encoding_DefaultXml, + NodeIds.EventFilter_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EventFilter_Encoding_DefaultBinary, + NodeIds.MonitoringFilter, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SelectClauses", + LocalizedText.NULL_VALUE, + NodeIds.SimpleAttributeOperand, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WhereClause", + LocalizedText.NULL_VALUE, + NodeIds.ContentFilter, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree redundantServerDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:RedundantServerDataType"), + NodeIds.RedundantServerDataType, + NodeIds.RedundantServerDataType_Encoding_DefaultBinary, + NodeIds.RedundantServerDataType_Encoding_DefaultXml, + NodeIds.RedundantServerDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.RedundantServerDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ServerId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServiceLevel", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerState", + LocalizedText.NULL_VALUE, + NodeIds.ServerState, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree samplingIntervalDiagnosticsDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:SamplingIntervalDiagnosticsDataType"), + NodeIds.SamplingIntervalDiagnosticsDataType, + NodeIds.SamplingIntervalDiagnosticsDataType_Encoding_DefaultBinary, + NodeIds.SamplingIntervalDiagnosticsDataType_Encoding_DefaultXml, + NodeIds.SamplingIntervalDiagnosticsDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SamplingIntervalDiagnosticsDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SamplingInterval", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MonitoredItemCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxMonitoredItemCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisabledMonitoredItemCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree serverDiagnosticsSummaryDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ServerDiagnosticsSummaryDataType"), + NodeIds.ServerDiagnosticsSummaryDataType, + NodeIds.ServerDiagnosticsSummaryDataType_Encoding_DefaultBinary, + NodeIds.ServerDiagnosticsSummaryDataType_Encoding_DefaultXml, + NodeIds.ServerDiagnosticsSummaryDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ServerDiagnosticsSummaryDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ServerViewCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CurrentSessionCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CumulatedSessionCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityRejectedSessionCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RejectedSessionCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SessionTimeoutCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SessionAbortCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CurrentSubscriptionCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CumulatedSubscriptionCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishingIntervalCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityRejectedRequestsCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RejectedRequestsCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree serverStatusDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ServerStatusDataType"), + NodeIds.ServerStatusDataType, + NodeIds.ServerStatusDataType_Encoding_DefaultBinary, + NodeIds.ServerStatusDataType_Encoding_DefaultXml, + NodeIds.ServerStatusDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ServerStatusDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "StartTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CurrentTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "State", + LocalizedText.NULL_VALUE, + NodeIds.ServerState, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BuildInfo", + LocalizedText.NULL_VALUE, + NodeIds.BuildInfo, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecondsTillShutdown", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ShutdownReason", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree sessionDiagnosticsDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:SessionDiagnosticsDataType"), + NodeIds.SessionDiagnosticsDataType, + NodeIds.SessionDiagnosticsDataType_Encoding_DefaultBinary, + NodeIds.SessionDiagnosticsDataType_Encoding_DefaultXml, + NodeIds.SessionDiagnosticsDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SessionDiagnosticsDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SessionId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SessionName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ClientDescription", + LocalizedText.NULL_VALUE, + NodeIds.ApplicationDescription, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EndpointUrl", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LocaleIds", + LocalizedText.NULL_VALUE, + NodeIds.LocaleId, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ActualSessionTimeout", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxResponseMessageSize", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ClientConnectionTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ClientLastContactTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CurrentSubscriptionsCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CurrentMonitoredItemsCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CurrentPublishRequestsInQueue", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TotalRequestCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UnauthorizedRequestCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReadCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "HistoryReadCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "HistoryUpdateCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CallCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CreateMonitoredItemsCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ModifyMonitoredItemsCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SetMonitoringModeCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SetTriggeringCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DeleteMonitoredItemsCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CreateSubscriptionCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ModifySubscriptionCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SetPublishingModeCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RepublishCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransferSubscriptionsCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DeleteSubscriptionsCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AddNodesCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AddReferencesCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DeleteNodesCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DeleteReferencesCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BrowseNextCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TranslateBrowsePathsToNodeIdsCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "QueryFirstCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "QueryNextCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RegisterNodesCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UnregisterNodesCount", + LocalizedText.NULL_VALUE, + NodeIds.ServiceCounterDataType, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree sessionSecurityDiagnosticsDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:SessionSecurityDiagnosticsDataType"), + NodeIds.SessionSecurityDiagnosticsDataType, + NodeIds.SessionSecurityDiagnosticsDataType_Encoding_DefaultBinary, + NodeIds.SessionSecurityDiagnosticsDataType_Encoding_DefaultXml, + NodeIds.SessionSecurityDiagnosticsDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SessionSecurityDiagnosticsDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SessionId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ClientUserIdOfSession", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ClientUserIdHistory", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AuthenticationMechanism", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Encoding", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportProtocol", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityMode", + LocalizedText.NULL_VALUE, + NodeIds.MessageSecurityMode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityPolicyUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ClientCertificate", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree serviceCounterDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ServiceCounterDataType"), + NodeIds.ServiceCounterDataType, + NodeIds.ServiceCounterDataType_Encoding_DefaultBinary, + NodeIds.ServiceCounterDataType_Encoding_DefaultXml, + NodeIds.ServiceCounterDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ServiceCounterDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "TotalCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ErrorCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree subscriptionDiagnosticsDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:SubscriptionDiagnosticsDataType"), + NodeIds.SubscriptionDiagnosticsDataType, + NodeIds.SubscriptionDiagnosticsDataType_Encoding_DefaultBinary, + NodeIds.SubscriptionDiagnosticsDataType_Encoding_DefaultXml, + NodeIds.SubscriptionDiagnosticsDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SubscriptionDiagnosticsDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SessionId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SubscriptionId", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Priority", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishingInterval", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxKeepAliveCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxLifetimeCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxNotificationsPerPublish", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishingEnabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ModifyCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EnableCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisableCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RepublishRequestCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RepublishMessageRequestCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RepublishMessageCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransferRequestCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransferredToAltClientCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransferredToSameClientCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishRequestCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataChangeNotificationsCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EventNotificationsCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NotificationsCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LatePublishRequestCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CurrentKeepAliveCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CurrentLifetimeCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UnacknowledgedMessageCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DiscardedMessageCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MonitoredItemCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisabledMonitoredItemCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MonitoringQueueOverflowCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NextSequenceNumber", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EventQueueOverflowCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree modelChangeStructureDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ModelChangeStructureDataType"), + NodeIds.ModelChangeStructureDataType, + NodeIds.ModelChangeStructureDataType_Encoding_DefaultBinary, + NodeIds.ModelChangeStructureDataType_Encoding_DefaultXml, + NodeIds.ModelChangeStructureDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ModelChangeStructureDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Affected", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AffectedType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Verb", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree range = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:Range"), + NodeIds.Range, + NodeIds.Range_Encoding_DefaultBinary, + NodeIds.Range_Encoding_DefaultXml, + NodeIds.Range_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.Range_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Low", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "High", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree eUInformation = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:EUInformation"), + NodeIds.EUInformation, + NodeIds.EUInformation_Encoding_DefaultBinary, + NodeIds.EUInformation_Encoding_DefaultXml, + NodeIds.EUInformation_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EUInformation_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NamespaceUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UnitId", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree annotation = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:Annotation"), + NodeIds.Annotation, + NodeIds.Annotation_Encoding_DefaultBinary, + NodeIds.Annotation_Encoding_DefaultXml, + NodeIds.Annotation_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.Annotation_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Message", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AnnotationTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree programDiagnosticDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ProgramDiagnosticDataType"), + NodeIds.ProgramDiagnosticDataType, + NodeIds.ProgramDiagnosticDataType_Encoding_DefaultBinary, + NodeIds.ProgramDiagnosticDataType_Encoding_DefaultXml, + NodeIds.ProgramDiagnosticDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ProgramDiagnosticDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "CreateSessionId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CreateClientName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "InvocationCreationTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastTransitionTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodCall", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodSessionId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodInputArguments", + LocalizedText.NULL_VALUE, + NodeIds.Argument, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodOutputArguments", + LocalizedText.NULL_VALUE, + NodeIds.Argument, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodCallTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodReturnStatus", + LocalizedText.NULL_VALUE, + NodeIds.StatusResult, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree semanticChangeStructureDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:SemanticChangeStructureDataType"), + NodeIds.SemanticChangeStructureDataType, + NodeIds.SemanticChangeStructureDataType_Encoding_DefaultBinary, + NodeIds.SemanticChangeStructureDataType_Encoding_DefaultXml, + NodeIds.SemanticChangeStructureDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SemanticChangeStructureDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Affected", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AffectedType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree historyEventFieldList = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:HistoryEventFieldList"), + NodeIds.HistoryEventFieldList, + NodeIds.HistoryEventFieldList_Encoding_DefaultBinary, + NodeIds.HistoryEventFieldList_Encoding_DefaultXml, + NodeIds.HistoryEventFieldList_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.HistoryEventFieldList_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "EventFields", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree aggregateConfiguration = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:AggregateConfiguration"), + NodeIds.AggregateConfiguration, + NodeIds.AggregateConfiguration_Encoding_DefaultBinary, + NodeIds.AggregateConfiguration_Encoding_DefaultXml, + NodeIds.AggregateConfiguration_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AggregateConfiguration_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "UseServerCapabilitiesDefaults", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TreatUncertainAsBad", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PercentDataBad", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PercentDataGood", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UseSlopedExtrapolation", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree enumValueType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:EnumValueType"), + NodeIds.EnumValueType, + NodeIds.EnumValueType_Encoding_DefaultBinary, + NodeIds.EnumValueType_Encoding_DefaultXml, + NodeIds.EnumValueType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EnumValueType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.Int64, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree enumField = + enumValueType.addChild( + new ClientDataType( + QualifiedName.parse("0:EnumField"), + NodeIds.EnumField, + NodeIds.EnumField_Encoding_DefaultBinary, + NodeIds.EnumField_Encoding_DefaultXml, + NodeIds.EnumField_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EnumField_Encoding_DefaultBinary, + NodeIds.EnumValueType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DisplayName", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.Int64, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree timeZoneDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:TimeZoneDataType"), + NodeIds.TimeZoneDataType, + NodeIds.TimeZoneDataType_Encoding_DefaultBinary, + NodeIds.TimeZoneDataType_Encoding_DefaultXml, + NodeIds.TimeZoneDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.TimeZoneDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Offset", + LocalizedText.NULL_VALUE, + NodeIds.Int16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DaylightSavingInOffset", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree modificationInfo = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ModificationInfo"), + NodeIds.ModificationInfo, + NodeIds.ModificationInfo_Encoding_DefaultBinary, + NodeIds.ModificationInfo_Encoding_DefaultXml, + NodeIds.ModificationInfo_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ModificationInfo_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ModificationTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UpdateType", + LocalizedText.NULL_VALUE, + NodeIds.HistoryUpdateType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree endpointUrlListDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:EndpointUrlListDataType"), + NodeIds.EndpointUrlListDataType, + NodeIds.EndpointUrlListDataType_Encoding_DefaultBinary, + NodeIds.EndpointUrlListDataType_Encoding_DefaultXml, + NodeIds.EndpointUrlListDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EndpointUrlListDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "EndpointUrlList", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree networkGroupDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:NetworkGroupDataType"), + NodeIds.NetworkGroupDataType, + NodeIds.NetworkGroupDataType_Encoding_DefaultBinary, + NodeIds.NetworkGroupDataType_Encoding_DefaultXml, + NodeIds.NetworkGroupDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.NetworkGroupDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ServerUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NetworkPaths", + LocalizedText.NULL_VALUE, + NodeIds.EndpointUrlListDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree axisInformation = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:AxisInformation"), + NodeIds.AxisInformation, + NodeIds.AxisInformation_Encoding_DefaultBinary, + NodeIds.AxisInformation_Encoding_DefaultXml, + NodeIds.AxisInformation_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AxisInformation_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "EngineeringUnits", + LocalizedText.NULL_VALUE, + NodeIds.EUInformation, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EURange", + LocalizedText.NULL_VALUE, + NodeIds.Range, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Title", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AxisScaleType", + LocalizedText.NULL_VALUE, + NodeIds.AxisScaleEnumeration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AxisSteps", + LocalizedText.NULL_VALUE, + NodeIds.Double, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree xVType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:XVType"), + NodeIds.XVType, + NodeIds.XVType_Encoding_DefaultBinary, + NodeIds.XVType_Encoding_DefaultXml, + NodeIds.XVType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.XVType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "X", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.Float, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree complexNumberType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ComplexNumberType"), + NodeIds.ComplexNumberType, + NodeIds.ComplexNumberType_Encoding_DefaultBinary, + NodeIds.ComplexNumberType_Encoding_DefaultXml, + NodeIds.ComplexNumberType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ComplexNumberType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Real", + LocalizedText.NULL_VALUE, + NodeIds.Float, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Imaginary", + LocalizedText.NULL_VALUE, + NodeIds.Float, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree doubleComplexNumberType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DoubleComplexNumberType"), + NodeIds.DoubleComplexNumberType, + NodeIds.DoubleComplexNumberType_Encoding_DefaultBinary, + NodeIds.DoubleComplexNumberType_Encoding_DefaultXml, + NodeIds.DoubleComplexNumberType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DoubleComplexNumberType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Real", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Imaginary", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree serverOnNetwork = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ServerOnNetwork"), + NodeIds.ServerOnNetwork, + NodeIds.ServerOnNetwork_Encoding_DefaultBinary, + NodeIds.ServerOnNetwork_Encoding_DefaultXml, + NodeIds.ServerOnNetwork_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ServerOnNetwork_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "RecordId", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DiscoveryUrl", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerCapabilities", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree trustListDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:TrustListDataType"), + NodeIds.TrustListDataType, + NodeIds.TrustListDataType_Encoding_DefaultBinary, + NodeIds.TrustListDataType_Encoding_DefaultXml, + NodeIds.TrustListDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.TrustListDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SpecifiedLists", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TrustedCertificates", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TrustedCrls", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IssuerCertificates", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IssuerCrls", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree optionSet = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:OptionSet"), + NodeIds.OptionSet, + NodeIds.OptionSet_Encoding_DefaultBinary, + NodeIds.OptionSet_Encoding_DefaultXml, + NodeIds.OptionSet_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.OptionSet_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ValidBits", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false) + }), + true)); + Tree union = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:Union"), + NodeIds.Union, + NodeIds.Union_Encoding_DefaultBinary, + NodeIds.Union_Encoding_DefaultXml, + NodeIds.Union_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.Union_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree discoveryConfiguration = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DiscoveryConfiguration"), + NodeIds.DiscoveryConfiguration, + NodeIds.DiscoveryConfiguration_Encoding_DefaultBinary, + NodeIds.DiscoveryConfiguration_Encoding_DefaultXml, + NodeIds.DiscoveryConfiguration_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DiscoveryConfiguration_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + false)); + Tree mdnsDiscoveryConfiguration = + discoveryConfiguration.addChild( + new ClientDataType( + QualifiedName.parse("0:MdnsDiscoveryConfiguration"), + NodeIds.MdnsDiscoveryConfiguration, + NodeIds.MdnsDiscoveryConfiguration_Encoding_DefaultBinary, + NodeIds.MdnsDiscoveryConfiguration_Encoding_DefaultXml, + NodeIds.MdnsDiscoveryConfiguration_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.MdnsDiscoveryConfiguration_Encoding_DefaultBinary, + NodeIds.DiscoveryConfiguration, + StructureType.Structure, + new StructureField[] { + new StructureField( + "MdnsServerName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerCapabilities", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree publishedVariableDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PublishedVariableDataType"), + NodeIds.PublishedVariableDataType, + NodeIds.PublishedVariableDataType_Encoding_DefaultBinary, + NodeIds.PublishedVariableDataType_Encoding_DefaultXml, + NodeIds.PublishedVariableDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PublishedVariableDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PublishedVariable", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AttributeId", + LocalizedText.NULL_VALUE, + NodeIds.IntegerId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SamplingIntervalHint", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DeadbandType", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DeadbandValue", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IndexRange", + LocalizedText.NULL_VALUE, + NodeIds.NumericRange, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SubstituteValue", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MetaDataProperties", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree fieldMetaData = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:FieldMetaData"), + NodeIds.FieldMetaData, + NodeIds.FieldMetaData_Encoding_DefaultBinary, + NodeIds.FieldMetaData_Encoding_DefaultXml, + NodeIds.FieldMetaData_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.FieldMetaData_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "FieldFlags", + LocalizedText.NULL_VALUE, + NodeIds.DataSetFieldFlags, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BuiltInType", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ValueRank", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ArrayDimensions", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxStringLength", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetFieldId", + LocalizedText.NULL_VALUE, + NodeIds.Guid, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Properties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree dataTypeDescription = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataTypeDescription"), + NodeIds.DataTypeDescription, + NodeIds.DataTypeDescription_Encoding_DefaultBinary, + NodeIds.DataTypeDescription_Encoding_DefaultXml, + NodeIds.DataTypeDescription_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataTypeDescription_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "DataTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false) + }), + true)); + Tree simpleTypeDescription = + dataTypeDescription.addChild( + new ClientDataType( + QualifiedName.parse("0:SimpleTypeDescription"), + NodeIds.SimpleTypeDescription, + NodeIds.SimpleTypeDescription_Encoding_DefaultBinary, + NodeIds.SimpleTypeDescription_Encoding_DefaultXml, + NodeIds.SimpleTypeDescription_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SimpleTypeDescription_Encoding_DefaultBinary, + NodeIds.DataTypeDescription, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BaseDataType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BuiltInType", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree structureDescription = + dataTypeDescription.addChild( + new ClientDataType( + QualifiedName.parse("0:StructureDescription"), + NodeIds.StructureDescription, + NodeIds.StructureDescription_Encoding_DefaultBinary, + NodeIds.StructureDescription_Encoding_DefaultXml, + NodeIds.StructureDescription_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.StructureDescription_Encoding_DefaultBinary, + NodeIds.DataTypeDescription, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "StructureDefinition", + LocalizedText.NULL_VALUE, + NodeIds.StructureDefinition, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree enumDescription = + dataTypeDescription.addChild( + new ClientDataType( + QualifiedName.parse("0:EnumDescription"), + NodeIds.EnumDescription, + NodeIds.EnumDescription_Encoding_DefaultBinary, + NodeIds.EnumDescription_Encoding_DefaultXml, + NodeIds.EnumDescription_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EnumDescription_Encoding_DefaultBinary, + NodeIds.DataTypeDescription, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataTypeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EnumDefinition", + LocalizedText.NULL_VALUE, + NodeIds.EnumDefinition, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "BuiltInType", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree keyValuePair = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:KeyValuePair"), + NodeIds.KeyValuePair, + NodeIds.KeyValuePair_Encoding_DefaultBinary, + NodeIds.KeyValuePair_Encoding_DefaultXml, + NodeIds.KeyValuePair_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.KeyValuePair_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Key", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree configurationVersionDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ConfigurationVersionDataType"), + NodeIds.ConfigurationVersionDataType, + NodeIds.ConfigurationVersionDataType_Encoding_DefaultBinary, + NodeIds.ConfigurationVersionDataType_Encoding_DefaultXml, + NodeIds.ConfigurationVersionDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ConfigurationVersionDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "MajorVersion", + LocalizedText.NULL_VALUE, + NodeIds.VersionTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MinorVersion", + LocalizedText.NULL_VALUE, + NodeIds.VersionTime, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree fieldTargetDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:FieldTargetDataType"), + NodeIds.FieldTargetDataType, + NodeIds.FieldTargetDataType_Encoding_DefaultBinary, + NodeIds.FieldTargetDataType_Encoding_DefaultXml, + NodeIds.FieldTargetDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.FieldTargetDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "DataSetFieldId", + LocalizedText.NULL_VALUE, + NodeIds.Guid, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReceiverIndexRange", + LocalizedText.NULL_VALUE, + NodeIds.NumericRange, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetNodeId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AttributeId", + LocalizedText.NULL_VALUE, + NodeIds.IntegerId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriteIndexRange", + LocalizedText.NULL_VALUE, + NodeIds.NumericRange, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "OverrideValueHandling", + LocalizedText.NULL_VALUE, + NodeIds.OverrideValueHandling, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "OverrideValue", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree networkAddressDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:NetworkAddressDataType"), + NodeIds.NetworkAddressDataType, + NodeIds.NetworkAddressDataType_Encoding_DefaultBinary, + NodeIds.NetworkAddressDataType_Encoding_DefaultXml, + NodeIds.NetworkAddressDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.NetworkAddressDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NetworkInterface", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + true)); + Tree networkAddressUrlDataType = + networkAddressDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:NetworkAddressUrlDataType"), + NodeIds.NetworkAddressUrlDataType, + NodeIds.NetworkAddressUrlDataType_Encoding_DefaultBinary, + NodeIds.NetworkAddressUrlDataType_Encoding_DefaultXml, + NodeIds.NetworkAddressUrlDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.NetworkAddressUrlDataType_Encoding_DefaultBinary, + NodeIds.NetworkAddressDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NetworkInterface", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Url", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree endpointType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:EndpointType"), + NodeIds.EndpointType, + NodeIds.EndpointType_Encoding_DefaultBinary, + NodeIds.EndpointType_Encoding_DefaultXml, + NodeIds.EndpointType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EndpointType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "EndpointUrl", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityMode", + LocalizedText.NULL_VALUE, + NodeIds.MessageSecurityMode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityPolicyUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportProfileUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree pubSubConfigurationDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubConfigurationDataType"), + NodeIds.PubSubConfigurationDataType, + NodeIds.PubSubConfigurationDataType_Encoding_DefaultBinary, + NodeIds.PubSubConfigurationDataType_Encoding_DefaultXml, + NodeIds.PubSubConfigurationDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PubSubConfigurationDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PublishedDataSets", + LocalizedText.NULL_VALUE, + NodeIds.PublishedDataSetDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Connections", + LocalizedText.NULL_VALUE, + NodeIds.PubSubConnectionDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Enabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree pubSubConfiguration2DataType = + pubSubConfigurationDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubConfiguration2DataType"), + NodeIds.PubSubConfiguration2DataType, + NodeIds.PubSubConfiguration2DataType_Encoding_DefaultBinary, + NodeIds.PubSubConfiguration2DataType_Encoding_DefaultXml, + NodeIds.PubSubConfiguration2DataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PubSubConfiguration2DataType_Encoding_DefaultBinary, + NodeIds.PubSubConfigurationDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Enabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Connections", + LocalizedText.NULL_VALUE, + NodeIds.PubSubConnectionDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishedDataSets", + LocalizedText.NULL_VALUE, + NodeIds.PublishedDataSetDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SubscribedDataSets", + LocalizedText.NULL_VALUE, + NodeIds.StandaloneSubscribedDataSetDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetClasses", + LocalizedText.NULL_VALUE, + NodeIds.DataSetMetaDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DefaultSecurityKeyServices", + LocalizedText.NULL_VALUE, + NodeIds.EndpointDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityGroups", + LocalizedText.NULL_VALUE, + NodeIds.SecurityGroupDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PubSubKeyPushTargets", + LocalizedText.NULL_VALUE, + NodeIds.PubSubKeyPushTargetDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ConfigurationVersion", + LocalizedText.NULL_VALUE, + NodeIds.VersionTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ConfigurationProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree dataTypeSchemaHeader = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataTypeSchemaHeader"), + NodeIds.DataTypeSchemaHeader, + NodeIds.DataTypeSchemaHeader_Encoding_DefaultBinary, + NodeIds.DataTypeSchemaHeader_Encoding_DefaultXml, + NodeIds.DataTypeSchemaHeader_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataTypeSchemaHeader_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Namespaces", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "StructureDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.StructureDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EnumDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.EnumDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SimpleDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.SimpleTypeDescription, + 1, + null, + UInteger.valueOf(0), + false) + }), + true)); + Tree dataSetMetaDataType = + dataTypeSchemaHeader.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetMetaDataType"), + NodeIds.DataSetMetaDataType, + NodeIds.DataSetMetaDataType_Encoding_DefaultBinary, + NodeIds.DataSetMetaDataType_Encoding_DefaultXml, + NodeIds.DataSetMetaDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataSetMetaDataType_Encoding_DefaultBinary, + NodeIds.DataTypeSchemaHeader, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SimpleDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.SimpleTypeDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EnumDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.EnumDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "StructureDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.StructureDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Namespaces", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Fields", + LocalizedText.NULL_VALUE, + NodeIds.FieldMetaData, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetClassId", + LocalizedText.NULL_VALUE, + NodeIds.Guid, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ConfigurationVersion", + LocalizedText.NULL_VALUE, + NodeIds.ConfigurationVersionDataType, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree uABinaryFileDataType = + dataTypeSchemaHeader.addChild( + new ClientDataType( + QualifiedName.parse("0:UABinaryFileDataType"), + NodeIds.UABinaryFileDataType, + NodeIds.UABinaryFileDataType_Encoding_DefaultBinary, + NodeIds.UABinaryFileDataType_Encoding_DefaultXml, + NodeIds.UABinaryFileDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UABinaryFileDataType_Encoding_DefaultBinary, + NodeIds.DataTypeSchemaHeader, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SimpleDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.SimpleTypeDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EnumDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.EnumDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "StructureDataTypes", + LocalizedText.NULL_VALUE, + NodeIds.StructureDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Namespaces", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SchemaLocation", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "FileHeader", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Body", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree publishedDataSetDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PublishedDataSetDataType"), + NodeIds.PublishedDataSetDataType, + NodeIds.PublishedDataSetDataType_Encoding_DefaultBinary, + NodeIds.PublishedDataSetDataType_Encoding_DefaultXml, + NodeIds.PublishedDataSetDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PublishedDataSetDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetFolder", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetMetaData", + LocalizedText.NULL_VALUE, + NodeIds.DataSetMetaDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ExtensionFields", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetSource", + LocalizedText.NULL_VALUE, + NodeIds.PublishedDataSetSourceDataType, + -1, + null, + UInteger.valueOf(0), + true) + }), + false)); + Tree publishedDataSetSourceDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PublishedDataSetSourceDataType"), + NodeIds.PublishedDataSetSourceDataType, + NodeIds.PublishedDataSetSourceDataType_Encoding_DefaultBinary, + NodeIds.PublishedDataSetSourceDataType_Encoding_DefaultXml, + NodeIds.PublishedDataSetSourceDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PublishedDataSetSourceDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree publishedDataItemsDataType = + publishedDataSetSourceDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:PublishedDataItemsDataType"), + NodeIds.PublishedDataItemsDataType, + NodeIds.PublishedDataItemsDataType_Encoding_DefaultBinary, + NodeIds.PublishedDataItemsDataType_Encoding_DefaultXml, + NodeIds.PublishedDataItemsDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PublishedDataItemsDataType_Encoding_DefaultBinary, + NodeIds.PublishedDataSetSourceDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PublishedData", + LocalizedText.NULL_VALUE, + NodeIds.PublishedVariableDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree publishedEventsDataType = + publishedDataSetSourceDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:PublishedEventsDataType"), + NodeIds.PublishedEventsDataType, + NodeIds.PublishedEventsDataType_Encoding_DefaultBinary, + NodeIds.PublishedEventsDataType_Encoding_DefaultXml, + NodeIds.PublishedEventsDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PublishedEventsDataType_Encoding_DefaultBinary, + NodeIds.PublishedDataSetSourceDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "EventNotifier", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SelectedFields", + LocalizedText.NULL_VALUE, + NodeIds.SimpleAttributeOperand, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Filter", + LocalizedText.NULL_VALUE, + NodeIds.ContentFilter, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree publishedActionDataType = + publishedDataSetSourceDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:PublishedActionDataType"), + NodeIds.PublishedActionDataType, + NodeIds.PublishedActionDataType_Encoding_DefaultBinary, + NodeIds.PublishedActionDataType_Encoding_DefaultXml, + NodeIds.PublishedActionDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PublishedActionDataType_Encoding_DefaultBinary, + NodeIds.PublishedDataSetSourceDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "RequestDataSetMetaData", + LocalizedText.NULL_VALUE, + NodeIds.DataSetMetaDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ActionTargets", + LocalizedText.NULL_VALUE, + NodeIds.ActionTargetDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree publishedActionMethodDataType = + publishedActionDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:PublishedActionMethodDataType"), + NodeIds.PublishedActionMethodDataType, + NodeIds.PublishedActionMethodDataType_Encoding_DefaultBinary, + NodeIds.PublishedActionMethodDataType_Encoding_DefaultXml, + NodeIds.PublishedActionMethodDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PublishedActionMethodDataType_Encoding_DefaultBinary, + NodeIds.PublishedActionDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ActionTargets", + LocalizedText.NULL_VALUE, + NodeIds.ActionTargetDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RequestDataSetMetaData", + LocalizedText.NULL_VALUE, + NodeIds.DataSetMetaDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ActionMethods", + LocalizedText.NULL_VALUE, + NodeIds.ActionMethodDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree publishedDataSetCustomSourceDataType = + publishedDataSetSourceDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:PublishedDataSetCustomSourceDataType"), + NodeIds.PublishedDataSetCustomSourceDataType, + NodeIds.PublishedDataSetCustomSourceDataType_Encoding_DefaultBinary, + NodeIds.PublishedDataSetCustomSourceDataType_Encoding_DefaultXml, + NodeIds.PublishedDataSetCustomSourceDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PublishedDataSetCustomSourceDataType_Encoding_DefaultBinary, + NodeIds.PublishedDataSetSourceDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "CyclicDataSet", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree dataSetWriterDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetWriterDataType"), + NodeIds.DataSetWriterDataType, + NodeIds.DataSetWriterDataType_Encoding_DefaultBinary, + NodeIds.DataSetWriterDataType_Encoding_DefaultXml, + NodeIds.DataSetWriterDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataSetWriterDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Enabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetWriterId", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetFieldContentMask", + LocalizedText.NULL_VALUE, + NodeIds.DataSetFieldContentMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "KeyFrameCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetWriterProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportSettings", + LocalizedText.NULL_VALUE, + NodeIds.DataSetWriterTransportDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "MessageSettings", + LocalizedText.NULL_VALUE, + NodeIds.DataSetWriterMessageDataType, + -1, + null, + UInteger.valueOf(0), + true) + }), + false)); + Tree dataSetWriterTransportDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetWriterTransportDataType"), + NodeIds.DataSetWriterTransportDataType, + NodeIds.DataSetWriterTransportDataType_Encoding_DefaultBinary, + NodeIds.DataSetWriterTransportDataType_Encoding_DefaultXml, + NodeIds.DataSetWriterTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataSetWriterTransportDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree brokerDataSetWriterTransportDataType = + dataSetWriterTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:BrokerDataSetWriterTransportDataType"), + NodeIds.BrokerDataSetWriterTransportDataType, + NodeIds.BrokerDataSetWriterTransportDataType_Encoding_DefaultBinary, + NodeIds.BrokerDataSetWriterTransportDataType_Encoding_DefaultXml, + NodeIds.BrokerDataSetWriterTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.BrokerDataSetWriterTransportDataType_Encoding_DefaultBinary, + NodeIds.DataSetWriterTransportDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "QueueName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ResourceUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AuthenticationProfileUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RequestedDeliveryGuarantee", + LocalizedText.NULL_VALUE, + NodeIds.BrokerTransportQualityOfService, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MetaDataQueueName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MetaDataUpdateTime", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree dataSetWriterMessageDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetWriterMessageDataType"), + NodeIds.DataSetWriterMessageDataType, + NodeIds.DataSetWriterMessageDataType_Encoding_DefaultBinary, + NodeIds.DataSetWriterMessageDataType_Encoding_DefaultXml, + NodeIds.DataSetWriterMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataSetWriterMessageDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree uadpDataSetWriterMessageDataType = + dataSetWriterMessageDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:UadpDataSetWriterMessageDataType"), + NodeIds.UadpDataSetWriterMessageDataType, + NodeIds.UadpDataSetWriterMessageDataType_Encoding_DefaultBinary, + NodeIds.UadpDataSetWriterMessageDataType_Encoding_DefaultXml, + NodeIds.UadpDataSetWriterMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UadpDataSetWriterMessageDataType_Encoding_DefaultBinary, + NodeIds.DataSetWriterMessageDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "DataSetMessageContentMask", + LocalizedText.NULL_VALUE, + NodeIds.UadpDataSetMessageContentMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ConfiguredSize", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NetworkMessageNumber", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetOffset", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree jsonDataSetWriterMessageDataType = + dataSetWriterMessageDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:JsonDataSetWriterMessageDataType"), + NodeIds.JsonDataSetWriterMessageDataType, + NodeIds.JsonDataSetWriterMessageDataType_Encoding_DefaultBinary, + NodeIds.JsonDataSetWriterMessageDataType_Encoding_DefaultXml, + NodeIds.JsonDataSetWriterMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.JsonDataSetWriterMessageDataType_Encoding_DefaultBinary, + NodeIds.DataSetWriterMessageDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "DataSetMessageContentMask", + LocalizedText.NULL_VALUE, + NodeIds.JsonDataSetMessageContentMask, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree pubSubGroupDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubGroupDataType"), + NodeIds.PubSubGroupDataType, + NodeIds.PubSubGroupDataType_Encoding_DefaultBinary, + NodeIds.PubSubGroupDataType_Encoding_DefaultXml, + NodeIds.PubSubGroupDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PubSubGroupDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Enabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityMode", + LocalizedText.NULL_VALUE, + NodeIds.MessageSecurityMode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityGroupId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityKeyServices", + LocalizedText.NULL_VALUE, + NodeIds.EndpointDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxNetworkMessageSize", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "GroupProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false) + }), + true)); + Tree writerGroupDataType = + pubSubGroupDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:WriterGroupDataType"), + NodeIds.WriterGroupDataType, + NodeIds.WriterGroupDataType_Encoding_DefaultBinary, + NodeIds.WriterGroupDataType_Encoding_DefaultXml, + NodeIds.WriterGroupDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.WriterGroupDataType_Encoding_DefaultBinary, + NodeIds.PubSubGroupDataType, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "GroupProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxNetworkMessageSize", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityKeyServices", + LocalizedText.NULL_VALUE, + NodeIds.EndpointDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityGroupId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityMode", + LocalizedText.NULL_VALUE, + NodeIds.MessageSecurityMode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Enabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriterGroupId", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishingInterval", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "KeepAliveTime", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Priority", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LocaleIds", + LocalizedText.NULL_VALUE, + NodeIds.LocaleId, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "HeaderLayoutUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportSettings", + LocalizedText.NULL_VALUE, + NodeIds.WriterGroupTransportDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "MessageSettings", + LocalizedText.NULL_VALUE, + NodeIds.WriterGroupMessageDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "DataSetWriters", + LocalizedText.NULL_VALUE, + NodeIds.DataSetWriterDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree readerGroupDataType = + pubSubGroupDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:ReaderGroupDataType"), + NodeIds.ReaderGroupDataType, + NodeIds.ReaderGroupDataType_Encoding_DefaultBinary, + NodeIds.ReaderGroupDataType_Encoding_DefaultXml, + NodeIds.ReaderGroupDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReaderGroupDataType_Encoding_DefaultBinary, + NodeIds.PubSubGroupDataType, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "GroupProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxNetworkMessageSize", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityKeyServices", + LocalizedText.NULL_VALUE, + NodeIds.EndpointDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityGroupId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityMode", + LocalizedText.NULL_VALUE, + NodeIds.MessageSecurityMode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Enabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportSettings", + LocalizedText.NULL_VALUE, + NodeIds.ReaderGroupTransportDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "MessageSettings", + LocalizedText.NULL_VALUE, + NodeIds.ReaderGroupMessageDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "DataSetReaders", + LocalizedText.NULL_VALUE, + NodeIds.DataSetReaderDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree writerGroupTransportDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:WriterGroupTransportDataType"), + NodeIds.WriterGroupTransportDataType, + NodeIds.WriterGroupTransportDataType_Encoding_DefaultBinary, + NodeIds.WriterGroupTransportDataType_Encoding_DefaultXml, + NodeIds.WriterGroupTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.WriterGroupTransportDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree datagramWriterGroupTransportDataType = + writerGroupTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:DatagramWriterGroupTransportDataType"), + NodeIds.DatagramWriterGroupTransportDataType, + NodeIds.DatagramWriterGroupTransportDataType_Encoding_DefaultBinary, + NodeIds.DatagramWriterGroupTransportDataType_Encoding_DefaultXml, + NodeIds.DatagramWriterGroupTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DatagramWriterGroupTransportDataType_Encoding_DefaultBinary, + NodeIds.WriterGroupTransportDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "MessageRepeatCount", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MessageRepeatDelay", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree datagramWriterGroupTransport2DataType = + datagramWriterGroupTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:DatagramWriterGroupTransport2DataType"), + NodeIds.DatagramWriterGroupTransport2DataType, + NodeIds.DatagramWriterGroupTransport2DataType_Encoding_DefaultBinary, + NodeIds.DatagramWriterGroupTransport2DataType_Encoding_DefaultXml, + NodeIds.DatagramWriterGroupTransport2DataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DatagramWriterGroupTransport2DataType_Encoding_DefaultBinary, + NodeIds.DatagramWriterGroupTransportDataType, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "MessageRepeatDelay", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MessageRepeatCount", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Address", + LocalizedText.NULL_VALUE, + NodeIds.NetworkAddressDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "QosCategory", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DatagramQos", + LocalizedText.NULL_VALUE, + NodeIds.TransmitQosDataType, + 1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "DiscoveryAnnounceRate", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Topic", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree brokerWriterGroupTransportDataType = + writerGroupTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:BrokerWriterGroupTransportDataType"), + NodeIds.BrokerWriterGroupTransportDataType, + NodeIds.BrokerWriterGroupTransportDataType_Encoding_DefaultBinary, + NodeIds.BrokerWriterGroupTransportDataType_Encoding_DefaultXml, + NodeIds.BrokerWriterGroupTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.BrokerWriterGroupTransportDataType_Encoding_DefaultBinary, + NodeIds.WriterGroupTransportDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "QueueName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ResourceUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AuthenticationProfileUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RequestedDeliveryGuarantee", + LocalizedText.NULL_VALUE, + NodeIds.BrokerTransportQualityOfService, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree writerGroupMessageDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:WriterGroupMessageDataType"), + NodeIds.WriterGroupMessageDataType, + NodeIds.WriterGroupMessageDataType_Encoding_DefaultBinary, + NodeIds.WriterGroupMessageDataType_Encoding_DefaultXml, + NodeIds.WriterGroupMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.WriterGroupMessageDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree uadpWriterGroupMessageDataType = + writerGroupMessageDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:UadpWriterGroupMessageDataType"), + NodeIds.UadpWriterGroupMessageDataType, + NodeIds.UadpWriterGroupMessageDataType_Encoding_DefaultBinary, + NodeIds.UadpWriterGroupMessageDataType_Encoding_DefaultXml, + NodeIds.UadpWriterGroupMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UadpWriterGroupMessageDataType_Encoding_DefaultBinary, + NodeIds.WriterGroupMessageDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "GroupVersion", + LocalizedText.NULL_VALUE, + NodeIds.VersionTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetOrdering", + LocalizedText.NULL_VALUE, + NodeIds.DataSetOrderingType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NetworkMessageContentMask", + LocalizedText.NULL_VALUE, + NodeIds.UadpNetworkMessageContentMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SamplingOffset", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishingOffset", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree jsonWriterGroupMessageDataType = + writerGroupMessageDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:JsonWriterGroupMessageDataType"), + NodeIds.JsonWriterGroupMessageDataType, + NodeIds.JsonWriterGroupMessageDataType_Encoding_DefaultBinary, + NodeIds.JsonWriterGroupMessageDataType_Encoding_DefaultXml, + NodeIds.JsonWriterGroupMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.JsonWriterGroupMessageDataType_Encoding_DefaultBinary, + NodeIds.WriterGroupMessageDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NetworkMessageContentMask", + LocalizedText.NULL_VALUE, + NodeIds.JsonNetworkMessageContentMask, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree pubSubConnectionDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubConnectionDataType"), + NodeIds.PubSubConnectionDataType, + NodeIds.PubSubConnectionDataType_Encoding_DefaultBinary, + NodeIds.PubSubConnectionDataType_Encoding_DefaultXml, + NodeIds.PubSubConnectionDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PubSubConnectionDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Enabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublisherId", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportProfileUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Address", + LocalizedText.NULL_VALUE, + NodeIds.NetworkAddressDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "ConnectionProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportSettings", + LocalizedText.NULL_VALUE, + NodeIds.ConnectionTransportDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "WriterGroups", + LocalizedText.NULL_VALUE, + NodeIds.WriterGroupDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReaderGroups", + LocalizedText.NULL_VALUE, + NodeIds.ReaderGroupDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree connectionTransportDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ConnectionTransportDataType"), + NodeIds.ConnectionTransportDataType, + NodeIds.ConnectionTransportDataType_Encoding_DefaultBinary, + NodeIds.ConnectionTransportDataType_Encoding_DefaultXml, + NodeIds.ConnectionTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ConnectionTransportDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree brokerConnectionTransportDataType = + connectionTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:BrokerConnectionTransportDataType"), + NodeIds.BrokerConnectionTransportDataType, + NodeIds.BrokerConnectionTransportDataType_Encoding_DefaultBinary, + NodeIds.BrokerConnectionTransportDataType_Encoding_DefaultXml, + NodeIds.BrokerConnectionTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.BrokerConnectionTransportDataType_Encoding_DefaultBinary, + NodeIds.ConnectionTransportDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ResourceUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AuthenticationProfileUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree datagramConnectionTransportDataType = + connectionTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:DatagramConnectionTransportDataType"), + NodeIds.DatagramConnectionTransportDataType, + NodeIds.DatagramConnectionTransportDataType_Encoding_DefaultBinary, + NodeIds.DatagramConnectionTransportDataType_Encoding_DefaultXml, + NodeIds.DatagramConnectionTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DatagramConnectionTransportDataType_Encoding_DefaultBinary, + NodeIds.ConnectionTransportDataType, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "DiscoveryAddress", + LocalizedText.NULL_VALUE, + NodeIds.NetworkAddressDataType, + -1, + null, + UInteger.valueOf(0), + true) + }), + false)); + Tree datagramConnectionTransport2DataType = + datagramConnectionTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:DatagramConnectionTransport2DataType"), + NodeIds.DatagramConnectionTransport2DataType, + NodeIds.DatagramConnectionTransport2DataType_Encoding_DefaultBinary, + NodeIds.DatagramConnectionTransport2DataType_Encoding_DefaultXml, + NodeIds.DatagramConnectionTransport2DataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DatagramConnectionTransport2DataType_Encoding_DefaultBinary, + NodeIds.DatagramConnectionTransportDataType, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "DiscoveryAddress", + LocalizedText.NULL_VALUE, + NodeIds.NetworkAddressDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "DiscoveryAnnounceRate", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DiscoveryMaxMessageSize", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "QosCategory", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DatagramQos", + LocalizedText.NULL_VALUE, + NodeIds.QosDataType, + 1, + null, + UInteger.valueOf(0), + true) + }), + false)); + Tree readerGroupTransportDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ReaderGroupTransportDataType"), + NodeIds.ReaderGroupTransportDataType, + NodeIds.ReaderGroupTransportDataType_Encoding_DefaultBinary, + NodeIds.ReaderGroupTransportDataType_Encoding_DefaultXml, + NodeIds.ReaderGroupTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReaderGroupTransportDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree readerGroupMessageDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ReaderGroupMessageDataType"), + NodeIds.ReaderGroupMessageDataType, + NodeIds.ReaderGroupMessageDataType_Encoding_DefaultBinary, + NodeIds.ReaderGroupMessageDataType_Encoding_DefaultXml, + NodeIds.ReaderGroupMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReaderGroupMessageDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree dataSetReaderDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetReaderDataType"), + NodeIds.DataSetReaderDataType, + NodeIds.DataSetReaderDataType_Encoding_DefaultBinary, + NodeIds.DataSetReaderDataType_Encoding_DefaultXml, + NodeIds.DataSetReaderDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataSetReaderDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Enabled", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublisherId", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "WriterGroupId", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetWriterId", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetMetaData", + LocalizedText.NULL_VALUE, + NodeIds.DataSetMetaDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetFieldContentMask", + LocalizedText.NULL_VALUE, + NodeIds.DataSetFieldContentMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MessageReceiveTimeout", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "KeyFrameCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "HeaderLayoutUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityMode", + LocalizedText.NULL_VALUE, + NodeIds.MessageSecurityMode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityGroupId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityKeyServices", + LocalizedText.NULL_VALUE, + NodeIds.EndpointDescription, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetReaderProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TransportSettings", + LocalizedText.NULL_VALUE, + NodeIds.DataSetReaderTransportDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "MessageSettings", + LocalizedText.NULL_VALUE, + NodeIds.DataSetReaderMessageDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "SubscribedDataSet", + LocalizedText.NULL_VALUE, + NodeIds.SubscribedDataSetDataType, + -1, + null, + UInteger.valueOf(0), + true) + }), + false)); + Tree dataSetReaderTransportDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetReaderTransportDataType"), + NodeIds.DataSetReaderTransportDataType, + NodeIds.DataSetReaderTransportDataType_Encoding_DefaultBinary, + NodeIds.DataSetReaderTransportDataType_Encoding_DefaultXml, + NodeIds.DataSetReaderTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataSetReaderTransportDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree brokerDataSetReaderTransportDataType = + dataSetReaderTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:BrokerDataSetReaderTransportDataType"), + NodeIds.BrokerDataSetReaderTransportDataType, + NodeIds.BrokerDataSetReaderTransportDataType_Encoding_DefaultBinary, + NodeIds.BrokerDataSetReaderTransportDataType_Encoding_DefaultXml, + NodeIds.BrokerDataSetReaderTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.BrokerDataSetReaderTransportDataType_Encoding_DefaultBinary, + NodeIds.DataSetReaderTransportDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "QueueName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ResourceUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AuthenticationProfileUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RequestedDeliveryGuarantee", + LocalizedText.NULL_VALUE, + NodeIds.BrokerTransportQualityOfService, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MetaDataQueueName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree datagramDataSetReaderTransportDataType = + dataSetReaderTransportDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:DatagramDataSetReaderTransportDataType"), + NodeIds.DatagramDataSetReaderTransportDataType, + NodeIds.DatagramDataSetReaderTransportDataType_Encoding_DefaultBinary, + NodeIds.DatagramDataSetReaderTransportDataType_Encoding_DefaultXml, + NodeIds.DatagramDataSetReaderTransportDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DatagramDataSetReaderTransportDataType_Encoding_DefaultBinary, + NodeIds.DataSetReaderTransportDataType, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "Address", + LocalizedText.NULL_VALUE, + NodeIds.NetworkAddressDataType, + -1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "QosCategory", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DatagramQos", + LocalizedText.NULL_VALUE, + NodeIds.ReceiveQosDataType, + 1, + null, + UInteger.valueOf(0), + true), + new StructureField( + "Topic", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree dataSetReaderMessageDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetReaderMessageDataType"), + NodeIds.DataSetReaderMessageDataType, + NodeIds.DataSetReaderMessageDataType_Encoding_DefaultBinary, + NodeIds.DataSetReaderMessageDataType_Encoding_DefaultXml, + NodeIds.DataSetReaderMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DataSetReaderMessageDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree uadpDataSetReaderMessageDataType = + dataSetReaderMessageDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:UadpDataSetReaderMessageDataType"), + NodeIds.UadpDataSetReaderMessageDataType, + NodeIds.UadpDataSetReaderMessageDataType_Encoding_DefaultBinary, + NodeIds.UadpDataSetReaderMessageDataType_Encoding_DefaultXml, + NodeIds.UadpDataSetReaderMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UadpDataSetReaderMessageDataType_Encoding_DefaultBinary, + NodeIds.DataSetReaderMessageDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "GroupVersion", + LocalizedText.NULL_VALUE, + NodeIds.VersionTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NetworkMessageNumber", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetOffset", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetClassId", + LocalizedText.NULL_VALUE, + NodeIds.Guid, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "NetworkMessageContentMask", + LocalizedText.NULL_VALUE, + NodeIds.UadpNetworkMessageContentMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetMessageContentMask", + LocalizedText.NULL_VALUE, + NodeIds.UadpDataSetMessageContentMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PublishingInterval", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReceiveOffset", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ProcessingOffset", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree jsonDataSetReaderMessageDataType = + dataSetReaderMessageDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:JsonDataSetReaderMessageDataType"), + NodeIds.JsonDataSetReaderMessageDataType, + NodeIds.JsonDataSetReaderMessageDataType_Encoding_DefaultBinary, + NodeIds.JsonDataSetReaderMessageDataType_Encoding_DefaultXml, + NodeIds.JsonDataSetReaderMessageDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.JsonDataSetReaderMessageDataType_Encoding_DefaultBinary, + NodeIds.DataSetReaderMessageDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NetworkMessageContentMask", + LocalizedText.NULL_VALUE, + NodeIds.JsonNetworkMessageContentMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetMessageContentMask", + LocalizedText.NULL_VALUE, + NodeIds.JsonDataSetMessageContentMask, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree subscribedDataSetDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:SubscribedDataSetDataType"), + NodeIds.SubscribedDataSetDataType, + NodeIds.SubscribedDataSetDataType_Encoding_DefaultBinary, + NodeIds.SubscribedDataSetDataType_Encoding_DefaultXml, + NodeIds.SubscribedDataSetDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SubscribedDataSetDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree targetVariablesDataType = + subscribedDataSetDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:TargetVariablesDataType"), + NodeIds.TargetVariablesDataType, + NodeIds.TargetVariablesDataType_Encoding_DefaultBinary, + NodeIds.TargetVariablesDataType_Encoding_DefaultXml, + NodeIds.TargetVariablesDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.TargetVariablesDataType_Encoding_DefaultBinary, + NodeIds.SubscribedDataSetDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "TargetVariables", + LocalizedText.NULL_VALUE, + NodeIds.FieldTargetDataType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree subscribedDataSetMirrorDataType = + subscribedDataSetDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:SubscribedDataSetMirrorDataType"), + NodeIds.SubscribedDataSetMirrorDataType, + NodeIds.SubscribedDataSetMirrorDataType_Encoding_DefaultBinary, + NodeIds.SubscribedDataSetMirrorDataType_Encoding_DefaultXml, + NodeIds.SubscribedDataSetMirrorDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SubscribedDataSetMirrorDataType_Encoding_DefaultBinary, + NodeIds.SubscribedDataSetDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ParentNodeName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree standaloneSubscribedDataSetRefDataType = + subscribedDataSetDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:StandaloneSubscribedDataSetRefDataType"), + NodeIds.StandaloneSubscribedDataSetRefDataType, + NodeIds.StandaloneSubscribedDataSetRefDataType_Encoding_DefaultBinary, + NodeIds.StandaloneSubscribedDataSetRefDataType_Encoding_DefaultXml, + NodeIds.StandaloneSubscribedDataSetRefDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.StandaloneSubscribedDataSetRefDataType_Encoding_DefaultBinary, + NodeIds.SubscribedDataSetDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "DataSetName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree standaloneSubscribedDataSetDataType = + subscribedDataSetDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:StandaloneSubscribedDataSetDataType"), + NodeIds.StandaloneSubscribedDataSetDataType, + NodeIds.StandaloneSubscribedDataSetDataType_Encoding_DefaultBinary, + NodeIds.StandaloneSubscribedDataSetDataType_Encoding_DefaultXml, + NodeIds.StandaloneSubscribedDataSetDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.StandaloneSubscribedDataSetDataType_Encoding_DefaultBinary, + NodeIds.SubscribedDataSetDataType, + StructureType.StructureWithSubtypedValues, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetFolder", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DataSetMetaData", + LocalizedText.NULL_VALUE, + NodeIds.DataSetMetaDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SubscribedDataSet", + LocalizedText.NULL_VALUE, + NodeIds.SubscribedDataSetDataType, + -1, + null, + UInteger.valueOf(0), + true) + }), + false)); + Tree identityMappingRuleType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:IdentityMappingRuleType"), + NodeIds.IdentityMappingRuleType, + NodeIds.IdentityMappingRuleType_Encoding_DefaultBinary, + NodeIds.IdentityMappingRuleType_Encoding_DefaultXml, + NodeIds.IdentityMappingRuleType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.IdentityMappingRuleType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "CriteriaType", + LocalizedText.NULL_VALUE, + NodeIds.IdentityCriteriaType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Criteria", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree additionalParametersType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:AdditionalParametersType"), + NodeIds.AdditionalParametersType, + NodeIds.AdditionalParametersType_Encoding_DefaultBinary, + NodeIds.AdditionalParametersType_Encoding_DefaultXml, + NodeIds.AdditionalParametersType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AdditionalParametersType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Parameters", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree ephemeralKeyType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:EphemeralKeyType"), + NodeIds.EphemeralKeyType, + NodeIds.EphemeralKeyType_Encoding_DefaultBinary, + NodeIds.EphemeralKeyType_Encoding_DefaultXml, + NodeIds.EphemeralKeyType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.EphemeralKeyType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PublicKey", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Signature", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree decimalDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DecimalDataType"), + NodeIds.DecimalDataType, + NodeIds.DecimalDataType_Encoding_DefaultBinary, + NodeIds.DecimalDataType_Encoding_DefaultXml, + NodeIds.DecimalDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DecimalDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Scale", + LocalizedText.NULL_VALUE, + NodeIds.Int16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Value", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree actionTargetDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ActionTargetDataType"), + NodeIds.ActionTargetDataType, + NodeIds.ActionTargetDataType_Encoding_DefaultBinary, + NodeIds.ActionTargetDataType_Encoding_DefaultXml, + NodeIds.ActionTargetDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ActionTargetDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ActionTargetId", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree actionMethodDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ActionMethodDataType"), + NodeIds.ActionMethodDataType, + NodeIds.ActionMethodDataType_Encoding_DefaultBinary, + NodeIds.ActionMethodDataType_Encoding_DefaultXml, + NodeIds.ActionMethodDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ActionMethodDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ObjectId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MethodId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree dtlsPubSubConnectionDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:DtlsPubSubConnectionDataType"), + NodeIds.DtlsPubSubConnectionDataType, + NodeIds.DtlsPubSubConnectionDataType_Encoding_DefaultBinary, + NodeIds.DtlsPubSubConnectionDataType_Encoding_DefaultXml, + NodeIds.DtlsPubSubConnectionDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.DtlsPubSubConnectionDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ClientCipherSuite", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ServerCipherSuites", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ZeroRTT", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CertificateGroupId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "VerifyClientCertificate", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree rationalNumber = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:RationalNumber"), + NodeIds.RationalNumber, + NodeIds.RationalNumber_Encoding_DefaultBinary, + NodeIds.RationalNumber_Encoding_DefaultXml, + NodeIds.RationalNumber_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.RationalNumber_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Numerator", + LocalizedText.NULL_VALUE, + NodeIds.Int32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Denominator", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree vector = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:Vector"), + NodeIds.Vector, + NodeIds.Vector_Encoding_DefaultBinary, + NodeIds.Vector_Encoding_DefaultXml, + NodeIds.Vector_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.Vector_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree _3DVector = + vector.addChild( + new ClientDataType( + QualifiedName.parse("0:3DVector"), + NodeIds.ThreeDVector, + NodeIds.ThreeDVector_Encoding_DefaultBinary, + NodeIds.ThreeDVector_Encoding_DefaultXml, + NodeIds.ThreeDVector_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ThreeDVector_Encoding_DefaultBinary, + NodeIds.Vector, + StructureType.Structure, + new StructureField[] { + new StructureField( + "X", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Y", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Z", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree cartesianCoordinates = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:CartesianCoordinates"), + NodeIds.CartesianCoordinates, + NodeIds.CartesianCoordinates_Encoding_DefaultBinary, + NodeIds.CartesianCoordinates_Encoding_DefaultXml, + NodeIds.CartesianCoordinates_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.CartesianCoordinates_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree _3DCartesianCoordinates = + cartesianCoordinates.addChild( + new ClientDataType( + QualifiedName.parse("0:3DCartesianCoordinates"), + NodeIds.ThreeDCartesianCoordinates, + NodeIds.ThreeDCartesianCoordinates_Encoding_DefaultBinary, + NodeIds.ThreeDCartesianCoordinates_Encoding_DefaultXml, + NodeIds.ThreeDCartesianCoordinates_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ThreeDCartesianCoordinates_Encoding_DefaultBinary, + NodeIds.CartesianCoordinates, + StructureType.Structure, + new StructureField[] { + new StructureField( + "X", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Y", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Z", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree orientation = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:Orientation"), + NodeIds.Orientation, + NodeIds.Orientation_Encoding_DefaultBinary, + NodeIds.Orientation_Encoding_DefaultXml, + NodeIds.Orientation_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.Orientation_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree _3DOrientation = + orientation.addChild( + new ClientDataType( + QualifiedName.parse("0:3DOrientation"), + NodeIds.ThreeDOrientation, + NodeIds.ThreeDOrientation_Encoding_DefaultBinary, + NodeIds.ThreeDOrientation_Encoding_DefaultXml, + NodeIds.ThreeDOrientation_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ThreeDOrientation_Encoding_DefaultBinary, + NodeIds.Orientation, + StructureType.Structure, + new StructureField[] { + new StructureField( + "A", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "B", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "C", + LocalizedText.NULL_VALUE, + NodeIds.Double, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree frame = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:Frame"), + NodeIds.Frame, + NodeIds.Frame_Encoding_DefaultBinary, + NodeIds.Frame_Encoding_DefaultXml, + NodeIds.Frame_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.Frame_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree _3DFrame = + frame.addChild( + new ClientDataType( + QualifiedName.parse("0:3DFrame"), + NodeIds.ThreeDFrame, + NodeIds.ThreeDFrame_Encoding_DefaultBinary, + NodeIds.ThreeDFrame_Encoding_DefaultXml, + NodeIds.ThreeDFrame_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ThreeDFrame_Encoding_DefaultBinary, + NodeIds.Frame, + StructureType.Structure, + new StructureField[] { + new StructureField( + "CartesianCoordinates", + LocalizedText.NULL_VALUE, + NodeIds.ThreeDCartesianCoordinates, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Orientation", + LocalizedText.NULL_VALUE, + NodeIds.ThreeDOrientation, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree lldpManagementAddressTxPortType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:LldpManagementAddressTxPortType"), + NodeIds.LldpManagementAddressTxPortType, + NodeIds.LldpManagementAddressTxPortType_Encoding_DefaultBinary, + NodeIds.LldpManagementAddressTxPortType_Encoding_DefaultXml, + NodeIds.LldpManagementAddressTxPortType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.LldpManagementAddressTxPortType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "AddressSubtype", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ManAddress", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TxEnable", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AddrLen", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IfSubtype", + LocalizedText.NULL_VALUE, + NodeIds.ManAddrIfSubtype, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IfId", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree lldpManagementAddressType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:LldpManagementAddressType"), + NodeIds.LldpManagementAddressType, + NodeIds.LldpManagementAddressType_Encoding_DefaultBinary, + NodeIds.LldpManagementAddressType_Encoding_DefaultXml, + NodeIds.LldpManagementAddressType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.LldpManagementAddressType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "AddressSubtype", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Address", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IfSubtype", + LocalizedText.NULL_VALUE, + NodeIds.ManAddrIfSubtype, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IfId", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree lldpTlvType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:LldpTlvType"), + NodeIds.LldpTlvType, + NodeIds.LldpTlvType_Encoding_DefaultBinary, + NodeIds.LldpTlvType_Encoding_DefaultXml, + NodeIds.LldpTlvType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.LldpTlvType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "TlvType", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TlvInfo", + LocalizedText.NULL_VALUE, + NodeIds.ByteString, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree aliasNameDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:AliasNameDataType"), + NodeIds.AliasNameDataType, + NodeIds.AliasNameDataType_Encoding_DefaultBinary, + NodeIds.AliasNameDataType_Encoding_DefaultXml, + NodeIds.AliasNameDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AliasNameDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "AliasName", + LocalizedText.NULL_VALUE, + NodeIds.QualifiedName, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReferencedNodes", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree currencyUnitType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:CurrencyUnitType"), + NodeIds.CurrencyUnitType, + NodeIds.CurrencyUnitType_Encoding_DefaultBinary, + NodeIds.CurrencyUnitType_Encoding_DefaultXml, + NodeIds.CurrencyUnitType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.CurrencyUnitType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NumericCode", + LocalizedText.NULL_VALUE, + NodeIds.Int16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Exponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AlphabeticCode", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Currency", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree securityGroupDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:SecurityGroupDataType"), + NodeIds.SecurityGroupDataType, + NodeIds.SecurityGroupDataType_Encoding_DefaultBinary, + NodeIds.SecurityGroupDataType_Encoding_DefaultXml, + NodeIds.SecurityGroupDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.SecurityGroupDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityGroupFolder", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "KeyLifetime", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityPolicyUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxFutureKeyCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "MaxPastKeyCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityGroupId", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RolePermissions", + LocalizedText.NULL_VALUE, + NodeIds.RolePermissionType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "GroupProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree qosDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:QosDataType"), + NodeIds.QosDataType, + NodeIds.QosDataType_Encoding_DefaultBinary, + NodeIds.QosDataType_Encoding_DefaultXml, + NodeIds.QosDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.QosDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[0]), + true)); + Tree transmitQosDataType = + qosDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:TransmitQosDataType"), + NodeIds.TransmitQosDataType, + NodeIds.TransmitQosDataType_Encoding_DefaultBinary, + NodeIds.TransmitQosDataType_Encoding_DefaultXml, + NodeIds.TransmitQosDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.TransmitQosDataType_Encoding_DefaultBinary, + NodeIds.QosDataType, + StructureType.Structure, + new StructureField[0]), + true)); + Tree transmitQosPriorityDataType = + transmitQosDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:TransmitQosPriorityDataType"), + NodeIds.TransmitQosPriorityDataType, + NodeIds.TransmitQosPriorityDataType_Encoding_DefaultBinary, + NodeIds.TransmitQosPriorityDataType_Encoding_DefaultXml, + NodeIds.TransmitQosPriorityDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.TransmitQosPriorityDataType_Encoding_DefaultBinary, + NodeIds.TransmitQosDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PriorityLabel", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree receiveQosDataType = + qosDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:ReceiveQosDataType"), + NodeIds.ReceiveQosDataType, + NodeIds.ReceiveQosDataType_Encoding_DefaultBinary, + NodeIds.ReceiveQosDataType_Encoding_DefaultXml, + NodeIds.ReceiveQosDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReceiveQosDataType_Encoding_DefaultBinary, + NodeIds.QosDataType, + StructureType.Structure, + new StructureField[0]), + true)); + Tree receiveQosPriorityDataType = + receiveQosDataType.addChild( + new ClientDataType( + QualifiedName.parse("0:ReceiveQosPriorityDataType"), + NodeIds.ReceiveQosPriorityDataType, + NodeIds.ReceiveQosPriorityDataType_Encoding_DefaultBinary, + NodeIds.ReceiveQosPriorityDataType_Encoding_DefaultXml, + NodeIds.ReceiveQosPriorityDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReceiveQosPriorityDataType_Encoding_DefaultBinary, + NodeIds.ReceiveQosDataType, + StructureType.Structure, + new StructureField[] { + new StructureField( + "PriorityLabel", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree programDiagnostic2DataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ProgramDiagnostic2DataType"), + NodeIds.ProgramDiagnostic2DataType, + NodeIds.ProgramDiagnostic2DataType_Encoding_DefaultBinary, + NodeIds.ProgramDiagnostic2DataType_Encoding_DefaultXml, + NodeIds.ProgramDiagnostic2DataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ProgramDiagnostic2DataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "CreateSessionId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "CreateClientName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "InvocationCreationTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastTransitionTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodCall", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodSessionId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodInputArguments", + LocalizedText.NULL_VALUE, + NodeIds.Argument, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodOutputArguments", + LocalizedText.NULL_VALUE, + NodeIds.Argument, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodInputValues", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodOutputValues", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodCallTime", + LocalizedText.NULL_VALUE, + NodeIds.UtcTime, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LastMethodReturnStatus", + LocalizedText.NULL_VALUE, + NodeIds.StatusCode, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree portableQualifiedName = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PortableQualifiedName"), + NodeIds.PortableQualifiedName, + NodeIds.PortableQualifiedName_Encoding_DefaultBinary, + NodeIds.PortableQualifiedName_Encoding_DefaultXml, + NodeIds.PortableQualifiedName_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PortableQualifiedName_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NamespaceUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree portableNodeId = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PortableNodeId"), + NodeIds.PortableNodeId, + NodeIds.PortableNodeId_Encoding_DefaultBinary, + NodeIds.PortableNodeId_Encoding_DefaultXml, + NodeIds.PortableNodeId_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PortableNodeId_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "NamespaceUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Identifier", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree unsignedRationalNumber = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:UnsignedRationalNumber"), + NodeIds.UnsignedRationalNumber, + NodeIds.UnsignedRationalNumber_Encoding_DefaultBinary, + NodeIds.UnsignedRationalNumber_Encoding_DefaultXml, + NodeIds.UnsignedRationalNumber_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UnsignedRationalNumber_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Numerator", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Denominator", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree userManagementDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:UserManagementDataType"), + NodeIds.UserManagementDataType, + NodeIds.UserManagementDataType_Encoding_DefaultBinary, + NodeIds.UserManagementDataType_Encoding_DefaultXml, + NodeIds.UserManagementDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.UserManagementDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "UserName", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserConfiguration", + LocalizedText.NULL_VALUE, + NodeIds.UserConfigurationMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree priorityMappingEntryType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PriorityMappingEntryType"), + NodeIds.PriorityMappingEntryType, + NodeIds.PriorityMappingEntryType_Encoding_DefaultBinary, + NodeIds.PriorityMappingEntryType_Encoding_DefaultXml, + NodeIds.PriorityMappingEntryType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PriorityMappingEntryType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "MappingUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PriorityLabel", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PriorityValue_PCP", + LocalizedText.NULL_VALUE, + NodeIds.Byte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PriorityValue_DSCP", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree pubSubKeyPushTargetDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubKeyPushTargetDataType"), + NodeIds.PubSubKeyPushTargetDataType, + NodeIds.PubSubKeyPushTargetDataType_Encoding_DefaultBinary, + NodeIds.PubSubKeyPushTargetDataType_Encoding_DefaultXml, + NodeIds.PubSubKeyPushTargetDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PubSubKeyPushTargetDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ApplicationUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PushTargetFolder", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EndpointUrl", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityPolicyUri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "UserTokenType", + LocalizedText.NULL_VALUE, + NodeIds.UserTokenPolicy, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RequestedKeyCount", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "RetryInterval", + LocalizedText.NULL_VALUE, + NodeIds.Duration, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "PushTargetProperties", + LocalizedText.NULL_VALUE, + NodeIds.KeyValuePair, + 1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "SecurityGroups", + LocalizedText.NULL_VALUE, + NodeIds.String, + 1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree pubSubConfigurationRefDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubConfigurationRefDataType"), + NodeIds.PubSubConfigurationRefDataType, + NodeIds.PubSubConfigurationRefDataType_Encoding_DefaultBinary, + NodeIds.PubSubConfigurationRefDataType_Encoding_DefaultXml, + NodeIds.PubSubConfigurationRefDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PubSubConfigurationRefDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ConfigurationMask", + LocalizedText.NULL_VALUE, + NodeIds.PubSubConfigurationRefMask, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ElementIndex", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ConnectionIndex", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "GroupIndex", + LocalizedText.NULL_VALUE, + NodeIds.UInt16, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree pubSubConfigurationValueDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubConfigurationValueDataType"), + NodeIds.PubSubConfigurationValueDataType, + NodeIds.PubSubConfigurationValueDataType_Encoding_DefaultBinary, + NodeIds.PubSubConfigurationValueDataType_Encoding_DefaultXml, + NodeIds.PubSubConfigurationValueDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.PubSubConfigurationValueDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ConfigurationElement", + LocalizedText.NULL_VALUE, + NodeIds.PubSubConfigurationRefDataType, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Identifier", + LocalizedText.NULL_VALUE, + NodeIds.BaseDataType, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree transactionErrorType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:TransactionErrorType"), + NodeIds.TransactionErrorType, + NodeIds.TransactionErrorType_Encoding_DefaultBinary, + NodeIds.TransactionErrorType_Encoding_DefaultXml, + NodeIds.TransactionErrorType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.TransactionErrorType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "TargetId", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Error", + LocalizedText.NULL_VALUE, + NodeIds.StatusCode, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Message", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree bitFieldDefinition = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:BitFieldDefinition"), + NodeIds.BitFieldDefinition, + NodeIds.BitFieldDefinition_Encoding_DefaultBinary, + NodeIds.BitFieldDefinition_Encoding_DefaultXml, + NodeIds.BitFieldDefinition_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.BitFieldDefinition_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Name", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Description", + LocalizedText.NULL_VALUE, + NodeIds.LocalizedText, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Reserved", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "StartingBitPosition", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "EndingBitPosition", + LocalizedText.NULL_VALUE, + NodeIds.UInt32, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree annotationDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:AnnotationDataType"), + NodeIds.AnnotationDataType, + NodeIds.AnnotationDataType_Encoding_DefaultBinary, + NodeIds.AnnotationDataType_Encoding_DefaultXml, + NodeIds.AnnotationDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.AnnotationDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "Annotation", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Discipline", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Uri", + LocalizedText.NULL_VALUE, + NodeIds.String, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree linearConversionDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:LinearConversionDataType"), + NodeIds.LinearConversionDataType, + NodeIds.LinearConversionDataType_Encoding_DefaultBinary, + NodeIds.LinearConversionDataType_Encoding_DefaultXml, + NodeIds.LinearConversionDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.LinearConversionDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "InitialAddend", + LocalizedText.NULL_VALUE, + NodeIds.Float, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Multiplicand", + LocalizedText.NULL_VALUE, + NodeIds.Float, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "Divisor", + LocalizedText.NULL_VALUE, + NodeIds.Float, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "FinalAddend", + LocalizedText.NULL_VALUE, + NodeIds.Float, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree quantityDimension = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:QuantityDimension"), + NodeIds.QuantityDimension, + NodeIds.QuantityDimension_Encoding_DefaultBinary, + NodeIds.QuantityDimension_Encoding_DefaultXml, + NodeIds.QuantityDimension_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.QuantityDimension_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "MassExponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LengthExponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TimeExponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ElectricCurrentExponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AmountOfSubstanceExponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "LuminousIntensityExponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "AbsoluteTemperatureExponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "DimensionlessExponent", + LocalizedText.NULL_VALUE, + NodeIds.SByte, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree referenceDescriptionDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ReferenceDescriptionDataType"), + NodeIds.ReferenceDescriptionDataType, + NodeIds.ReferenceDescriptionDataType_Encoding_DefaultBinary, + NodeIds.ReferenceDescriptionDataType_Encoding_DefaultXml, + NodeIds.ReferenceDescriptionDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReferenceDescriptionDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "SourceNode", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "ReferenceType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsForward", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetNode", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + Tree referenceListEntryDataType = + structure.addChild( + new ClientDataType( + QualifiedName.parse("0:ReferenceListEntryDataType"), + NodeIds.ReferenceListEntryDataType, + NodeIds.ReferenceListEntryDataType_Encoding_DefaultBinary, + NodeIds.ReferenceListEntryDataType_Encoding_DefaultXml, + NodeIds.ReferenceListEntryDataType_Encoding_DefaultJson, + new StructureDefinition( + NodeIds.ReferenceListEntryDataType_Encoding_DefaultBinary, + NodeIds.Structure, + StructureType.Structure, + new StructureField[] { + new StructureField( + "ReferenceType", + LocalizedText.NULL_VALUE, + NodeIds.NodeId, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "IsForward", + LocalizedText.NULL_VALUE, + NodeIds.Boolean, + -1, + null, + UInteger.valueOf(0), + false), + new StructureField( + "TargetNode", + LocalizedText.NULL_VALUE, + NodeIds.ExpandedNodeId, + -1, + null, + UInteger.valueOf(0), + false) + }), + false)); + } + + @SuppressWarnings("unused") + private static void createEnumerationNodes(Tree enumeration) { + Tree structureType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:StructureType"), + NodeIds.StructureType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Structure"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "StructureWithOptionalFields"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Union"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "StructureWithSubtypedValues"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "UnionWithSubtypedValues") + }), + false)); + Tree namingRuleType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:NamingRuleType"), + NodeIds.NamingRuleType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "The BrowseName must appear in all instances of the type."), + "Mandatory"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "The BrowseName may appear in an instance of the type."), + "Optional"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The modelling rule defines a constraint and the BrowseName is not used in an instance of the type."), + "Constraint") + }), + false)); + Tree idType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:IdType"), + NodeIds.IdType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Numeric"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "String"), + new EnumField(2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Guid"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Opaque") + }), + false)); + Tree nodeClass = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:NodeClass"), + NodeIds.NodeClass, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "No value is specified."), + "Unspecified"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The Node is an Object."), + "Object"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The Node is a Variable."), + "Variable"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The Node is a Method."), + "Method"), + new EnumField( + 8L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The Node is an ObjectType."), + "ObjectType"), + new EnumField( + 16L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The Node is a VariableType."), + "VariableType"), + new EnumField( + 32L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The Node is a ReferenceType."), + "ReferenceType"), + new EnumField( + 64L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The Node is a DataType."), + "DataType"), + new EnumField( + 128L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The Node is a View."), + "View") + }), + false)); + Tree messageSecurityMode = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:MessageSecurityMode"), + NodeIds.MessageSecurityMode, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Invalid"), + new EnumField(1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "None"), + new EnumField(2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Sign"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "SignAndEncrypt") + }), + false)); + Tree userTokenType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:UserTokenType"), + NodeIds.UserTokenType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Anonymous"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "UserName"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Certificate"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "IssuedToken") + }), + false)); + Tree applicationType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:ApplicationType"), + NodeIds.ApplicationType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Server"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Client"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "ClientAndServer"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "DiscoveryServer") + }), + false)); + Tree securityTokenRequestType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:SecurityTokenRequestType"), + NodeIds.SecurityTokenRequestType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Issue"), + new EnumField(1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Renew") + }), + false)); + Tree nodeAttributesMask = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:NodeAttributesMask"), + NodeIds.NodeAttributesMask, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField(0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "None"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "AccessLevel"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "ArrayDimensions"), + new EnumField( + 4L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "BrowseName"), + new EnumField( + 8L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "ContainsNoLoops"), + new EnumField( + 16L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "DataType"), + new EnumField( + 32L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Description"), + new EnumField( + 64L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "DisplayName"), + new EnumField( + 128L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "EventNotifier"), + new EnumField( + 256L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Executable"), + new EnumField( + 512L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Historizing"), + new EnumField( + 1024L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "InverseName"), + new EnumField( + 2048L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "IsAbstract"), + new EnumField( + 4096L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "MinimumSamplingInterval"), + new EnumField( + 8192L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "NodeClass"), + new EnumField( + 16384L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "NodeId"), + new EnumField( + 32768L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Symmetric"), + new EnumField( + 65536L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "UserAccessLevel"), + new EnumField( + 131072L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "UserExecutable"), + new EnumField( + 262144L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "UserWriteMask"), + new EnumField( + 524288L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "ValueRank"), + new EnumField( + 1048576L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "WriteMask"), + new EnumField( + 2097152L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Value"), + new EnumField( + 4194304L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "DataTypeDefinition"), + new EnumField( + 8388608L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "RolePermissions"), + new EnumField( + 16777216L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "AccessRestrictions"), + new EnumField( + 33554431L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "All"), + new EnumField( + 26501220L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "BaseNode"), + new EnumField( + 26501348L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Object"), + new EnumField( + 26503268L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "ObjectType"), + new EnumField( + 26571383L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "Variable"), + new EnumField( + 28600438L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "VariableType"), + new EnumField( + 26632548L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Method"), + new EnumField( + 26537060L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "ReferenceType"), + new EnumField( + 26501356L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "View") + }), + false)); + Tree filterOperator = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:FilterOperator"), + NodeIds.FilterOperator, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Equals"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "IsNull"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "GreaterThan"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "LessThan"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "GreaterThanOrEqual"), + new EnumField( + 5L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "LessThanOrEqual"), + new EnumField(6L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Like"), + new EnumField(7L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Not"), + new EnumField( + 8L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Between"), + new EnumField( + 9L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "InList"), + new EnumField(10L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "And"), + new EnumField(11L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Or"), + new EnumField( + 12L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Cast"), + new EnumField( + 13L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "InView"), + new EnumField( + 14L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "OfType"), + new EnumField( + 15L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "RelatedTo"), + new EnumField( + 16L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "BitwiseAnd"), + new EnumField( + 17L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "BitwiseOr") + }), + false)); + Tree redundancySupport = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:RedundancySupport"), + NodeIds.RedundancySupport, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField(0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "None"), + new EnumField(1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Cold"), + new EnumField(2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Warm"), + new EnumField(3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Hot"), + new EnumField( + 4L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Transparent"), + new EnumField( + 5L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "HotAndMirrored") + }), + false)); + Tree serverState = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:ServerState"), + NodeIds.ServerState, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Running"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Failed"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "NoConfiguration"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Suspended"), + new EnumField( + 4L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Shutdown"), + new EnumField(5L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Test"), + new EnumField( + 6L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "CommunicationFault"), + new EnumField( + 7L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Unknown") + }), + false)); + Tree exceptionDeviationFormat = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:ExceptionDeviationFormat"), + NodeIds.ExceptionDeviationFormat, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "AbsoluteValue"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "PercentOfValue"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "PercentOfRange"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "PercentOfEURange"), + new EnumField( + 4L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Unknown") + }), + false)); + Tree historyUpdateType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:HistoryUpdateType"), + NodeIds.HistoryUpdateType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Data was inserted."), + "Insert"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Data was replaced."), + "Replace"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Data was inserted or replaced."), + "Update"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Data was deleted."), + "Delete") + }), + false)); + Tree performUpdateType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:PerformUpdateType"), + NodeIds.PerformUpdateType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Data was inserted."), + "Insert"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Data was replaced."), + "Replace"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Data was inserted or replaced."), + "Update"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Data was deleted."), + "Remove") + }), + false)); + Tree openFileMode = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:OpenFileMode"), + NodeIds.OpenFileMode, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField(1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Read"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Write"), + new EnumField( + 4L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "EraseExisting"), + new EnumField( + 8L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Append") + }), + false)); + Tree axisScaleEnumeration = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:AxisScaleEnumeration"), + NodeIds.AxisScaleEnumeration, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Linear"), + new EnumField(1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Log"), + new EnumField(2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Ln") + }), + false)); + Tree trustListMasks = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:TrustListMasks"), + NodeIds.TrustListMasks, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "No fields are provided."), + "None"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The TrustedCertificates are provided."), + "TrustedCertificates"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The TrustedCrls are provided."), + "TrustedCrls"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The IssuerCertificates are provided."), + "IssuerCertificates"), + new EnumField( + 8L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The IssuerCrls are provided."), + "IssuerCrls"), + new EnumField( + 15L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "All fields are provided."), + "All") + }), + false)); + Tree pubSubState = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubState"), + NodeIds.PubSubState, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Disabled"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Paused"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Operational"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Error"), + new EnumField( + 4L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "PreOperational") + }), + false)); + Tree brokerTransportQualityOfService = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:BrokerTransportQualityOfService"), + NodeIds.BrokerTransportQualityOfService, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "NotSpecified"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "BestEffort"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "AtLeastOnce"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "AtMostOnce"), + new EnumField( + 4L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "ExactlyOnce") + }), + false)); + Tree identityCriteriaType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:IdentityCriteriaType"), + NodeIds.IdentityCriteriaType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "The rule specifies a UserName from a UserNameIdentityToken."), + "UserName"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "The rule specifies the Thumbprint of a user or CA Certificate."), + "Thumbprint"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The rule is a Role specified in an Access Token."), + "Role"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "The rule is a user group specified in the Access Token."), + "GroupId"), + new EnumField( + 5L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The rule specifies Anonymous UserIdentityToken."), + "Anonymous"), + new EnumField( + 6L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "The rule specifies any non Anonymous UserIdentityToken."), + "AuthenticatedUser"), + new EnumField( + 7L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The rule specifies the combination of an application identity and an Anonymous UserIdentityToken."), + "Application"), + new EnumField( + 8L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The rule specifies the X509 subject name of a user or CA Certificate."), + "X509Subject"), + new EnumField( + 9L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The rule specifies any trusted application that has been authenticated with a trusted ApplicationInstance Certificate."), + "TrustedApplication") + }), + false)); + Tree overrideValueHandling = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:OverrideValueHandling"), + NodeIds.OverrideValueHandling, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Disabled"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "LastUsableValue"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "OverrideValue") + }), + false)); + Tree actionState = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:ActionState"), + NodeIds.ActionState, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField(0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Idle"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Executing"), + new EnumField(2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Done") + }), + false)); + Tree chassisIdSubtype = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:ChassisIdSubtype"), + NodeIds.ChassisIdSubtype, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a chassis identifier based on the value of entPhysicalAlias object (defined in IETF RFC 2737) for a chassis component (i.e., an entPhysicalClass value of chassis(3))"), + "ChassisComponent"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a chassis identifier based on the value of ifAlias object (defined in IETF RFC 2863) for an interface on the containing chassis."), + "InterfaceAlias"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a chassis identifier based on the value of entPhysicalAlias object (defined in IETF RFC 2737) for a port or backplane component (i.e., entPhysicalClass has a value of port(10), or backplane(4)), within the containing chassis."), + "PortComponent"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a chassis identifier based on the value of a unicast source address (encoded in network byte order and IEEE 802.3 canonical bit order) of a port on the containing chassis as defined in IEEE Std 802-2014."), + "MacAddress"), + new EnumField( + 5L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a chassis identifier based on a network address associated with a particular chassis. The encoded address is actually composed of two fields. The first field is a single octet, representing the IANA AddressFamilyNumbers value for the specific address type, and the second field is the network address value."), + "NetworkAddress"), + new EnumField( + 6L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a chassis identifier based on the value of ifName object (defined in IETF RFC 2863) for an interface on the containing chassis."), + "InterfaceName"), + new EnumField( + 7L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a chassis identifier based on a locally defined value."), + "Local") + }), + false)); + Tree portIdSubtype = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:PortIdSubtype"), + NodeIds.PortIdSubtype, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a port identifier based on the ifAlias MIB object defined in IETF RFC 2863."), + "InterfaceAlias"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a port identifier based on the value of entPhysicalAlias (defined in IETF RFC 2737) for a port component (i.e., entPhysicalClass value of port(10) or backplane(4)), within the containing chassis."), + "PortComponent"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a port identifier based on a unicast source address (encoded in network byte order and IEEE 802.3 canonical bit order) which has been detected by the agent and associated with a particular port (IEEE Std 802-2014)."), + "MacAddress"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a port identifier based on a network address, detected by the agent and associated with a particular port."), + "NetworkAddress"), + new EnumField( + 5L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a port identifier based on the ifName MIB object, defined in IETF RFC 2863."), + "InterfaceName"), + new EnumField( + 6L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a port identifier based on the agent-local identifier of the circuit (defined in IETF RFC 3046), detected by the agent and associated with a particular port."), + "AgentCircuitId"), + new EnumField( + 7L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Represents a port identifier based on a value locally assigned."), + "Local") + }), + false)); + Tree manAddrIfSubtype = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:ManAddrIfSubtype"), + NodeIds.ManAddrIfSubtype, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Optional variable is not set."), + "None"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Interface is not known."), + "Unknown"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Interface based on the port-ref MIB object."), + "PortRef"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Interface based on the system port number."), + "SystemPortNumber") + }), + false)); + Tree diagnosticsLevel = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:DiagnosticsLevel"), + NodeIds.DiagnosticsLevel, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Basic"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Advanced"), + new EnumField(2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Info"), + new EnumField(3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Log"), + new EnumField(4L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Debug") + }), + false)); + Tree pubSubDiagnosticsCounterClassification = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:PubSubDiagnosticsCounterClassification"), + NodeIds.PubSubDiagnosticsCounterClassification, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Information"), + new EnumField(1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Error") + }), + false)); + Tree dataSetOrderingType = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:DataSetOrderingType"), + NodeIds.DataSetOrderingType, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Undefined"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "AscendingWriterId"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "AscendingWriterIdSingle") + }), + false)); + Tree duplex = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:Duplex"), + NodeIds.Duplex, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Full duplex."), + "Full"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Half duplex."), + "Half"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Link is currently disconnected or initializing."), + "Unknown") + }), + false)); + Tree interfaceAdminStatus = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:InterfaceAdminStatus"), + NodeIds.InterfaceAdminStatus, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Ready to pass packets."), + "Up"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "Not ready to pass packets and not in some test mode."), + "Down"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "In some test mode."), + "Testing") + }), + false)); + Tree interfaceOperStatus = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:InterfaceOperStatus"), + NodeIds.InterfaceOperStatus, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Ready to pass packets."), + "Up"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The interface does not pass any packets."), + "Down"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "In some test mode. No operational packets can be passed."), + "Testing"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Status cannot be determined for some reason."), + "Unknown"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Waiting for some external event."), + "Dormant"), + new EnumField( + 5L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Some component (typically hardware) is missing."), + "NotPresent"), + new EnumField( + 6L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Down due to state of lower-layer interface(s)."), + "LowerLayerDown") + }), + false)); + Tree negotiationStatus = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:NegotiationStatus"), + NodeIds.NegotiationStatus, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The auto-negotiation protocol is running and negotiation is currently in-progress."), + "InProgress"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "The auto-negotiation protocol has completed successfully."), + "Complete"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The auto-negotiation protocol has failed."), + "Failed"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The auto-negotiation status is not currently known, this could be because it is still negotiating or the protocol cannot run (e.g., if no medium is present)."), + "Unknown"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "No auto-negotiation is executed. The auto-negotiation function is either not supported on this interface or has not been enabled."), + "NoNegotiation") + }), + false)); + Tree tsnFailureCode = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:TsnFailureCode"), + NodeIds.TsnFailureCode, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "No failure"), + "NoFailure"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Insufficient bandwidth"), + "InsufficientBandwidth"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Insufficient bridge resources"), + "InsufficientResources"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Insufficient bandwidth for Traffic Class"), + "InsufficientTrafficClassBandwidth"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "StreamID in use by another Talker"), + "StreamIdInUse"), + new EnumField( + 5L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Stream destination address already in use"), + "StreamDestinationAddressInUse"), + new EnumField( + 6L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Stream pre-empted by higher rank"), + "StreamPreemptedByHigherRank"), + new EnumField( + 7L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Reported latency has changed"), + "LatencyHasChanged"), + new EnumField( + 8L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Egress port is not AVBCapable"), + "EgressPortNotAvbCapable"), + new EnumField( + 9L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Use a different destination address"), + "UseDifferentDestinationAddress"), + new EnumField( + 10L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Out of MSRP resources"), + "OutOfMsrpResources"), + new EnumField( + 11L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Out of MMRP resources"), + "OutOfMmrpResources"), + new EnumField( + 12L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Cannot store destination address"), + "CannotStoreDestinationAddress"), + new EnumField( + 13L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Requested priority is not an SR Class priority"), + "PriorityIsNotAnSrcClass"), + new EnumField( + 14L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "MaxFrameSize is too large for media"), + "MaxFrameSizeTooLarge"), + new EnumField( + 15L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "MaxFanInPorts limit has been reached"), + "MaxFanInPortsLimitReached"), + new EnumField( + 16L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Changes in FirstValue for a registered StreamID"), + "FirstValueChangedForStreamId"), + new EnumField( + 17L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "VLAN is blocked on this egress port (Registration Forbidden)"), + "VlanBlockedOnEgress"), + new EnumField( + 18L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "VLAN tagging is disabled on this egress port (untagged set)"), + "VlanTaggingDisabledOnEgress"), + new EnumField( + 19L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "SR class priority mismatch"), + "SrClassPriorityMismatch"), + new EnumField( + 20L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "Enhanced feature cannot be propagated to original Port"), + "FeatureNotPropagated"), + new EnumField( + 21L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "MaxLatency exceeded"), + "MaxLatencyExceeded"), + new EnumField( + 22L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Nearest Bridge cannot provide network identification for stream transformation"), + "BridgeDoesNotProvideNetworkId"), + new EnumField( + 23L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Stream transformation not supported"), + "StreamTransformNotSupported"), + new EnumField( + 24L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "Stream identification type not supported for stream transformation"), + "StreamIdTypeNotSupported"), + new EnumField( + 25L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "Enhanced feature cannot be supported without a CNC"), + "FeatureNotSupported") + }), + false)); + Tree tsnStreamState = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:TsnStreamState"), + NodeIds.TsnStreamState, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "The related TSN Stream is currently disabled."), + "Disabled"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The related TSN Stream is in the process of receiving configuration parameters from the TSN Control Layer."), + "Configuring"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The related TSN Stream has successfully received and applied the configuration from the TSN Control Layer. The related TSN Stream is not fully operational as long as local preconditions (e.g. synchronization state) are not valid."), + "Ready"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", + "The related TSN Stream object is configured and all other required preconditions (e.g. synchronization state) for sending / receiving data are valid."), + "Operational"), + new EnumField( + 4L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "The related TSN Stream object is in an error state."), + "Error") + }), + false)); + Tree tsnTalkerStatus = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:TsnTalkerStatus"), + NodeIds.TsnTalkerStatus, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "No Talker detected."), + "None"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Talker ready (configured)."), + "Ready"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Talker failed."), + "Failed") + }), + false)); + Tree tsnListenerStatus = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:TsnListenerStatus"), + NodeIds.TsnListenerStatus, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "No Listener detected."), + "None"), + new EnumField( + 1L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Listener ready (configured)."), + "Ready"), + new EnumField( + 2L, + LocalizedText.NULL_VALUE, + new LocalizedText( + "", "One or more Listeners ready, and one or more Listeners failed."), + "PartialFailed"), + new EnumField( + 3L, + LocalizedText.NULL_VALUE, + new LocalizedText("", "Listener failed."), + "Failed") + }), + false)); + Tree redundantServerMode = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:RedundantServerMode"), + NodeIds.RedundantServerMode, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, + LocalizedText.NULL_VALUE, + LocalizedText.NULL_VALUE, + "PrimaryWithBackup"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "PrimaryOnly"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "BackupReady"), + new EnumField( + 3L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "BackupNotReady") + }), + false)); + Tree conversionLimitEnum = + enumeration.addChild( + new ClientDataType( + QualifiedName.parse("0:ConversionLimitEnum"), + NodeIds.ConversionLimitEnum, + null, + null, + null, + new EnumDefinition( + new EnumField[] { + new EnumField( + 0L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "NoConversion"), + new EnumField( + 1L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Limited"), + new EnumField( + 2L, LocalizedText.NULL_VALUE, LocalizedText.NULL_VALUE, "Unlimited") + }), + false)); + } } From 1cd3299ff3b89a8edecc75db6f57688f162a1bd5 Mon Sep 17 00:00:00 2001 From: Kevin Herron Date: Thu, 11 Dec 2025 07:54:10 -0800 Subject: [PATCH 6/8] ~ formatting --- .../typetree/LazyClientDataTypeTreeSeed.java | 92 ++++++++++++++----- 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java index 7a5180540..2d274bac7 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTreeSeed.java @@ -9906,7 +9906,8 @@ private static void createEnumerationNodes(Tree enumeration) { LocalizedText.NULL_VALUE, new LocalizedText( "", - "The modelling rule defines a constraint and the BrowseName is not used in an instance of the type."), + "The modelling rule defines a constraint and the BrowseName is not" + + " used in an instance of the type."), "Constraint") }), false)); @@ -10553,21 +10554,25 @@ private static void createEnumerationNodes(Tree enumeration) { LocalizedText.NULL_VALUE, new LocalizedText( "", - "The rule specifies the combination of an application identity and an Anonymous UserIdentityToken."), + "The rule specifies the combination of an application identity and an" + + " Anonymous UserIdentityToken."), "Application"), new EnumField( 8L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "The rule specifies the X509 subject name of a user or CA Certificate."), + "The rule specifies the X509 subject name of a user or CA" + + " Certificate."), "X509Subject"), new EnumField( 9L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "The rule specifies any trusted application that has been authenticated with a trusted ApplicationInstance Certificate."), + "The rule specifies any trusted application that has been" + + " authenticated with a trusted ApplicationInstance" + + " Certificate."), "TrustedApplication") }), false)); @@ -10623,42 +10628,60 @@ private static void createEnumerationNodes(Tree enumeration) { LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a chassis identifier based on the value of entPhysicalAlias object (defined in IETF RFC 2737) for a chassis component (i.e., an entPhysicalClass value of chassis(3))"), + "Represents a chassis identifier based on the value of" + + " entPhysicalAlias object (defined in IETF RFC 2737) for a" + + " chassis component (i.e., an entPhysicalClass value of" + + " chassis(3))"), "ChassisComponent"), new EnumField( 2L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a chassis identifier based on the value of ifAlias object (defined in IETF RFC 2863) for an interface on the containing chassis."), + "Represents a chassis identifier based on the value of ifAlias object" + + " (defined in IETF RFC 2863) for an interface on the containing" + + " chassis."), "InterfaceAlias"), new EnumField( 3L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a chassis identifier based on the value of entPhysicalAlias object (defined in IETF RFC 2737) for a port or backplane component (i.e., entPhysicalClass has a value of port(10), or backplane(4)), within the containing chassis."), + "Represents a chassis identifier based on the value of" + + " entPhysicalAlias object (defined in IETF RFC 2737) for a port" + + " or backplane component (i.e., entPhysicalClass has a value of" + + " port(10), or backplane(4)), within the containing chassis."), "PortComponent"), new EnumField( 4L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a chassis identifier based on the value of a unicast source address (encoded in network byte order and IEEE 802.3 canonical bit order) of a port on the containing chassis as defined in IEEE Std 802-2014."), + "Represents a chassis identifier based on the value of a unicast" + + " source address (encoded in network byte order and IEEE 802.3" + + " canonical bit order) of a port on the containing chassis as" + + " defined in IEEE Std 802-2014."), "MacAddress"), new EnumField( 5L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a chassis identifier based on a network address associated with a particular chassis. The encoded address is actually composed of two fields. The first field is a single octet, representing the IANA AddressFamilyNumbers value for the specific address type, and the second field is the network address value."), + "Represents a chassis identifier based on a network address" + + " associated with a particular chassis. The encoded address is" + + " actually composed of two fields. The first field is a single" + + " octet, representing the IANA AddressFamilyNumbers value for" + + " the specific address type, and the second field is the" + + " network address value."), "NetworkAddress"), new EnumField( 6L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a chassis identifier based on the value of ifName object (defined in IETF RFC 2863) for an interface on the containing chassis."), + "Represents a chassis identifier based on the value of ifName object" + + " (defined in IETF RFC 2863) for an interface on the containing" + + " chassis."), "InterfaceName"), new EnumField( 7L, @@ -10684,42 +10707,53 @@ private static void createEnumerationNodes(Tree enumeration) { LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a port identifier based on the ifAlias MIB object defined in IETF RFC 2863."), + "Represents a port identifier based on the ifAlias MIB object defined" + + " in IETF RFC 2863."), "InterfaceAlias"), new EnumField( 2L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a port identifier based on the value of entPhysicalAlias (defined in IETF RFC 2737) for a port component (i.e., entPhysicalClass value of port(10) or backplane(4)), within the containing chassis."), + "Represents a port identifier based on the value of entPhysicalAlias" + + " (defined in IETF RFC 2737) for a port component (i.e.," + + " entPhysicalClass value of port(10) or backplane(4)), within" + + " the containing chassis."), "PortComponent"), new EnumField( 3L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a port identifier based on a unicast source address (encoded in network byte order and IEEE 802.3 canonical bit order) which has been detected by the agent and associated with a particular port (IEEE Std 802-2014)."), + "Represents a port identifier based on a unicast source address" + + " (encoded in network byte order and IEEE 802.3 canonical bit" + + " order) which has been detected by the agent and associated" + + " with a particular port (IEEE Std 802-2014)."), "MacAddress"), new EnumField( 4L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a port identifier based on a network address, detected by the agent and associated with a particular port."), + "Represents a port identifier based on a network address, detected by" + + " the agent and associated with a particular port."), "NetworkAddress"), new EnumField( 5L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a port identifier based on the ifName MIB object, defined in IETF RFC 2863."), + "Represents a port identifier based on the ifName MIB object, defined" + + " in IETF RFC 2863."), "InterfaceName"), new EnumField( 6L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "Represents a port identifier based on the agent-local identifier of the circuit (defined in IETF RFC 3046), detected by the agent and associated with a particular port."), + "Represents a port identifier based on the agent-local identifier of" + + " the circuit (defined in IETF RFC 3046), detected by the agent" + + " and associated with a particular port."), "AgentCircuitId"), new EnumField( 7L, @@ -10938,7 +10972,8 @@ private static void createEnumerationNodes(Tree enumeration) { LocalizedText.NULL_VALUE, new LocalizedText( "", - "The auto-negotiation protocol is running and negotiation is currently in-progress."), + "The auto-negotiation protocol is running and negotiation is" + + " currently in-progress."), "InProgress"), new EnumField( 1L, @@ -10956,14 +10991,18 @@ private static void createEnumerationNodes(Tree enumeration) { LocalizedText.NULL_VALUE, new LocalizedText( "", - "The auto-negotiation status is not currently known, this could be because it is still negotiating or the protocol cannot run (e.g., if no medium is present)."), + "The auto-negotiation status is not currently known, this could be" + + " because it is still negotiating or the protocol cannot run" + + " (e.g., if no medium is present)."), "Unknown"), new EnumField( 4L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "No auto-negotiation is executed. The auto-negotiation function is either not supported on this interface or has not been enabled."), + "No auto-negotiation is executed. The auto-negotiation function is" + + " either not supported on this interface or has not been" + + " enabled."), "NoNegotiation") }), false)); @@ -11095,7 +11134,8 @@ private static void createEnumerationNodes(Tree enumeration) { LocalizedText.NULL_VALUE, new LocalizedText( "", - "Nearest Bridge cannot provide network identification for stream transformation"), + "Nearest Bridge cannot provide network identification for stream" + + " transformation"), "BridgeDoesNotProvideNetworkId"), new EnumField( 23L, @@ -11137,21 +11177,27 @@ private static void createEnumerationNodes(Tree enumeration) { LocalizedText.NULL_VALUE, new LocalizedText( "", - "The related TSN Stream is in the process of receiving configuration parameters from the TSN Control Layer."), + "The related TSN Stream is in the process of receiving configuration" + + " parameters from the TSN Control Layer."), "Configuring"), new EnumField( 2L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "The related TSN Stream has successfully received and applied the configuration from the TSN Control Layer. The related TSN Stream is not fully operational as long as local preconditions (e.g. synchronization state) are not valid."), + "The related TSN Stream has successfully received and applied the" + + " configuration from the TSN Control Layer. The related TSN" + + " Stream is not fully operational as long as local" + + " preconditions (e.g. synchronization state) are not valid."), "Ready"), new EnumField( 3L, LocalizedText.NULL_VALUE, new LocalizedText( "", - "The related TSN Stream object is configured and all other required preconditions (e.g. synchronization state) for sending / receiving data are valid."), + "The related TSN Stream object is configured and all other required" + + " preconditions (e.g. synchronization state) for sending /" + + " receiving data are valid."), "Operational"), new EnumField( 4L, From fbe76828136963a5e04d6faae25af8574ee083b5 Mon Sep 17 00:00:00 2001 From: Kevin Herron Date: Thu, 11 Dec 2025 18:21:04 -0800 Subject: [PATCH 7/8] Remove LazyTypeTreeUtils, inline methods into LazyClientDataTypeTree - Move browseInverseUntilKnown and browseInverseParent into LazyClientDataTypeTree as private instance methods - Call ClientBrowseUtils directly instead of through LazyTypeTreeUtils --- .../typetree/LazyClientDataTypeTree.java | 69 ++++++++- .../client/typetree/LazyTypeTreeUtils.java | 135 ------------------ 2 files changed, 65 insertions(+), 139 deletions(-) delete mode 100644 opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTree.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTree.java index bea9c2f3a..c66b4b97e 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTree.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeTree.java @@ -36,6 +36,7 @@ import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult; import org.eclipse.milo.opcua.stack.core.types.structured.DataTypeDefinition; import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; @@ -239,8 +240,7 @@ private void resolvePath(NodeId dataTypeId) throws UaException { NamespaceTable nsTable = getNamespaceTable(); OperationLimits limits = client.getOperationLimits(); - List pathToResolve = - LazyTypeTreeUtils.browseInverseUntilKnown(client, dataTypeId, types.keySet(), nsTable); + List pathToResolve = browseInverseUntilKnown(dataTypeId, types.keySet(), nsTable); if (pathToResolve.isEmpty() || pathToResolve.size() < 2) { LOGGER.debug("Could not resolve path to known ancestor for DataType {}", dataTypeId); @@ -285,7 +285,7 @@ private List fetchDataTypeInfoBatch( } List values = - LazyTypeTreeUtils.readWithOperationLimits(client, readValueIds, limits); + ClientBrowseUtils.readWithOperationLimits(client, readValueIds, limits); // Browse encodings List> encodingRefs = browseEncodings(nodeIds, limits); @@ -332,6 +332,67 @@ private List fetchDataTypeInfoBatch( return result; } + /** + * Browse inverse HasSubtype references from {@code startId} until reaching a node that exists in + * {@code knownTypeIds}. + * + * @param startId the NodeId to start browsing from. + * @param knownTypeIds the set of NodeIds that are already known/loaded. + * @param namespaceTable the namespace table for converting ExpandedNodeIds. + * @return path from startId to known ancestor (inclusive), or empty list if unreachable. + */ + private List browseInverseUntilKnown( + NodeId startId, Set knownTypeIds, NamespaceTable namespaceTable) { + + List path = new ArrayList<>(); + NodeId current = startId; + + while (current != null && !knownTypeIds.contains(current)) { + path.add(current); + current = browseInverseParent(current, namespaceTable); + } + + if (current != null && knownTypeIds.contains(current)) { + path.add(current); + return path; + } + + return List.of(); + } + + /** + * Browse the inverse HasSubtype reference from {@code nodeId} to find its parent type. + * + * @param nodeId the NodeId to browse from. + * @param namespaceTable the namespace table for converting ExpandedNodeIds. + * @return the parent NodeId, or null if not found. + */ + private @Nullable NodeId browseInverseParent(NodeId nodeId, NamespaceTable namespaceTable) { + try { + BrowseDescription bd = + new BrowseDescription( + nodeId, + BrowseDirection.Inverse, + NodeIds.HasSubtype, + false, + uint(NodeClass.DataType.getValue()), + uint(BrowseResultMask.All.getValue())); + + BrowseResult result = client.browse(bd); + + if (result.getStatusCode().isGood() + && result.getReferences() != null + && result.getReferences().length > 0) { + + return result.getReferences()[0].getNodeId().toNodeId(namespaceTable).orElse(null); + } + } catch (UaException e) { + LOGGER.debug("Failed to browse inverse parent for {}: {}", nodeId, e.getMessage()); + } + + return null; + } + private List> browseEncodings( List dataTypeIds, OperationLimits limits) { @@ -348,7 +409,7 @@ private List> browseEncodings( uint(BrowseResultMask.All.getValue()))) .toList(); - return LazyTypeTreeUtils.browseWithOperationLimits(client, browseDescriptions, limits); + return ClientBrowseUtils.browseWithOperationLimits(client, browseDescriptions, limits); } private static QualifiedName extractBrowseName(DataValue value) { diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java deleted file mode 100644 index 35a93a66a..000000000 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyTypeTreeUtils.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2025 the Eclipse Milo Authors - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.milo.opcua.sdk.client.typetree; - -import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import org.eclipse.milo.opcua.sdk.client.OpcUaClient; -import org.eclipse.milo.opcua.sdk.client.OperationLimits; -import org.eclipse.milo.opcua.stack.core.NamespaceTable; -import org.eclipse.milo.opcua.stack.core.NodeIds; -import org.eclipse.milo.opcua.stack.core.UaException; -import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; -import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; -import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; -import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; -import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; -import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; -import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult; -import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId; -import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; -import org.jspecify.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** Shared utilities for lazy type tree implementations. */ -final class LazyTypeTreeUtils { - - private static final Logger LOGGER = LoggerFactory.getLogger(LazyTypeTreeUtils.class); - - private LazyTypeTreeUtils() {} - - /** - * Browse inverse HasSubtype references from {@code startId} until reaching a node that exists in - * {@code knownTypeIds}. - * - * @param client the OPC UA client to use for browsing. - * @param startId the NodeId to start browsing from. - * @param knownTypeIds the set of NodeIds that are already known/loaded. - * @param namespaceTable the namespace table for converting ExpandedNodeIds. - * @return path from startId to known ancestor (inclusive), or empty list if unreachable. - */ - static List browseInverseUntilKnown( - OpcUaClient client, NodeId startId, Set knownTypeIds, NamespaceTable namespaceTable) { - - List path = new ArrayList<>(); - NodeId current = startId; - - while (current != null && !knownTypeIds.contains(current)) { - path.add(current); - current = browseInverseParent(client, current, namespaceTable); - } - - if (current != null && knownTypeIds.contains(current)) { - path.add(current); - return path; - } - - return List.of(); - } - - /** - * Browse the inverse HasSubtype reference from {@code nodeId} to find its parent type. - * - * @param client the OPC UA client to use for browsing. - * @param nodeId the NodeId to browse from. - * @param namespaceTable the namespace table for converting ExpandedNodeIds. - * @return the parent NodeId, or null if not found. - */ - static @Nullable NodeId browseInverseParent( - OpcUaClient client, NodeId nodeId, NamespaceTable namespaceTable) { - - try { - BrowseDescription bd = - new BrowseDescription( - nodeId, - BrowseDirection.Inverse, - NodeIds.HasSubtype, - false, - uint(NodeClass.DataType.getValue()), - uint(BrowseResultMask.All.getValue())); - - BrowseResult result = client.browse(bd); - - if (result.getStatusCode().isGood() - && result.getReferences() != null - && result.getReferences().length > 0) { - - return result.getReferences()[0].getNodeId().toNodeId(namespaceTable).orElse(null); - } - } catch (UaException e) { - LOGGER.debug("Failed to browse inverse parent for {}: {}", nodeId, e.getMessage()); - } - - return null; - } - - /** - * Read values with operation limits, partitioning requests as necessary. - * - * @param client the OPC UA client. - * @param readValueIds the list of ReadValueIds to read. - * @param limits the operation limits from the server. - * @return the list of DataValues corresponding to the read requests. - */ - static List readWithOperationLimits( - OpcUaClient client, List readValueIds, OperationLimits limits) { - - return ClientBrowseUtils.readWithOperationLimits(client, readValueIds, limits); - } - - /** - * Browse with operation limits, partitioning requests as necessary. - * - * @param client the OPC UA client. - * @param browseDescriptions the list of BrowseDescriptions. - * @param limits the operation limits from the server. - * @return the list of reference description lists corresponding to each browse request. - */ - static List> browseWithOperationLimits( - OpcUaClient client, List browseDescriptions, OperationLimits limits) { - - return ClientBrowseUtils.browseWithOperationLimits(client, browseDescriptions, limits); - } -} From 9917c4149532e34375c3ee2380f707ce5ecd0876 Mon Sep 17 00:00:00 2001 From: Kevin Herron Date: Fri, 12 Dec 2025 07:32:20 -0800 Subject: [PATCH 8/8] Introduce DataTypeManagerFactory and LazyClientDataTypeManager - Add DataTypeManagerFactory interface to abstract DataTypeManager creation - Add LazyClientDataTypeManager that resolves codecs on demand - Move DefaultDataTypeManagerInitializer to DataTypeManagerFactory.DefaultInitializer - Replace setDataTypeManagerInitializer with setDynamicDataTypeManagerFactory - Update LegacyDataTypeManagerInitializer to implement Initializer interface - Update example to use new factory API --- .../LegacyDataTypeDictionaryExample.java | 8 +- .../dtd/LegacyDataTypeManagerInitializer.java | 13 +- .../milo/opcua/sdk/client/OpcUaClient.java | 172 +++------ .../typetree/DataTypeManagerFactory.java | 236 ++++++++++++ .../typetree/LazyClientDataTypeManager.java | 335 ++++++++++++++++++ 5 files changed, 629 insertions(+), 135 deletions(-) create mode 100644 opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeManagerFactory.java create mode 100644 opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeManager.java diff --git a/milo-examples/client-examples/src/main/java/org/eclipse/milo/examples/client/LegacyDataTypeDictionaryExample.java b/milo-examples/client-examples/src/main/java/org/eclipse/milo/examples/client/LegacyDataTypeDictionaryExample.java index df451d9f3..a22f18a21 100644 --- a/milo-examples/client-examples/src/main/java/org/eclipse/milo/examples/client/LegacyDataTypeDictionaryExample.java +++ b/milo-examples/client-examples/src/main/java/org/eclipse/milo/examples/client/LegacyDataTypeDictionaryExample.java @@ -12,8 +12,8 @@ import java.util.concurrent.CompletableFuture; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; -import org.eclipse.milo.opcua.sdk.client.OpcUaClient.DefaultDataTypeManagerInitializer; import org.eclipse.milo.opcua.sdk.client.dtd.LegacyDataTypeManagerInitializer; +import org.eclipse.milo.opcua.sdk.client.typetree.DataTypeManagerFactory; import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy; import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; import org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject; @@ -27,7 +27,8 @@ * specification. * *

This was the default (and only supported mechanism) in Milo 0.6.x and earlier. Milo 1.x now - * uses the DataTypeDefinition attribute instead via {@link DefaultDataTypeManagerInitializer}. + * uses the DataTypeDefinition attribute instead via {@link + * DataTypeManagerFactory.DefaultInitializer}. * *

Requires a server that still supports DataTypeDictionary, such as the Unified Automation C++ * demo server, which this example is configured for by default. @@ -42,7 +43,8 @@ public static void main(String[] args) throws Exception { @Override public void run(OpcUaClient client, CompletableFuture future) throws Exception { - client.setDataTypeManagerInitializer(new LegacyDataTypeManagerInitializer(client)); + client.setDynamicDataTypeManagerFactory( + DataTypeManagerFactory.eager(new LegacyDataTypeManagerInitializer(client))); client.connect(); diff --git a/opc-ua-sdk/dtd-reader/src/main/java/org/eclipse/milo/opcua/sdk/client/dtd/LegacyDataTypeManagerInitializer.java b/opc-ua-sdk/dtd-reader/src/main/java/org/eclipse/milo/opcua/sdk/client/dtd/LegacyDataTypeManagerInitializer.java index 238c15c09..3786e7581 100644 --- a/opc-ua-sdk/dtd-reader/src/main/java/org/eclipse/milo/opcua/sdk/client/dtd/LegacyDataTypeManagerInitializer.java +++ b/opc-ua-sdk/dtd-reader/src/main/java/org/eclipse/milo/opcua/sdk/client/dtd/LegacyDataTypeManagerInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 the Eclipse Milo Authors + * Copyright (c) 2025 the Eclipse Milo Authors * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -12,6 +12,7 @@ import java.util.List; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.typetree.DataTypeManagerFactory; import org.eclipse.milo.opcua.sdk.core.dtd.generic.StructCodec; import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; import org.eclipse.milo.opcua.stack.core.NamespaceTable; @@ -19,7 +20,15 @@ import org.eclipse.milo.opcua.stack.core.types.DataTypeDictionary; import org.eclipse.milo.opcua.stack.core.types.DataTypeManager; -public class LegacyDataTypeManagerInitializer implements OpcUaClient.DataTypeManagerInitializer { +/** + * A {@link DataTypeManagerFactory.Initializer} that reads legacy DataTypeDictionary information + * from the server and registers codecs based on that. + * + *

This is for servers that support the legacy (OPC UA <= 1.03) DataTypeDictionary mechanism. + * + * @see DataTypeManagerFactory#eager(DataTypeManagerFactory.Initializer) + */ +public class LegacyDataTypeManagerInitializer implements DataTypeManagerFactory.Initializer { private final OpcUaClient client; private final BinaryCodecFactory codecFactory; diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java index 062db7e53..e61b20ee9 100644 --- a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java @@ -38,18 +38,17 @@ import org.eclipse.milo.opcua.sdk.client.session.SessionFsmFactory; import org.eclipse.milo.opcua.sdk.client.subscriptions.OpcUaSubscription; import org.eclipse.milo.opcua.sdk.client.subscriptions.PublishingManager; +import org.eclipse.milo.opcua.sdk.client.typetree.DataTypeManagerFactory; import org.eclipse.milo.opcua.sdk.client.typetree.DataTypeTreeBuilder; import org.eclipse.milo.opcua.sdk.client.typetree.DataTypeTreeFactory; +import org.eclipse.milo.opcua.sdk.client.typetree.LazyClientDataTypeManager; import org.eclipse.milo.opcua.sdk.client.typetree.ObjectTypeTreeBuilder; import org.eclipse.milo.opcua.sdk.client.typetree.VariableTypeTreeBuilder; -import org.eclipse.milo.opcua.sdk.core.types.codec.DynamicCodecFactory; -import org.eclipse.milo.opcua.sdk.core.typetree.DataType; import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; import org.eclipse.milo.opcua.sdk.core.typetree.ObjectTypeTree; import org.eclipse.milo.opcua.sdk.core.typetree.VariableTypeTree; import org.eclipse.milo.opcua.stack.core.*; import org.eclipse.milo.opcua.stack.core.channel.EncodingLimits; -import org.eclipse.milo.opcua.stack.core.encoding.DataTypeCodec; import org.eclipse.milo.opcua.stack.core.encoding.DefaultEncodingManager; import org.eclipse.milo.opcua.stack.core.encoding.EncodingContext; import org.eclipse.milo.opcua.stack.core.encoding.EncodingManager; @@ -140,7 +139,6 @@ import org.eclipse.milo.opcua.stack.core.types.structured.SetPublishingModeResponse; import org.eclipse.milo.opcua.stack.core.types.structured.SetTriggeringRequest; import org.eclipse.milo.opcua.stack.core.types.structured.SetTriggeringResponse; -import org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition; import org.eclipse.milo.opcua.stack.core.types.structured.SubscriptionAcknowledgement; import org.eclipse.milo.opcua.stack.core.types.structured.TransferSubscriptionsRequest; import org.eclipse.milo.opcua.stack.core.types.structured.TransferSubscriptionsResponse; @@ -159,7 +157,6 @@ import org.eclipse.milo.opcua.stack.core.util.LongSequence; import org.eclipse.milo.opcua.stack.core.util.ManifestUtil; import org.eclipse.milo.opcua.stack.core.util.Namespaces; -import org.eclipse.milo.opcua.stack.core.util.Tree; import org.eclipse.milo.opcua.stack.core.util.Unit; import org.eclipse.milo.opcua.stack.transport.client.ClientApplicationContext; import org.eclipse.milo.opcua.stack.transport.client.OpcClientTransport; @@ -330,11 +327,10 @@ public static OpcUaClient create( private final VariableTypeManager variableTypeManager = new VariableTypeManager(); - private DataTypeManagerInitializer dataTypeManagerInitializer = - new DefaultDataTypeManagerInitializer(); - private DataTypeTreeFactory dataTypeTreeFactory = DataTypeTreeFactory.eager(); + private DataTypeManagerFactory dynamicDataTypeManagerFactory = DataTypeManagerFactory.eager(); + private final EncodingManager encodingManager = DefaultEncodingManager.createAndInitialize(); private final DataTypeManager staticDataTypeManager = @@ -645,21 +641,22 @@ public DataTypeManager getStaticDataTypeManager() { /** * Get the client's "dynamic" {@link DataTypeManager}. * - *

This {@link DataTypeManager} is for dynamic codecs that were created by reading datatype - * information from the server at runtime. + *

This {@link DataTypeManager} is for dynamic codecs created by reading datatype information + * from the server at runtime. + * + *

By default, the client uses {@link DataTypeManagerFactory#eager()}, which creates a {@link + * DefaultDataTypeManager} with all known types eagerly registered. + * + *

Use {@link #setDynamicDataTypeManagerFactory(DataTypeManagerFactory)} with {@link + * DataTypeManagerFactory#lazy()} to configure the client with a {@link LazyClientDataTypeManager} + * that resolves codecs on demand. * * @return the client's dynamic {@link DataTypeManager}. - * @see #setDataTypeManagerInitializer(DataTypeManagerInitializer) + * @see #setDynamicDataTypeManagerFactory(DataTypeManagerFactory) */ public DataTypeManager getDynamicDataTypeManager() throws UaException { return dynamicDataTypeManager.getOrThrow( - () -> { - DataTypeManager dataTypeManager = - DefaultDataTypeManager.createAndInitialize(getNamespaceTable()); - dataTypeManagerInitializer.initialize( - getNamespaceTable(), getDataTypeTree(), dataTypeManager); - return dataTypeManager; - }); + () -> dynamicDataTypeManagerFactory.create(this, getNamespaceTable(), getDataTypeTree())); } /** @@ -1081,23 +1078,6 @@ public RequestHeader newRequestHeader(NodeId authToken, UInteger requestTimeout) null); } - /** - * Set the {@link DataTypeManagerInitializer} that called to register codecs with the client's - * dynamic {@link DataTypeManager}. - * - *

This resets the client's dynamic {@link DataTypeManager} and {@link EncodingContext}. They - * will be built or rebuilt the next time they are accessed. - * - * @param dataTypeManagerInitializer the {@link DataTypeManagerInitializer} to set. - * @see #getDynamicDataTypeManager() - */ - public void setDataTypeManagerInitializer(DataTypeManagerInitializer dataTypeManagerInitializer) { - this.dataTypeManagerInitializer = dataTypeManagerInitializer; - - dynamicDataTypeManager.reset(); - dynamicEncodingContext.reset(); - } - /** * Set the {@link DataTypeTreeFactory} used to create the {@link DataTypeTree}. * @@ -1122,6 +1102,33 @@ public void setDataTypeTreeFactory(DataTypeTreeFactory dataTypeTreeFactory) { dataTypeTree.reset(); } + /** + * Set the {@link DataTypeManagerFactory} used to create the dynamic {@link DataTypeManager}. + * + *

By default, the client uses {@link DataTypeManagerFactory#eager()}, which creates a {@link + * DefaultDataTypeManager} with all known types eagerly registered. + * + *

Use {@link DataTypeManagerFactory#lazy()} to configure the client with a {@link + * LazyClientDataTypeManager} that resolves codecs on demand. This pairs well with {@link + * DataTypeTreeFactory#lazy()} for a fully lazy type resolution system. + * + *

This resets the client's cached {@link DataTypeManager}. It will be created again the next + * time it is accessed. + * + * @param dynamicDataTypeManagerFactory the {@link DataTypeManagerFactory} to set. + * @see #getDynamicDataTypeManager() + * @see DataTypeManagerFactory#eager() + * @see DataTypeManagerFactory#lazy() + */ + public void setDynamicDataTypeManagerFactory( + DataTypeManagerFactory dynamicDataTypeManagerFactory) { + + this.dynamicDataTypeManagerFactory = dynamicDataTypeManagerFactory; + + dynamicDataTypeManager.reset(); + dynamicEncodingContext.reset(); + } + // region Attribute Services /** @@ -3014,99 +3021,4 @@ public void removeSessionInitializer(SessionInitializer initializer) { sessionFsm.removeInitializer(initializer); logger.debug("Removed SessionInitializer: {}", initializer); } - - public interface DataTypeManagerInitializer { - - /** - * Register codecs for custom data types. - * - * @param namespaceTable the Server's {@link NamespaceTable}. - * @param dataTypeTree the Client's {@link DataTypeTree}. - * @param dataTypeManager the {@link DataTypeManager} to register codecs with. - */ - void initialize( - NamespaceTable namespaceTable, DataTypeTree dataTypeTree, DataTypeManager dataTypeManager) - throws UaException; - } - - public static class DefaultDataTypeManagerInitializer implements DataTypeManagerInitializer { - - private final CodecFactory codecFactory; - - /** - * Create a new {@link DefaultDataTypeManagerInitializer} that uses {@link DynamicCodecFactory}. - */ - public DefaultDataTypeManagerInitializer() { - this(DynamicCodecFactory::create); - } - - /** - * Create a new {@link DefaultDataTypeManagerInitializer} using the provided {@link - * CodecFactory}. - * - * @param codecFactory the {@link CodecFactory} to use when creating {@link DataTypeCodec}s. - */ - public DefaultDataTypeManagerInitializer(CodecFactory codecFactory) { - this.codecFactory = codecFactory; - } - - @Override - public void initialize( - NamespaceTable namespaceTable, DataTypeTree dataTypeTree, DataTypeManager dataTypeManager) { - - Tree structureNode = dataTypeTree.getTreeNode(NodeIds.Structure); - - if (structureNode != null) { - structureNode.traverse( - dataType -> { - if (dataType.getDataTypeDefinition() != null) { - LoggerFactory.getLogger(getClass()) - .debug( - "Registering type: name={}, dataTypeId={}", - dataType.getBrowseName(), - dataType.getNodeId()); - - String namespaceUri = namespaceTable.get(dataType.getNodeId().getNamespaceIndex()); - - if (namespaceUri == null) { - throw new UaRuntimeException( - StatusCodes.Bad_UnexpectedError, - "DataType namespace not registered: " - + dataType.getNodeId().toParseableString()); - } - - dataTypeManager.registerType( - dataType.getNodeId(), - codecFactory.create(dataType, dataTypeTree), - getBinaryEncodingId(dataType), - dataType.getXmlEncodingId(), - dataType.getJsonEncodingId()); - } - }); - } else { - LoggerFactory.getLogger(getClass()) - .warn( - "Structure (i=22) not found in the DataType tree; is the Server's DataType" - + " hierarchy sane?"); - } - } - - private static NodeId getBinaryEncodingId(DataType dataType) { - NodeId binaryEncodingId = dataType.getBinaryEncodingId(); - - if (binaryEncodingId == null - && dataType.getDataTypeDefinition() instanceof StructureDefinition definition) { - - // Hail mary work around for non-compliant Servers that don't have encoding nodes - // in their address space. The DefaultEncodingId in a StructureDefinition shall - // always be the Default Binary encoding, so let's see if the Server at least set - // this correctly. - // See https://reference.opcfoundation.org/Core/Part3/v105/docs/8.48 - - binaryEncodingId = definition.getDefaultEncodingId(); - } - - return binaryEncodingId; - } - } } diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeManagerFactory.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeManagerFactory.java new file mode 100644 index 000000000..df9919fcf --- /dev/null +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/DataTypeManagerFactory.java @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import org.eclipse.milo.opcua.sdk.client.CodecFactory; +import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.core.types.codec.DynamicCodecFactory; +import org.eclipse.milo.opcua.sdk.core.typetree.DataType; +import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; +import org.eclipse.milo.opcua.stack.core.NamespaceTable; +import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.eclipse.milo.opcua.stack.core.StatusCodes; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.UaRuntimeException; +import org.eclipse.milo.opcua.stack.core.types.DataTypeManager; +import org.eclipse.milo.opcua.stack.core.types.DefaultDataTypeManager; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition; +import org.eclipse.milo.opcua.stack.core.util.Tree; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A factory that creates a {@link DataTypeManager} for a given {@link OpcUaClient}. + * + *

Implementations can create different types of DataTypeManagers, such as: + * + *

+ * + * @see DefaultDataTypeManager + * @see LazyClientDataTypeManager + */ +@FunctionalInterface +public interface DataTypeManagerFactory { + + /** + * Creates a {@link DataTypeManager} for the given client. + * + * @param client the {@link OpcUaClient} to create a DataTypeManager for. + * @param namespaceTable the server's {@link NamespaceTable}. + * @param dataTypeTree the {@link DataTypeTree} to use for type resolution. + * @return a new {@link DataTypeManager} instance. + * @throws UaException if an error occurs while creating the manager. + */ + DataTypeManager create( + OpcUaClient client, NamespaceTable namespaceTable, DataTypeTree dataTypeTree) + throws UaException; + + /** + * Returns the default factory that eagerly initializes a {@link DataTypeManager} using {@link + * DefaultDataTypeManager#createAndInitialize(NamespaceTable)}. + * + *

The eager factory creates and initializes all codecs for known structure types in the {@link + * DataTypeTree} at creation time, using {@link DynamicCodecFactory} and the default initializer. + * + * @return the default {@link DataTypeManagerFactory}. + */ + static DataTypeManagerFactory eager() { + return eager(new DefaultInitializer()); + } + + /** + * Returns an eager factory that uses a {@link DefaultInitializer} with the provided {@link + * CodecFactory}. + * + *

The eager factory creates and initializes all codecs for known structure types in the {@link + * DataTypeTree} at creation time. + * + * @param codecFactory the {@link CodecFactory} to use when creating codecs. + * @return a {@link DataTypeManagerFactory} that eagerly initializes types. + */ + static DataTypeManagerFactory eager(CodecFactory codecFactory) { + return eager(new DefaultInitializer(codecFactory)); + } + + /** + * Returns an eager factory that uses the provided {@link Initializer}. + * + *

The eager factory creates and initializes all codecs for known structure types in the {@link + * DataTypeTree} at creation time. + * + * @param initializer the {@link Initializer} to use for registering codecs. + * @return a {@link DataTypeManagerFactory} that eagerly initializes types. + */ + static DataTypeManagerFactory eager(Initializer initializer) { + return (client, namespaceTable, dataTypeTree) -> { + DataTypeManager dataTypeManager = DefaultDataTypeManager.createAndInitialize(namespaceTable); + initializer.initialize(namespaceTable, dataTypeTree, dataTypeManager); + return dataTypeManager; + }; + } + + /** + * Returns a factory that creates a {@link LazyClientDataTypeManager}. + * + *

The lazy factory creates a manager that resolves codecs on demand when they are first + * requested, rather than eagerly registering all codecs at creation time. Uses {@link + * DynamicCodecFactory} by default. + * + * @return a {@link DataTypeManagerFactory} that creates lazy-loading managers. + */ + static DataTypeManagerFactory lazy() { + return lazy(DynamicCodecFactory::create); + } + + /** + * Returns a factory that creates a {@link LazyClientDataTypeManager} with a custom {@link + * CodecFactory}. + * + *

The lazy factory creates a manager that resolves codecs on demand when they are first + * requested, rather than eagerly registering all codecs at creation time. + * + * @param codecFactory the {@link CodecFactory} to use when creating codecs on demand. + * @return a {@link DataTypeManagerFactory} that creates lazy-loading managers. + */ + static DataTypeManagerFactory lazy(CodecFactory codecFactory) { + return (client, namespaceTable, dataTypeTree) -> + new LazyClientDataTypeManager(client, namespaceTable, dataTypeTree, codecFactory::create); + } + + /** + * An initializer that registers codecs for custom data types with a {@link DataTypeManager}. + * + *

Implementations traverse the {@link DataTypeTree} and register codecs for structure types. + */ + interface Initializer { + + /** + * Register codecs for custom data types. + * + * @param namespaceTable the Server's {@link NamespaceTable}. + * @param dataTypeTree the Client's {@link DataTypeTree}. + * @param dataTypeManager the {@link DataTypeManager} to register codecs with. + * @throws UaException if an error occurs during initialization. + */ + void initialize( + NamespaceTable namespaceTable, DataTypeTree dataTypeTree, DataTypeManager dataTypeManager) + throws UaException; + } + + /** + * The default {@link Initializer} implementation that traverses the DataType hierarchy and + * registers codecs for all structure types with a {@link DataTypeManager}. + * + *

Uses {@link DynamicCodecFactory} by default, but can be configured with a custom {@link + * CodecFactory}. + */ + class DefaultInitializer implements Initializer { + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultInitializer.class); + + private final CodecFactory codecFactory; + + /** Create a new {@link DefaultInitializer} that uses {@link DynamicCodecFactory}. */ + public DefaultInitializer() { + this(DynamicCodecFactory::create); + } + + /** + * Create a new {@link DefaultInitializer} using the provided {@link CodecFactory}. + * + * @param codecFactory the {@link CodecFactory} to use when creating codecs. + */ + public DefaultInitializer(CodecFactory codecFactory) { + this.codecFactory = codecFactory; + } + + @Override + public void initialize( + NamespaceTable namespaceTable, DataTypeTree dataTypeTree, DataTypeManager dataTypeManager) { + + Tree structureNode = dataTypeTree.getTreeNode(NodeIds.Structure); + + if (structureNode != null) { + structureNode.traverse( + dataType -> { + if (dataType.getDataTypeDefinition() != null) { + LOGGER.debug( + "Registering type: name={}, dataTypeId={}", + dataType.getBrowseName(), + dataType.getNodeId()); + + String namespaceUri = namespaceTable.get(dataType.getNodeId().getNamespaceIndex()); + + if (namespaceUri == null) { + throw new UaRuntimeException( + StatusCodes.Bad_UnexpectedError, + "DataType namespace not registered: " + + dataType.getNodeId().toParseableString()); + } + + dataTypeManager.registerType( + dataType.getNodeId(), + codecFactory.create(dataType, dataTypeTree), + getBinaryEncodingId(dataType), + dataType.getXmlEncodingId(), + dataType.getJsonEncodingId()); + } + }); + } else { + LOGGER.warn( + "Structure (i=22) not found in the DataType tree; is the Server's DataType" + + " hierarchy sane?"); + } + } + + private static NodeId getBinaryEncodingId(DataType dataType) { + NodeId binaryEncodingId = dataType.getBinaryEncodingId(); + + if (binaryEncodingId == null + && dataType.getDataTypeDefinition() instanceof StructureDefinition definition) { + + // Hail mary work around for non-compliant Servers that don't have encoding nodes + // in their address space. The DefaultEncodingId in a StructureDefinition shall + // always be the Default Binary encoding, so let's see if the Server at least set + // this correctly. + // See https://reference.opcfoundation.org/Core/Part3/v105/docs/8.48 + + binaryEncodingId = definition.getDefaultEncodingId(); + } + + return binaryEncodingId; + } + } +} diff --git a/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeManager.java b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeManager.java new file mode 100644 index 000000000..e8a863e2a --- /dev/null +++ b/opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/typetree/LazyClientDataTypeManager.java @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2025 the Eclipse Milo Authors + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.eclipse.milo.opcua.sdk.client.typetree; + +import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.BiFunction; +import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.core.types.codec.DynamicCodecFactory; +import org.eclipse.milo.opcua.sdk.core.typetree.DataType; +import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree; +import org.eclipse.milo.opcua.stack.core.NamespaceTable; +import org.eclipse.milo.opcua.stack.core.NodeIds; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.encoding.DataTypeCodec; +import org.eclipse.milo.opcua.stack.core.types.DataTypeInitializer; +import org.eclipse.milo.opcua.stack.core.types.DefaultDataTypeManager; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; +import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; +import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult; +import org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition; +import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A lazy-loading {@link org.eclipse.milo.opcua.stack.core.types.DataTypeManager} that resolves + * codecs on demand. + * + *

This implementation works in conjunction with {@link LazyClientDataTypeTree} to provide fully + * lazy resolution of both type information and codecs. When a codec is requested for a type that + * isn't already registered, this manager: + * + *

    + *
  1. Uses the {@link DataTypeTree} to resolve the type (which triggers lazy browsing if using + * {@link LazyClientDataTypeTree}) + *
  2. Creates a codec using {@link DynamicCodecFactory} + *
  3. Registers the codec for future use + *
+ * + *

Namespace 0 Types

+ * + *

Built-in types from namespace 0 are pre-initialized via {@link DataTypeInitializer} in the + * constructor. Lazy resolution is only triggered for non-namespace-0 types. + * + *

Thread Safety

+ * + *

This implementation is thread-safe. All read operations first check the parent class under no + * lock, then acquire a write lock only when resolution is needed. Resolution attempts are tracked + * to avoid repeated failures. + * + *

Resolution Behavior

+ * + *

Resolution errors (e.g., network failures, non-existent types) do not cause exceptions. + * Instead, {@code null} is returned. Once a resolution attempt has failed, it will not be retried + * unless {@link #clearFailedResolutions()} is called. + */ +public class LazyClientDataTypeManager extends DefaultDataTypeManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(LazyClientDataTypeManager.class); + + private final OpcUaClient client; + private final DataTypeTree dataTypeTree; + private final BiFunction codecFactory; + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private final Set attemptedResolution = ConcurrentHashMap.newKeySet(); + + /** + * Create a new {@link LazyClientDataTypeManager}. + * + * @param client a connected {@link OpcUaClient}. + * @param namespaceTable the server's {@link NamespaceTable}. + * @param dataTypeTree the {@link DataTypeTree} to use for type resolution. This is typically a + * {@link LazyClientDataTypeTree} for full lazy behavior. + */ + public LazyClientDataTypeManager( + OpcUaClient client, NamespaceTable namespaceTable, DataTypeTree dataTypeTree) { + + this(client, namespaceTable, dataTypeTree, DynamicCodecFactory::create); + } + + /** + * Create a new {@link LazyClientDataTypeManager} with a custom codec factory. + * + * @param client a connected {@link OpcUaClient}. + * @param namespaceTable the server's {@link NamespaceTable}. + * @param dataTypeTree the {@link DataTypeTree} to use for type resolution. + * @param codecFactory a factory function that creates {@link DataTypeCodec}s from {@link + * DataType} and {@link DataTypeTree}. + */ + public LazyClientDataTypeManager( + OpcUaClient client, + NamespaceTable namespaceTable, + DataTypeTree dataTypeTree, + BiFunction codecFactory) { + + this.client = client; + this.dataTypeTree = dataTypeTree; + this.codecFactory = codecFactory; + + // Pre-initialize namespace 0 codecs + new DataTypeInitializer().initialize(namespaceTable, this); + } + + /** + * Clear failed resolution attempts, allowing retry. + * + *

When a codec resolution fails (e.g., due to network errors or non-existent types), the + * failure is recorded to avoid repeated failed attempts. This method clears those records, + * allowing later queries for those types to attempt resolution again. + * + *

This is useful after transient network issues have been resolved or when the server's type + * system may have changed. + */ + public void clearFailedResolutions() { + lock.writeLock().lock(); + try { + attemptedResolution.clear(); + } finally { + lock.writeLock().unlock(); + } + } + + @Override + public @Nullable DataTypeCodec getCodec(NodeId id) { + // Fast path: check if already registered + DataTypeCodec codec = super.getCodec(id); + if (codec != null) { + return codec; + } + + // Never lazily resolve namespace 0 types; they should already be initialized + if (id.getNamespaceIndex().intValue() == 0) { + return null; + } + + // Skip if we've already tried and failed + if (attemptedResolution.contains(id)) { + return null; + } + + // Slow path: attempt lazy resolution under write lock + lock.writeLock().lock(); + try { + // Re-check in case another thread just resolved it + codec = super.getCodec(id); + if (codec != null) { + return codec; + } + + // Mark as attempted before trying resolution + if (!attemptedResolution.add(id)) { + return null; + } + + return resolveAndRegisterCodec(id); + } finally { + lock.writeLock().unlock(); + } + } + + @Override + public @Nullable NodeId getBinaryEncodingId(NodeId dataTypeId) { + ensureRegisteredForDataType(dataTypeId); + return super.getBinaryEncodingId(dataTypeId); + } + + @Override + public @Nullable NodeId getXmlEncodingId(NodeId dataTypeId) { + ensureRegisteredForDataType(dataTypeId); + return super.getXmlEncodingId(dataTypeId); + } + + @Override + public @Nullable NodeId getJsonEncodingId(NodeId dataTypeId) { + ensureRegisteredForDataType(dataTypeId); + return super.getJsonEncodingId(dataTypeId); + } + + private void ensureRegisteredForDataType(NodeId dataTypeId) { + // Skip namespace 0 types + if (dataTypeId.getNamespaceIndex().intValue() == 0) { + return; + } + + // Fast path: already registered + if (super.getBinaryEncodingId(dataTypeId) != null + || super.getXmlEncodingId(dataTypeId) != null + || super.getJsonEncodingId(dataTypeId) != null) { + return; + } + + // Skip if already attempted + if (attemptedResolution.contains(dataTypeId)) { + return; + } + + // Slow path: attempt resolution under write lock + lock.writeLock().lock(); + try { + // Re-check after acquiring lock + if (attemptedResolution.contains(dataTypeId)) { + return; + } + + attemptedResolution.add(dataTypeId); + resolveAndRegisterCodecFromDataTypeId(dataTypeId); + } finally { + lock.writeLock().unlock(); + } + } + + private @Nullable DataTypeCodec resolveAndRegisterCodec(NodeId id) { + try { + // First, try to treat `id` as a DataType NodeId + DataType dataType = dataTypeTree.getDataType(id); + + if (dataType == null || dataType.getDataTypeDefinition() == null) { + // Otherwise, treat `id` as an encoding NodeId and discover its DataType + NodeId dataTypeId = browseDataTypeIdForEncoding(id); + if (dataTypeId == null) { + LOGGER.debug("No DataType found for encoding {}", id); + return null; + } + + dataType = dataTypeTree.getDataType(dataTypeId); + } + + if (dataType == null || dataType.getDataTypeDefinition() == null) { + LOGGER.debug("No DataTypeDefinition available for {}", id); + return null; + } + + // Create the codec and register it + return createAndRegisterCodec(dataType); + } catch (Exception e) { + LOGGER.debug("Error resolving codec for {}: {}", id, e.getMessage()); + return null; + } + } + + private void resolveAndRegisterCodecFromDataTypeId(NodeId dataTypeId) { + try { + DataType dataType = dataTypeTree.getDataType(dataTypeId); + + if (dataType != null && dataType.getDataTypeDefinition() != null) { + createAndRegisterCodec(dataType); + } + } catch (Exception e) { + LOGGER.debug("Error resolving codec for DataType {}: {}", dataTypeId, e.getMessage()); + } + } + + private @Nullable DataTypeCodec createAndRegisterCodec(DataType dataType) { + NodeId binaryEncodingId = getBinaryEncodingIdFromDataType(dataType); + + DataTypeCodec codec = codecFactory.apply(dataType, dataTypeTree); + + super.registerType( + dataType.getNodeId(), + codec, + binaryEncodingId, + dataType.getXmlEncodingId(), + dataType.getJsonEncodingId()); + + LOGGER.debug( + "Lazily registered codec for: name={}, dataTypeId={}", + dataType.getBrowseName(), + dataType.getNodeId()); + + return codec; + } + + private static @Nullable NodeId getBinaryEncodingIdFromDataType(DataType dataType) { + NodeId binaryEncodingId = dataType.getBinaryEncodingId(); + + if (binaryEncodingId == null + && dataType.getDataTypeDefinition() instanceof StructureDefinition definition) { + + // Workaround for non-compliant servers that don't have encoding nodes. + // The DefaultEncodingId in a StructureDefinition shall always be the Default Binary + // encoding. + // See https://reference.opcfoundation.org/Core/Part3/v105/docs/8.48 + binaryEncodingId = definition.getDefaultEncodingId(); + } + + return binaryEncodingId; + } + + private @Nullable NodeId browseDataTypeIdForEncoding(NodeId encodingId) { + try { + BrowseDescription bd = + new BrowseDescription( + encodingId, + BrowseDirection.Inverse, + NodeIds.HasEncoding, + false, + uint(NodeClass.DataType.getValue()), + uint(BrowseResultMask.All.getValue())); + + BrowseResult result = client.browse(bd); + + if (result.getStatusCode().isGood() + && result.getReferences() != null + && result.getReferences().length > 0) { + + return result + .getReferences()[0] + .getNodeId() + .toNodeId(client.getNamespaceTable()) + .orElse(null); + } + + LOGGER.debug("No DataType found via inverse HasEncoding for encoding {}", encodingId); + } catch (UaException e) { + LOGGER.debug("Failed to browse DataType for encoding {}: {}", encodingId, e.getMessage()); + } + + return null; + } +}