# How to preload nodes in the server OPC-UA address space?

**URL:** <https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652>\
**Category:** 3rd Party Modules\
**Created:** [February 4, 2015, 4:43pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652 "2015-02-04T16:43:24Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Amarth](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarth/32/3313_2.png) [@Amarth](https://forum.inductiveautomation.com/u/Amarth)\
**Post date:** [February 4, 2015, 4:43pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/1 "2015-02-04T16:43:24Z")

</div>

Hello,

I am currently making a module (driver) in order to fetch data from an “exotic” PLC and expose them to another SCADA system by using the OPC-UA Server. The fetching part works fine but I have a problem accessing my data with the secondary SCADA.  
This SCADA system can not suscribe to OPC Nodes if its translation calls fail. It simply stops its subscription process to a Node if it cannot be translated.

Like many drivers, mine does not load its nodes in the server address space unless it it necessary. It means that all translation calls will fail, as nodes are not loaded.

If I browse my driver’s nodes with the Designer OPC Browser or the Gateway Quick client, they seem to be loaded in the OPC-UA Server as the translation calls from the secondary SCADA work fine after that.

So I tried to implement a browsing function in my driver, but even if it seems to browse my nodes (so say my logs entries), it looks like it does not browse them the same way that the OPC Browser does as translation calls fail.

My question is : Is there a way to make an ‘browsing-like-an-OPC-Browser-that-would-browse-all-nodes’ function inside my driver ?

Thank you in advance for your answers.

Regards.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [February 5, 2015, 3:55pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/2 "2015-02-05T15:55:28Z")

</div>

Rather than trying to simulate a browse coming from OPC it might be easier to just add all your nodes to the NodeManager when you start up. You must have or be able to obtain this information already, since you’re theoretically able to respond to a series of browse requests that would enumerate the nodes.

---

<div class="post-metadata">

**Author:** ![Amarth](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarth/32/3313_2.png) [@Amarth](https://forum.inductiveautomation.com/u/Amarth)\
**Post date:** [February 5, 2015, 4:34pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/3 "2015-02-05T16:34:55Z")

</div>

Thank you Kevin for your reply.

The nodes are currently already added to the NodeManager. I use something like that :

`public static DataNode addNode(Map<String, BrowseNode> nodemap, FolderNode parent, String adress, String name, DataType type, List<DataNode> uaNodes, Variant val, NodeManager nodeManager)
	{
		DataNode node = new DataNode(adress, name);
		node.setType(type);
		node.setValue(val);
		parent.addChild((BrowseNode) node);
		nodemap.put(adress, (BrowseNode) node);
		uaNodes.add(node);
		return node;
	}`

The thing is that even if they are in the NodeManager, they are not loaded in the adress space of the OPC-UA Server. It seems to be done once the nodes are browsed but not before. That is where lies my problem (or the secondary SCADA system’s one) : As they are not loaded, their paths cannot be translated to NodeId. The secondary SCADA simply stops its subscritpion process.

But, if the nodes have been browsed first, the traslation calls are successful and the secondary SCADA can manage to suscribe these nodes.

That is why I would like to be able to browse my nodes once they are all added to my NodeManager.

Regards.

---

<div class="post-metadata">

**Author:** ![Amarth](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarth/32/3313_2.png) [@Amarth](https://forum.inductiveautomation.com/u/Amarth)\
**Post date:** [February 6, 2015, 1:43pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/4 "2015-02-06T13:43:05Z")

</div>

Here is the subscription method of the secondary SCADA :

- Session Create.
- Node Paths to NodeID (using TranslateBrowsePathToNodeIds)
- Subscription Create (using CreateSubscription)
- Add Monitored Items

If the TranslateBrowsePathToNodeIds() call fails, the SCADA simply stops its subscription process for this node.

---

<div class="post-metadata">

**Author:** ![Amarth](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarth/32/3313_2.png) [@Amarth](https://forum.inductiveautomation.com/u/Amarth)\
**Post date:** [February 12, 2015, 12:59pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/5 "2015-02-12T12:59:11Z")

</div>

Hello,

I am still on this problem and cannot find any work around. Is it possible to simulate a browsing operation from the driver itself ?

Regards.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [February 12, 2015, 7:35pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/6 "2015-02-12T19:35:12Z")

</div>

In your example your’e not actually adding anything to the NodeManager, just to the node map.

NodeManager#addNode() is how a Node is added to the address space; it’s the same thing drivers do in the buildNode() call. Pre-loading them instead of waiting for a browse to come in (which results in buildNode() being called) should allow them to be targeted by the TranslateBrowsePathsToNodeId call from the client.

---

<div class="post-metadata">

**Author:** ![Amarth](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarth/32/3313_2.png) [@Amarth](https://forum.inductiveautomation.com/u/Amarth)\
**Post date:** [February 18, 2015, 11:13am UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/7 "2015-02-18T11:13:13Z")

</div>

Thank you Kevin for pointing that.

I added the addNode() method by taking inspiration from the driver code but, unfortunately, the nodes do not seem to be pre-loaded. And the TranslateBrowsePathToNodeId calls continue to fail.

Here is my new addNode method (not really clean yet but just for the tests):

```auto
	public static void addNode(Map<String, BrowseNode> nodemap, FolderNode parent, String adress, String name, DataType type, List<DataNode> uaNodes, List<Node> uaNodes_SBR, Variant val, NodeManager nodeManager, DriverContext driverContext)
	{	
	DataNode node = (DataNode)nodemap.get(adress);
        if ( node == null)
        {
            node = new DataNode(adress, name);
            node.setType(type);
            node.setValue(val);
            parent.addChild((BrowseNode) node);
            nodemap.put(adress, (BrowseNode) node);
        }
        NodeBuilderFactory builderFactory = driverContext.getNodeBuilderFactory();
        Node uaNode = builderFactory.newVariableNodeBuilder()
                                    .setNodeId(new NodeId(String.format("[%s]%s", new Object[]{name, adress}), 0))
                                    .setBrowseName(new QualifiedName(0, node.getDisplayName()))
                                    .setDisplayName(new LocalizedText(node.getDisplayName()))
                                    .setDataType(type.getNodeId())
                                    .setTypeDefinition(NodeIds.VariableNode_DataType.getNodeId())
                                    .setAccessLevel( EnumSet.of(AccessLevel.CurrentRead))
                                    .setUserAccessLevel(EnumSet.of(AccessLevel.CurrentRead))
                                    .buildAndAdd(nodeManager);

        nodeManager.addNode(uaNode);
        node.setUANode(uaNode);
        uaNodes.add(node);
        return;
}
```

Nodes are successfully created and the console reads no error at all. Still, the second SCADA calls to translate paths continue to fail.

I have tried many ways and i’m running out of ideas to make it work…  
The most incomprehensible thing is that if I browse the node using the Quick client or the Designer OPC Browser make the translate calls successful.

I’m thinking of a dirty workaround that would periodically browse the nodes but I can not figure the methods called by the designer OPC Browser. Is there a way to get them ?

I can provide code, logs, screenshots, Teamviewer sessions to explain more accurately my problem but I really need to make it work.

Thank you in advance.

Regards.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [February 19, 2015, 4:17pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/8 "2015-02-19T16:17:38Z")

</div>

I think what’s missing, assuming you’re calling addNode() for all your nodes on startup, is that when a browse happens references between nodes are also created, which is what gives these nodes in the address space any kind of structure.

After or during the addition of the nodes I think you need to also be calling NodeManager#addReference() to create whatever structure these are in.

```auto
				nodeManager.addReference(new Reference(
						nodeId,
						childNodeId,
						ReferenceType.HasComponent,
						ReferenceDirection.Forward));
```

Also - I think you should be using namespace index 1 for your NodeIds instead of 0.

---

<div class="post-metadata">

**Author:** ![Amarth](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarth/32/3313_2.png) [@Amarth](https://forum.inductiveautomation.com/u/Amarth)\
**Post date:** [February 20, 2015, 11:31am UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/9 "2015-02-20T11:31:04Z")

</div>

Thank you for the reply.

I added the NodeMamager.addReference() in my addNode() method (which is actually called for all my nodes on startup).  
It looks like :

```auto
        NodeId parentNodeId = new NodeId(parent.getBrowseName(),1);
        try {
        	nodeManager.addReference(new Reference(
        			parentNodeId,
    				uaNode.getNodeId(),
    				ReferenceType.HasComponent,
    				ReferenceDirection.Forward
    			));
```

That was added right after the “uaNodes.add(node);” in my previous code. Not really sure it is the correct syntax nor the expected arguments.

Anyway, it does not seem to preload much. I thought it came from my paths but even the nodes under the root nor the [Diagnostics] ones are preloaded…

I also changed the namespace to 1 instead of 0.

---

<div class="post-metadata">

**Author:** ![Amarth](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarth/32/3313_2.png) [@Amarth](https://forum.inductiveautomation.com/u/Amarth)\
**Post date:** [February 23, 2015, 5:10pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/10 "2015-02-23T17:10:51Z")

</div>

Hello,

I tried different ways to write the parent NodeId but none of them has been successful.

References seem to be correctly done (so says my logger) but the nodes aren’t pre-loaded.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [February 23, 2015, 6:03pm UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/11 "2015-02-23T18:03:47Z")

</div>

I’m not sure what it is you’re doing differently here. The only thing that happens when you browse from the quick client is that the server creates the browse structure in its address space as you browse, which is basically what you’re mimicking by creating nodes, adding them to the node manager, then adding the references to the node manager. Nothing else happens during a browse of a device, and the translate browse paths logic doesn’t rely on anything other than nodes and references existing.

I don’t know how you’d trigger a browse from within a driver, but you could trigger one programmatically from scripting using the system.opc.browse or system.opc.browseServer

---

<div class="post-metadata">

**Author:** ![Amarth](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarth/32/3313_2.png) [@Amarth](https://forum.inductiveautomation.com/u/Amarth)\
**Post date:** [February 24, 2015, 11:07am UTC](https://forum.inductiveautomation.com/t/how-to-preload-nodes-in-the-server-opc-ua-address-space/9652/12 "2015-02-24T11:07:52Z")

</div>

This function did not exist in 7.6.x. It explains why I could not find it.  
Anyway, I migrated all my stuff (driver+Gateway) to 7.7 and that did the trick.

Thank you very very much. ![:thumb_left:](https://us1.discourse-cdn.com/inductiveautomation/original/1X/e26afb081ddde6df016df6ee49159cf56aaca688.gif ":thumb\_left:")

Best regards.
