10/18/2019
Hi,
In UA 1.05.02, the handling of encoding/decoding structures is changed i.e. it is either AllowSubTypes or Optional properties as a choice.
What is the primary reason for it? This would be a breaking change for the current applications and also an additional work on the SDK vendors.
Can someone please help with context of this and reasoning?
Thanks,
Mohit
10/18/2019
Hi Randy,
Thanks for your response.
Basically, I am using VDMA Industrial Joining Technologies DRAFT specification which uses Machinery Result Specification. In the Machinery Result Model, we have
ResultDataType {
{
ResultMetaDataType resultMetaData; – Mandatory
BaseDataType[] resultContent; Mandatory
}
Problem: While importing the NodeSet, it throws Bad Decoding Error, when contacted the SDK Supplier, this needs some upgrades based on UA 1.05.02 in their layer but if we mark resultContent as OPTIONAL, it works.
So, in UA 1.05.02, we added a strong rule where structure fields can be sub-typed ONLY if that is Mandatory or we can have OPTIONAL fields without sub-type feature.
Can you please share the purpose of making this change in the UA specification as NOT all SDK suppliers have changed the behaviour?
THIS also causes a long term issue in adaptability of the OPC UA as these dependencies causes delays in the implementations.
05/30/2017
To clarify the ‘IsOptional’ flag has an overloaded meaning because we did not want to break existing implementations and the StructureDefinition only had one bit we could reuse.
So you are not setting ‘IsOptional’; You are setting ‘AllowSubtypes’ in this context.
If the AllowSubtypes/IsOptional flag is not set then only instances of ResultMetaDataType can be put in the field.
Setting AllowSubtypes/IsOptional allows any subtype of ResultMetaDataType.
Earlier versions implemented this use case by declaring the field type as ‘Structure’ rather than using a more descriptive abstract base type.
This implies that providing an input that does not set AllowSubtypes/IsOptional is simply wrong and you need to fix your input. Your tooling is providing the correct response to bad input.
That said, if you had an older tool that did not understand the AllowSubtypes flag then you would need to change your input to have Structure as the DataType instead of ResultMetaDataType. This would ensure wire compatibility with applications that do understand the flag.
The overloading of the IsOptional field is described here:
10/18/2019
Hi Randy,
Thanks again for your inputs. The input provided is NOT part of our specification. It is from MachineryResult and I can change it locally and try the suggestion.
But, Can you please share some detailed background context on AllowSubTypes and Only Optional use case introduced on its purpose, reasoning and any impact? I could not find any relevant documentation for the same.
I want to understand what was the problem statement it was solving when we say code-generation. A reference link to any documentation would be really helpful and in the mean-while I will validate the local changes in the NodeSet.
05/30/2017
You need to report the problem to the WG. The specification clearly indicates AllowSubtypes=true:
https://reference.opcfoundatio…..s/34/18957
I also checked the NodeSet online and it correctly sets the AllowsSubtypes = true.
So you may be dealing with an out of date version of the NodeSet. Please download the correct one:
https://reference.opcfoundatio…..odesets/34
The short answer is the lack of any way to indicate when subytypes were permitted was a major flaw in the DataTypeDefinition construct. Overloading the IsOptional flag was the least invasive way to address this omission that did not break wire protocol compatibility.
Specifically, code generators needed to know whether to create a structure like this:
class MyDataType {
MyFieldType Value1; // only instances of MyFieldType allowed.
}
or
class MyDataType {
ExtensionObject Value1; // any subtype of MyFieldType allowed.
}
That said, optional elements structures have been in the specification from 1.04 so I have no idea why you think that was a change.
More importantly, I do not believe this a tool issue.
Your problem is you have is with a NodeSet with invalid data (i.e. it does not match the published specification) .
You need to use the correct NodeSet.
10/18/2019
Hello Randy,
I am also using latest NodeSet and it has AllowSubTypes. After I added the highlighted IsOptional=true (as a work-around), it worked for me with the current SDK version i am using. It might be SDK vendor issue but from an user perspective, these things are dependency on an SDK. We cannot change the SDK vendors if there is delay in fix from a specific SDK vendor in general. ResultContent is BaseDataType[] and is Mandatory as per the Specification.
<Definition Name=”1:ResultDataType”>
<Field Name=”ResultMetaData” DataType=”ResultMetaDataType” AllowSubTypes=”true”>
<Description>Contains meta data describing the resultContent.</Description>
</Field>
<Field Name=”ResultContent” ValueRank=”1″ ArrayDimensions=”0″ IsOptional=”true”>
<Description>Abstract data type to be subtyped from to hold result data created by the selected recipe.</Description>
</Field>
</Definition>
</UADataType>
I know that optional structures were supported in UA 1.04 and encoding would work the same way as you mentioned. But, I wanted to understand, why we had to add a step where we made it mutually exclusive to have either sub-typable or optional. Why cannot optional fields be sub-typed… (You gave an example above but this is also forcing the Companion Standards to use it as mentioned, why the flexibility defined earlier is removed was my primary question?)
Ofcourse, maybe code-generators are facing issue but code generation is one-time static thing, the flexibility of having fields based on the use case is just removed for code-generation use case or are there any other reference documents for the same?
05/30/2017
That makes no sense.
The tool cannot possibly produce correct code with that hack.
I think this is a tool bug then.
The instructions for people dealing with older tools that do not understand AllowSubTypes are:
1) Replace DataType=<MyDataType> with DataType=”Structure”
2) Delete AllowSubTypes flag.
This is a simple procedure that ensures old tools will continue to work.
10/18/2019
Thanks again Randy.
There are couple of contexts in the discussion.
- Context 1: Alternative syntax in the NodeSet – For ImportNodeSet
- Ok, I completely agree that IsOptional change is NOT the correct one, BUT, here I was trying to troubleshoot the issue on how to make it work.
- I can remove IsOptional again and try per the syntax suggested by you and check if the ImportNodeSet works or not.
- Context 2: Our requirements
- We DO NOT have requirements for any auto-code generation. We just want to use the latest specifications where the application level is generated based on the manually written logic.
- We just want to use the structures irrespective of which format they support from OPC UA.
- Context 3: Code Generation Tool
- In your response, you have been referring to Tool, I guess, you meant, it is the UaModeler or similar type of tool which generates the application code? Or Is it something else?
- Context 4: Older Version Support or Backward Compatibility
- If a given OPC UA SDK does NOT support UA 1.05.02 and we have a need to use the Machinery Result specification with just some additional types, we should be able to use them as OPC UA specifications are extensible.
- If a given base specification or Companion Specification has defined the NodeSet based on the newer models using AllowSubTypes then are we supposed to make the change locally to make it work as per your suggestion?
- Context 5: Purpose of the changes done related to code generation using AllowSubTypes
- You have explained the example on that, is that the only reason or is there any document or reference where the context, analysis and other details captured?
05/30/2017
Any code that consumes a DataTypeDefinition needs to understand the new semantics. Older applications that only understand the 1.04 StructureTypes should reject DataTypeDefinitions that use the new StructureTypes so they will not be able to support new constructs like ResultDataType. This is expected whenever features are added (i.e. old applications cannot use new features).
You can use any NodeSet with old SDKs by making the changes I suggested. You could probably write a script do the substitution instead of relying on hand edits.
In the old model fields that allowed subtypes were untyped (i.e. Structure) which meant that literally any Structure could be passed and the application is expected to verify one of the correct types was provided. In the new model fields that allow subtypes have a DataType set to basetype which means the information model now describes what is allowed in the field instead of burying requirements in text.
It was a necessary improvement to the information model that includes a relatively simple fix to ensure compatibility with old code that reads NodeSets (the wire representation is not affected).
10/18/2019
Thanks a lot again Randy.
I will try the suggestion from your side to edit the existing NodeSet and check if it works with the older Tool. After the SDK supplier provides the fix, I will revert the file to original state.
Also, I agree that new features cannot be expected to work with older version of the Tools but as a whole, OPC UA NodeSets and models were defined in such a way that, any new types defined should work automatically as extensions.
But, here Import of the NodeSet failed and will try the work-around.
1 Guest(s)