You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2021/04/30 11:20:23 UTC

[plc4x] branch feature/native_opua_client updated: Can now open/close a connection and read values.

This is an automated email from the ASF dual-hosted git repository.

hutcheb pushed a commit to branch feature/native_opua_client
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/feature/native_opua_client by this push:
     new 73bebf2  Can now open/close a connection and read values.
73bebf2 is described below

commit 73bebf27f07ec8d549d6a503fbdf43cad381334a
Author: hutcheb <be...@gmail.com>
AuthorDate: Fri Apr 30 07:19:39 2021 -0400

    Can now open/close a connection and read values.
---
 .../java/opcua/protocol/OpcuaProtocolLogic.java    | 71 ++++++++++++++--------
 .../opcua/protocol/OpcuaSubscriptionHandle.java    |  3 +-
 protocols/opcua/src/main/xslt/opc-common.xsl       |  4 ++
 protocols/opcua/src/main/xslt/opc-manual.xsl       | 30 +++++----
 4 files changed, 67 insertions(+), 41 deletions(-)

diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
index 553e64d..d4aad96 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
@@ -99,9 +99,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
     );
     protected static final ExtensionObject NULL_EXTENSION_OBJECT = new ExtensionObject(
         NULL_EXPANDED_NODEID,
-        new NullExtension(false,
-            false,
-            false));               // Body
+        new ExtensionObjectEncodingMask(false, false, false),
+        new NullExtension());               // Body
     private static final long EPOCH_OFFSET = 116444736000000000L;         //Offset between OPC UA epoch time and linux epoch time.
     private static final PascalString APPLICATION_URI = new PascalString("urn:apache:plc4x:client");
     private static final PascalString PRODUCT_URI = new PascalString("urn:apache:plc4x:client");
@@ -192,7 +191,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
 
         ExpandedNodeId expandedNodeId = new ExpandedNodeId(false,           //Namespace Uri Specified
             false,            //Server Index Specified
-            new NodeIdFourByte((short) 0, 471),
+            new NodeIdFourByte((short) 0, 473),
             null,
             null);    //Identifier for OpenSecureChannel
 
@@ -209,11 +208,14 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             requestHeader,
             true);
 
+        ExtensionObject extObject = new ExtensionObject(
+            expandedNodeId,
+            null,
+            closeSessionRequest);
+
         try {
-            WriteBuffer buffer = new WriteBuffer(closeSessionRequest.getLengthInBytes(), true);
-            ExtensionObjectIO.staticSerialize(buffer, new ExtensionObject(
-                expandedNodeId,
-                closeSessionRequest));
+            WriteBuffer buffer = new WriteBuffer(extObject.getLengthInBytes(), true);
+            ExtensionObjectIO.staticSerialize(buffer, extObject);
 
             OpcuaMessageRequest messageRequest = new OpcuaMessageRequest(FINAL_CHUNK,
                 channelId.get(),
@@ -262,6 +264,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             transactionId,
             new ExtensionObject(
                 expandedNodeId,
+                null,
                 closeSecureChannelRequest));
 
         context.sendRequest(new OpcuaAPU(closeRequest))
@@ -358,6 +361,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             WriteBuffer buffer = new WriteBuffer(openSecureChannelRequest.getLengthInBytes(), true);
             ExtensionObjectIO.staticSerialize(buffer, new ExtensionObject(
                 expandedNodeId,
+                null,
                 openSecureChannelRequest));
 
             OpcuaOpenRequest openRequest = new OpcuaOpenRequest(FINAL_CHUNK,
@@ -375,7 +379,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 .unwrap(p -> (OpcuaOpenResponse) p.getMessage())
                 .handle(opcuaOpenResponse -> {
                     try {
-                        ExtensionObject message = ExtensionObjectIO.staticParse(new ReadBuffer(opcuaOpenResponse.getMessage(), true));
+                        ExtensionObject message = ExtensionObjectIO.staticParse(new ReadBuffer(opcuaOpenResponse.getMessage(), true), false);
                         if (message.getBody() instanceof ServiceFault) {
                             ServiceFault fault = (ServiceFault) message.getBody();
                             LOGGER.error("Failed to connect to opc ua server for the following reason:- {}, {}", ((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode(), OpcuaStatusCodes.enumForValue(((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode()));
@@ -437,6 +441,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             WriteBuffer buffer = new WriteBuffer(endpointsRequest.getLengthInBytes(), true);
             ExtensionObjectIO.staticSerialize(buffer, new ExtensionObject(
                 expandedNodeId,
+                null,
                 endpointsRequest));
 
             OpcuaMessageRequest messageRequest = new OpcuaMessageRequest(FINAL_CHUNK,
@@ -452,7 +457,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 .unwrap(p -> (OpcuaMessageResponse) p.getMessage())
                 .handle(opcuaMessageResponse -> {
                     try {
-                        ExtensionObject message = ExtensionObjectIO.staticParse(new ReadBuffer(opcuaMessageResponse.getMessage(), true));
+                        ExtensionObject message = ExtensionObjectIO.staticParse(new ReadBuffer(opcuaMessageResponse.getMessage(), true), false);
                         if (message.getBody() instanceof ServiceFault) {
                             ServiceFault fault = (ServiceFault) message.getBody();
                             LOGGER.error("Failed to connect to opc ua server for the following reason:- {}, {}", ((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode(), OpcuaStatusCodes.enumForValue(((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode()));
@@ -515,6 +520,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             transactionId,
             new ExtensionObject(
                 expandedNodeId,
+                null,
                 closeSecureChannelRequest));
 
         context.sendRequest(new OpcuaAPU(closeRequest))
@@ -567,6 +573,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
 
         ExtensionObject extObject = new ExtensionObject(
             expandedNodeId,
+            null,
             openSecureChannelRequest);
 
         try {
@@ -598,7 +605,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                             opcuaOpenResponse = (OpcuaOpenResponse) OpcuaAPUIO.staticParse(encryptionHandler.decodeMessage(opcuaOpenResponse, opcuaOpenResponse.getMessage()), true).getMessage();
                         }
                         ReadBuffer readBuffer = new ReadBuffer(opcuaOpenResponse.getMessage(), true);
-                        ExtensionObject message = ExtensionObjectIO.staticParse(readBuffer);
+                        ExtensionObject message = ExtensionObjectIO.staticParse(readBuffer, false);
 
                         if (message.getBody() instanceof ServiceFault) {
                             ServiceFault fault = (ServiceFault) message.getBody();
@@ -684,6 +691,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
 
         ExtensionObject extObject = new ExtensionObject(
             expandedNodeId,
+            null,
             createSessionRequest);
 
         try {
@@ -711,7 +719,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 .unwrap(p -> (OpcuaMessageResponse) p.getMessage())
                 .handle(opcuaMessageResponse -> {
                     try {
-                        ExtensionObject message = ExtensionObjectIO.staticParse(new ReadBuffer(opcuaMessageResponse.getMessage(), true));
+                        ExtensionObject message = ExtensionObjectIO.staticParse(new ReadBuffer(opcuaMessageResponse.getMessage(), true), false);
                         if (message.getBody() instanceof ServiceFault) {
                             ServiceFault fault = (ServiceFault) message.getBody();
                             LOGGER.error("Failed to connect to opc ua server for the following reason:- {}, {}", ((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode(), OpcuaStatusCodes.enumForValue(((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode()));
@@ -789,7 +797,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
 
         ExtensionObject userIdentityToken = null;
         if (this.username == null) {
-            userIdentityToken = getIdentityToken("none");
+            userIdentityToken = getIdentityToken("anonymous");
         } else {
             userIdentityToken = getIdentityToken("username");
         }
@@ -812,6 +820,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
 
         ExtensionObject extObject = new ExtensionObject(
             expandedNodeId,
+            null,
             activateSessionRequest);
 
         try {
@@ -832,7 +841,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 .handle(opcuaActivateResponse -> {
                     LOGGER.debug("Got Activate Session Response Connection Response");
                     try {
-                        ExtensionObject message = ExtensionObjectIO.staticParse(new ReadBuffer(opcuaActivateResponse.getMessage(), true));
+                        ExtensionObject message = ExtensionObjectIO.staticParse(new ReadBuffer(opcuaActivateResponse.getMessage(), true), false);
                         if (message.getBody() instanceof ServiceFault) {
                             ServiceFault fault = (ServiceFault) message.getBody();
                             LOGGER.error("Failed to connect to opc ua server for the following reason:- {}, {}", ((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode(), OpcuaStatusCodes.enumForValue(((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode()));
@@ -901,13 +910,16 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             null,
             null);
 
+        ExtensionObject extObject = new ExtensionObject(
+            expandedNodeId,
+            null,
+            opcuaReadRequest);
+
         int transactionId = getTransactionIdentifier();
 
         try {
-            WriteBuffer buffer = new WriteBuffer(opcuaReadRequest.getLengthInBytes(), true);
-            ExtensionObjectIO.staticSerialize(buffer, new ExtensionObject(
-                expandedNodeId,
-                opcuaReadRequest));
+            WriteBuffer buffer = new WriteBuffer(extObject.getLengthInBytes(), true);
+            ExtensionObjectIO.staticSerialize(buffer, extObject);
 
             OpcuaMessageRequest readMessageRequest = new OpcuaMessageRequest(FINAL_CHUNK,
                 channelId.get(),
@@ -927,7 +939,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     // Prepare the response.
                     PlcReadResponse response = null;
                     try {
-                        response = new DefaultPlcReadResponse(request, readResponse(request.getFieldNames(), (ReadResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true)).getBody()));
+                        response = new DefaultPlcReadResponse(request, readResponse(request.getFieldNames(), (ReadResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true), false).getBody()));
                     } catch (ParseException e) {
                         e.printStackTrace();
                     };
@@ -1441,6 +1453,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             WriteBuffer buffer = new WriteBuffer(opcuaWriteRequest.getLengthInBytes(), true);
             ExtensionObjectIO.staticSerialize(buffer, new ExtensionObject(
                 expandedNodeId,
+                null,
                 opcuaWriteRequest));
 
             OpcuaMessageRequest writeMessageRequest = new OpcuaMessageRequest(FINAL_CHUNK,
@@ -1460,7 +1473,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 .handle(opcuaResponse -> {
                     WriteResponse responseMessage = null;
                     try {
-                        responseMessage = (WriteResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true)).getBody();
+                        responseMessage = (WriteResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true), false).getBody();
                     } catch (ParseException e) {
                         e.printStackTrace();
                     }
@@ -1650,6 +1663,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             WriteBuffer buffer = new WriteBuffer(createSubscriptionRequest.getLengthInBytes(), true);
             ExtensionObjectIO.staticSerialize(buffer, new ExtensionObject(
                 expandedNodeId,
+                null,
                 createSubscriptionRequest));
 
             int transactionId = getTransactionIdentifier();
@@ -1671,7 +1685,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 .handle(opcuaResponse -> {
                     CreateSubscriptionResponse responseMessage = null;
                     try {
-                        responseMessage = (CreateSubscriptionResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true)).getBody();
+                        responseMessage = (CreateSubscriptionResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true), false).getBody();
                     } catch (ParseException e) {
                         e.printStackTrace();
                     }
@@ -1722,6 +1736,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             WriteBuffer buffer = new WriteBuffer(createMonitoredItemsRequest.getLengthInBytes(), true);
             ExtensionObjectIO.staticSerialize(buffer, new ExtensionObject(
                 expandedNodeId,
+                null,
                 createMonitoredItemsRequest));
 
             int transactionId = getTransactionIdentifier();
@@ -1743,7 +1758,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 .handle(opcuaResponse -> {
                     CreateMonitoredItemsResponse responseMessage = null;
                     try {
-                        responseMessage = (CreateMonitoredItemsResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true)).getBody();
+                        responseMessage = (CreateMonitoredItemsResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true), false).getBody();
                     } catch (ParseException e) {
                         e.printStackTrace();
                     }
@@ -1878,19 +1893,20 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
         ExpandedNodeId extExpandedNodeId = null;
         ExtensionObject userIdentityToken = null;
         switch (securityPolicy) {
-            case "none":
+            case "anonymous":
                 //If we aren't using authentication tell the server we would like to login anonymously
                 AnonymousIdentityToken anonymousIdentityToken = new AnonymousIdentityToken();
 
                 extExpandedNodeId = new ExpandedNodeId(false,           //Namespace Uri Specified
                     false,            //Server Index Specified
                     new NodeIdFourByte((short) 0, OpcuaNodeIdServices.AnonymousIdentityToken_Encoding_DefaultBinary.getValue()),
-                    NULL_STRING,
-                    1L);
+                    null,
+                    null);
 
                 return new ExtensionObject(
                     extExpandedNodeId,
-                    new UserIdentityToken(anonymousIdentityToken));
+                    new ExtensionObjectEncodingMask(false, false, true),
+                    new UserIdentityToken(new PascalString("anonymous"), anonymousIdentityToken));
             case "username":
                 //Encrypt the password using the server nonce and server public key
                 byte[] passwordBytes = this.password.getBytes();
@@ -1918,7 +1934,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
 
                 return new ExtensionObject(
                     extExpandedNodeId,
-                    new UserIdentityToken(userNameIdentityToken));
+                    new ExtensionObjectEncodingMask(false, false, true),
+                    new UserIdentityToken(new PascalString("username"), userNameIdentityToken));
         }
         return null;
     }
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java
index 9ef28c2..e74a10a 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java
@@ -131,6 +131,7 @@ public class OpcuaSubscriptionHandle extends DefaultPlcSubscriptionHandle {
                         WriteBuffer buffer = new WriteBuffer(publishRequest.getLengthInBytes(), true);
                         ExtensionObjectIO.staticSerialize(buffer, new ExtensionObject(
                             extExpandedNodeId,
+                            null,
                             publishRequest));
 
                         int transactionId = this.plcSubscriber.getTransactionIdentifier();
@@ -152,7 +153,7 @@ public class OpcuaSubscriptionHandle extends DefaultPlcSubscriptionHandle {
                             .handle(opcuaResponse -> {
                                 PublishResponse responseMessage = null;
                                 try {
-                                    responseMessage = (PublishResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true)).getBody();
+                                    responseMessage = (PublishResponse) ExtensionObjectIO.staticParse(new ReadBuffer(opcuaResponse.getMessage(), true), false).getBody();
                                 } catch (ParseException e) {
                                     e.printStackTrace();
                                 }
diff --git a/protocols/opcua/src/main/xslt/opc-common.xsl b/protocols/opcua/src/main/xslt/opc-common.xsl
index 020b1f3..5fc5633 100644
--- a/protocols/opcua/src/main/xslt/opc-common.xsl
+++ b/protocols/opcua/src/main/xslt/opc-common.xsl
@@ -221,6 +221,8 @@
                         <xsl:variable name="id" select="number(substring-after($file/node:UANodeSet/node:UADataType[@BrowseName=$browseName]/@NodeId, '=')) + 2"/><xsl:text>
             </xsl:text>[array <xsl:value-of select="$dataType"/>  '<xsl:value-of select="$lowerCaseName"/>' count '<xsl:value-of select="$lowerCaseLengthField"/>' ['<xsl:value-of select='$id'/>']]
             </xsl:when>
+                    <xsl:when test="$dataType = 'ExtensionObject'">[array <xsl:value-of select="$dataType"/>  '<xsl:value-of select="$lowerCaseName"/>' count '<xsl:value-of select="$lowerCaseLengthField"/>' ['true']]
+                    </xsl:when>
                     <xsl:otherwise>[array <xsl:value-of select="$dataType"/>  '<xsl:value-of select="$lowerCaseName"/>' count '<xsl:value-of select="$lowerCaseLengthField"/>']
             </xsl:otherwise>
                 </xsl:choose>
@@ -242,6 +244,8 @@
                 <xsl:variable name="id" select="number(substring-after($file/node:UANodeSet/node:UADataType[@BrowseName=$browseName]/@NodeId, '=')) + 2"/><xsl:text>
             </xsl:text>[<xsl:value-of select="$mspecType"/><xsl:text> </xsl:text><xsl:value-of select="$dataType"/> '<xsl:value-of select="$lowerCaseName"/>' ['<xsl:value-of select='$id'/>']]
             </xsl:when>
+            <xsl:when test="$dataType = 'ExtensionObject'">[<xsl:value-of select="$mspecType"/><xsl:text> </xsl:text><xsl:value-of select="$dataType"/> '<xsl:value-of select="$lowerCaseName"/>' ['true']]
+            </xsl:when>
             <xsl:otherwise>[<xsl:value-of select="$mspecType"/><xsl:text> </xsl:text><xsl:value-of select="$dataType"/> '<xsl:value-of select="$lowerCaseName"/>']
             </xsl:otherwise>
         </xsl:choose>
diff --git a/protocols/opcua/src/main/xslt/opc-manual.xsl b/protocols/opcua/src/main/xslt/opc-manual.xsl
index a5ab28c..a68225f 100644
--- a/protocols/opcua/src/main/xslt/opc-manual.xsl
+++ b/protocols/opcua/src/main/xslt/opc-manual.xsl
@@ -99,7 +99,7 @@
            [simple          int 32             'secureTokenId']
            [simple          int 32             'sequenceNumber']
            [simple          int 32             'requestId']
-           [simple          ExtensionObject       'message']
+           [simple          ExtensionObject       'message' ['false']]
        ]
        ['MSG','false'     OpcuaMessageRequest
            [simple          string '8'         'chunk']
@@ -150,9 +150,17 @@
     [simple bit 'binaryBody]
 ]
 
-[type 'ExtensionObject'
+[type 'ExtensionObjectEncodingMask'
+    [reserved int 5 '0x00']
+    [simple bit 'typeIdSpecified']
+    [simple bit 'xmlbody']
+    [simple bit 'binaryBody]
+]
+
+[type 'ExtensionObject' [bit 'includeEncodingMask']
     //A serialized object prefixed with its data type identifier.
     [simple ExpandedNodeId 'typeId']
+    [optional ExtensionObjectEncodingMask 'encodingMask' 'includeEncodingMask']
     [virtual string '-1' 'identifier' 'typeId.identifier']
     [simple ExtensionObjectDefinition 'body' ['identifier']]
 ]
@@ -160,10 +168,6 @@
 [discriminatedType 'ExtensionObjectDefinition' [string '-1' 'identifier']
     [typeSwitch 'identifier'
         ['0' NullExtension
-            [reserved int 5 '0x00']
-            [simple bit 'xmlbody']
-            [simple bit 'binaryBody]
-            [simple bit 'typeIdSpecified']
         ]
 
         <xsl:for-each select="/opc:TypeDictionary/opc:StructuredType[(@BaseType = 'ua:ExtensionObject') and not(@Name = 'UserIdentityToken') and not(@Name = 'PublishedDataSetDataType') and not(@Name = 'DataSetReaderDataType')]">
@@ -173,16 +177,16 @@
         </xsl:for-each>
 
         ['316' UserIdentityToken
-            [simple UserIdentityTokenDefinition 'userIdentityTokenDefinition']
+            [implicit int 32 'policyLength' 'policyId.lengthInBytes']
+            [simple PascalString 'policyId']
+            [simple UserIdentityTokenDefinition 'userIdentityTokenDefinition' ['policyId.stringValue']]
         ]
     ]
 ]
 
-[discriminatedType 'UserIdentityTokenDefinition'
-    [implicit int 32 'policyIdLength' 'policyId.length']
-    [discriminator string '-1' 'policyId']
-    [typeSwitch 'policyId'
-        ['none' AnonymousIdentityToken
+[discriminatedType 'UserIdentityTokenDefinition' [string '-1' 'identifier']
+    [typeSwitch 'identifier'
+        ['anonymous' AnonymousIdentityToken
         ]
         ['username' UserNameIdentityToken
             [simple PascalString 'userName']
@@ -291,7 +295,7 @@
         ]
         ['22' VariantExtensionObject [bit 'arrayLengthSpecified']
             [optional int 32 'arrayLength' 'arrayLengthSpecified']
-            [array ExtensionObject 'value' count 'arrayLength == null ? 1 : arrayLength']
+            [array ExtensionObject 'value' count 'arrayLength == null ? 1 : arrayLength' ['true']]
         ]
         ['23' VariantDataValue [bit 'arrayLengthSpecified']
             [optional int 32 'arrayLength' 'arrayLengthSpecified']