Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -27,7 +27,8 @@
* specification.
*
* <p>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}.
*
* <p>Requires a server that still supports DataTypeDictionary, such as the Unified Automation C++
* demo server, which this example is configured for by default.
Expand All @@ -42,7 +43,8 @@ public static void main(String[] args) throws Exception {

@Override
public void run(OpcUaClient client, CompletableFuture<OpcUaClient> future) throws Exception {
client.setDataTypeManagerInitializer(new LegacyDataTypeManagerInitializer(client));
client.setDynamicDataTypeManagerFactory(
DataTypeManagerFactory.eager(new LegacyDataTypeManagerInitializer(client)));

client.connect();

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -12,14 +12,23 @@

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;
import org.eclipse.milo.opcua.stack.core.UaException;
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.
*
* <p>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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading