Search code examples
javaopcopc-uamilo

Browse server NameSpace and access custom references


I'm new to the OPC-UA universe and to the Milo SDK so I will try to do my best to explain what a i'm trying to do.

I have a OPC-UA server instance running, that loads some nodes to the server NameSapce. On the other hand I have a client that subscribes to this server and tries to browse this nodes. I can see the nodes in the Client and I can access some of the references that are defined to this node. What i'm trying to do now whiteout much success is to access a reference that is defined in the server and the UA-Expert can see it but my Milo Client implementation can't. The custom reference was defined in the server side, and my goal is to access their "BrowseName" or "DisplayName".

I believe that this can be a simple issue but now i'm struggling with this.

I will leave some print screens to exemplify what i mean in the text above:

In the image below the red arrow points to the reference that I'm trying to read, so in the second image we can see that the manufacture and description that have the type of HasComponent are reed correctly but the HasAMLRoleReference is not listed in the debug window.

Custom Reference

Debug info

This code it's not mine so I can't vouch for the correct implementation, but in the server side I know that this happens:

server.getNodeMap().addReference(new Reference(
                    new NodeId(NAMESPACE_IDX, getPrefix(e.getParentElement())),
                    new NodeId(1, 4001),// new NodeId(1,4001) = HasAmlRoleReference
                    server.getNodeMap().getNode(new NodeId(NAMESPACE_IDX, name)).get().getNodeId().expanded(), 
                    server.getNodeMap().getNode(new NodeId(NAMESPACE_IDX, name)).get().getNodeClass(), 
                    true)

So the ReferenceTypeId is a new NodeId(1, 4001) and this is the type that I'm trying to read in the client side. My code is based in the BrowseNode Exemple from the Milo git repo.

In this last image we can see the Address Space, so here we have some parameters that are also present in the References as HasComponent and so I can be using the wrong methods to access the one that i can't the HasAMLRoleReference, I sincerely don't know. enter image description here

Thanks in advance for the help.


[EDIT 1]

public void browseNode(String indent, OpcUaClient client, NodeId browseRoot){
try
{

  String equipmentNamespace = "openMOSRoleClassLib/Equipment";
  String skillNamespace = "openMOSRoleClassLib/Skill";
  String moduleNamespace = "openMOSRoleClassLib/Equipment/Module";

  BrowseDescription browse = new BrowseDescription(
          browseRoot,
          BrowseDirection.Forward,
          Identifiers.References,
          true,
          //uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue()),
          uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue() | NodeClass.ReferenceType.getValue()),
          uint(BrowseResultMask.All.getValue())
  );

  BrowseDescription browse2 = new BrowseDescription(
          browseRoot,
          BrowseDirection.Forward,
          new NodeId(1, 4001),
          true,
          //uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue()),
          uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue() | NodeClass.ReferenceType.getValue()),
          uint(BrowseResultMask.All.getValue())
  );

  BrowseResult browseResult = client.browse(browse).get();
  List<ReferenceDescription> references = toList(browseResult.getReferences());

  System.out.println("\n");
  for (ReferenceDescription rd : references)
  {

    //logger.info("Node={}", rd.getBrowseName().getName());
    System.out.println(indent + "Node=                         " + rd.getBrowseName().getName());
    System.out.println(indent + "Type=                         " + rd.getTypeId().toParseableString());
    System.out.println(indent + "NodeId:                       " + rd.getNodeId().toString());
    System.out.println(indent + "Other INFO[]:                 " + rd.getTypeDefinition().toParseableString());
    System.out.println(indent + "Other INFO[NamespaceIndex]:   " + rd.getReferenceTypeId().expanded().getNamespaceIndex());
    System.out.println(indent + "Other INFO[ReferenceTypeId]:  " + rd.getReferenceTypeId().expanded().toString());

    // recursively browse to children
    rd.getNodeId().local().ifPresent(nodeId -> browseNode("\t" + indent, client, nodeId));

  }
} catch (InterruptedException | ExecutionException e)
{
  logger.error("Browsing nodeId={} failed: {}", browseRoot, e.getMessage(), e);
}
}

[EDIT 2]

enter image description here

When I right click the Equipment reference it loads the information that is shown below.

enter image description here


Solution

  • Ok, the problem seems to be that you're only browsing for nodes with NodeClass: Object, Variable, ReferenceType.

    The HasAMLRoleReferences you're looking for are pointing to nodes with NodeClass of ObjectType, which is why you're not seeing them returned.