06/29/2022
I started reading the specification of the “Call” service in part 4 and eventually stumbled upon part 3 where method nodes are specified. Sadly, the more I read the less I understand. Here is why:
Consider the UA Namespace with types “FileType”, “TrustListType” and the “TrustList” object below the DefaultApplicationGroup. All of these have an associated “Read” method node
- FileType -hasComponent-> Read (i=11585)
- TrustListType -hasComponent-> Read (i=12532)
- DefaultApplicationGroup::TrustList (i=12642) -hasComponent-> Read (i=12652)
The description of the Call Service (see https://reference.opcfoundatio…..ocs/5.11.2) for parameter “objectId” tells us
The NodeId shall be that of the Object or ObjectType on which the Method is invoked.
In case of an ObjectType the ObjectType or a super type of the ObjectType shall be the source of a HasComponent Reference (or subtype of HasComponent Reference) to the Method specified in methodId.
In case of an Object the Object or the ObjectType of the Object or a super type of that ObjectType shall be the source of a HasComponent Reference (or subtype of HasComponent Reference) to the Method specified in methodId.
In my head this translates to the following:
- Calling i=11585 (FileType::Read) on the TrustList object -> shall work
- Calling i=12532 (TrustListType::Read) on the TrustList object -> shall work
- Calling i=12652 on the TrustList object -> shall work
Now reading further the description of parameter “methodId”
NodeId of the Method to invoke.
If the objectId is the NodeId of an Object, it is allowed to use the NodeId of a Method that is the target of a HasComponent Reference from the ObjectType of the Object.
this translates to the following to me:
- Calling i=11585 (FileType::Read) on the TrustList object -> shall it work or not?
- Calling i=12532 (TrustListType::Read) on the TrustList object -> shall work
- Calling i=12652 on the Trust List object -> shall work
If we look into part 3 (https://reference.opcfoundatio…..5/docs/5.7) now, there is this passage
A Method shall always be the TargetNode of at least one HasComponent Reference. The SourceNode of these HasComponent References shall be an Object or an ObjectType. If a Method is called, then the NodeId of one of those Nodes shall be put into the Call Service defined in OPC 10000-4 as parameter to detect the context of the Method operation.
which translates to the following to me:
- Calling i=11585 (FileType::Read) on the TrustList object -> shall not work
- Calling i=12532 (TrustListType::Read) on the TrustList object -> shall not work
- Calling i=12652 on the TrustList object -> shall work
I am confused now. Still there is the following hint also in part 3 (https://reference.opcfoundatio…..5/docs/4.8)
Methods are “lightweight” functions, whose scope is bounded by an owning (see Note) Object, similar to the methods of a class in object-oriented programming or an owning ObjectType, similar to static methods of a class. Methods are invoked by a client, proceed to completion on the Server and return the result to the client. The lifetime of the Method’s invocation instance begins when the client calls the Method and ends when the result is returned.
NOTE The owning Object or ObjectType is specified in the service call when invoking the Method.
which can be interpreted as an indicator, that the initial statement for parameter “objectId” from the “Call”-Service describes the real deal.
Can someone clarify if this assumption is correct?
05/30/2017
Node i=12532 does not exist in the NodeSet.
I realized the CSVs used to have unused Nodes defined but they have been removed from the CSVs.
So there are only 2 NodeIds that are relevant: i=11585 (FileType::Read) and i=12652 on the TrustList object.
The rule is this:
The Method on the Object identified by the ObjectId provided.
The Method on TypeDefinition of the Object identified by the ObjectId.
But the TypeDefinition includes all of the components it inherits with overridden components hiding the parent component.
In this example, i=11585 (FileType::Read) is the Method on the TypeDefinition.
If the i=12532 (TrustListType::Read) actually existed then it would be the one used because it is what ends up being part of the TypeDefinition.
06/29/2022
Ok so if I understand you correctly, the super type statement in the description of parameter “objectId” of Call Service is wrong (or at least wrongly phrased)? Because it reads, that regardless if a method is overridden downwards the hierarchy or not, all objectId+methodId combinations would be allowed (which would make sense in an object-oriented programming language where you could cast the object to any type of the object’s type hierarchy that has access to the desired method and call it).
Whereas you say, that only the method on the object level and the first found method belonging to an objectype upward the hiearchy is allowed. This is an important difference. And it still means, that the statement in part 3 is wrong in this regard.
Another case which comes to my mind is where objectId refers to an ObjectType. Because of being meant to be like a call to a “static method” (in the object-oriented world) only methods that have an incoming hasComponent reference from that ObjectType should be used with Call Service in this specific case.
What would the correct wording be like for the 3 cited statements in my initial post?
05/30/2017
Originally only the MethodId of the Method on the Object could be used.
This was problematic since it required clients to Browse every Object they encounter even though they know the Method exists because of the TypeDefinition. The best solution would have used the BrowseName instead of the NodeId but that was not an option so the compromise of using a well-known NodeId from the TypeDefinition was introduced.
As you have succinctly pointed out, this change led to confusing wording in the specification and we need a mantis issue.
Since the point of adding the TypeDefinition was to allow the client to use a well-known Node for the MethodId. If we want to solution that is consistent with that object then any Method in the TypeDefinition hierarchy should be valid with a preference for the Method on the ObjectType which originally defined the Method.
My preference would be to only require the MethodId of the ObjectType that originally defined the Method.
A Client developer should assume that this would work.
A Server developer will likely assume this is what is expected.
06/29/2022
Ok so, this sounds reasonable. I will create the mantis issue soon.
One point to further consider for this situation is this of the RolePermissions. They are defined to be associated with specific nodes in the Information Model. My assumption would be, that only the permissions of the MethodNode that directly belong to the objectId apply regardless of what is actually provided to the Call-Service. I will point this out in the mantis issue to be considered as well.
1 Guest(s)