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/01/02 12:23:03 UTC

[plc4x] branch feature/native_opua_client updated: Getting my head around how to represent some datatypes in mspec.

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 e03bd13  Getting my head around how to represent some datatypes in mspec.
e03bd13 is described below

commit e03bd13ae71fa6b2e40d85985d8095f1c3392502
Author: hutcheb <be...@gmail.com>
AuthorDate: Sat Jan 2 07:22:01 2021 -0500

    Getting my head around how to represent some datatypes in mspec.
---
 .../BaseFreemarkerLanguageTemplateHelper.java      |  8 ++
 .../main/resources/templates/java/io-template.ftlh | 20 ++++-
 .../resources/templates/java/pojo-template.ftlh    | 32 ++++---
 .../mspec/parser/MessageFormatListener.java        |  1 -
 .../java/opcua/protocol/OpcuaProtocolLogic.java    | 97 +++++++++++++---------
 .../plc4x/java/spi/generation/ReadBuffer.java      |  2 +-
 .../plc4x/java/spi/generation/WriteBuffer.java     | 28 ++++++-
 protocols/opcua/src/main/xslt/opc-types.xsl        | 40 +++------
 8 files changed, 141 insertions(+), 87 deletions(-)

diff --git a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
index 2d35bf5..3d897b9 100644
--- a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
+++ b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
@@ -249,6 +249,14 @@ public abstract class BaseFreemarkerLanguageTemplateHelper implements Freemarker
             final ImplicitField implicitField = implicitFieldOptional.get();
             return Optional.of(implicitField.getType());
         }
+        // Check if the expression is a VirtualField
+        final Optional<VirtualField> virtualFieldOptional = baseType.getFields().stream().filter(
+            field -> field instanceof VirtualField).map(field -> (VirtualField) field).filter(
+            virtualField -> virtualField.getName().equals(propertyName)).findFirst();
+        if(virtualFieldOptional.isPresent()) {
+            final VirtualField virtualField = virtualFieldOptional.get();
+            return Optional.of(virtualField.getType());
+        }
         // Check if the expression root is referencing an argument
         if(baseType.getParserArguments() != null) {
             final Optional<Argument> argumentOptional = Arrays.stream(baseType.getParserArguments()).filter(
diff --git a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
index dc127b6..ea54624 100644
--- a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
@@ -243,10 +243,13 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
         <#break>
     <#case "discriminator">
         <#assign discriminatorField = field>
-        <#assign simpleTypeReference = discriminatorField.type>
 
         // Discriminator Field (${discriminatorField.name}) (Used as input to a switch field)
-        ${helper.getLanguageTypeNameForField(field)} ${discriminatorField.name} = ${helper.getReadBufferReadMethodCall(simpleTypeReference)};
+        <#if helper.isEnumField(field)>
+            ${helper.getLanguageTypeNameForField(field)} ${discriminatorField.name} = ${helper.getLanguageTypeNameForField(discriminatorField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(discriminatorField.type))});
+        <#else>
+            ${helper.getLanguageTypeNameForField(field)} ${discriminatorField.name} = <#if helper.isSimpleTypeReference(discriminatorField.type)>${helper.getReadBufferReadMethodCall(discriminatorField.type)}<#else>${discriminatorField.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(discriminatorField.type, parserArgument?index), true)}) (${helper.toParseExpression(discrim [...]
+        </#if>
         <#break>
     <#case "enum">
         <#assign enumField = field>
@@ -460,11 +463,20 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
         <#break>
     <#case "discriminator">
         <#assign discriminatorField = field>
-        <#assign simpleTypeReference = discriminatorField.type>
 
         // Discriminator Field (${discriminatorField.name}) (Used as input to a switch field)
         ${helper.getLanguageTypeNameForField(field)} ${discriminatorField.name} = (${helper.getLanguageTypeNameForField(field)}) _value.get${discriminatorField.name?cap_first}();
-        ${helper.getWriteBufferWriteMethodCall(simpleTypeReference, "(" + discriminatorField.name + ")")};
+        <#if helper.isSimpleTypeReference(discriminatorField.type)>
+            <#assign simpleTypeReference = discriminatorField.type>
+            ${helper.getWriteBufferWriteMethodCall(simpleTypeReference, "(" + discriminatorField.name + ")")};
+        <#else>
+            <#assign complexTypeReference = discriminatorField.type>
+            <#if helper.isEnumField(field)>
+                ${helper.getWriteBufferWriteMethodCall(helper.getEnumBaseTypeReference(discriminatorField.type), "(" + discriminatorField.name + ".getValue())")};
+            <#else>
+                ${complexTypeReference.name}IO.staticSerialize(io, ${discriminatorField.name});
+            </#if>
+        </#if>
         <#break>
     <#case "enum">
         <#assign enumField = field>
diff --git a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
index 7772377..ee1ebe7 100644
--- a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
@@ -93,9 +93,11 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${
     <#list helper.getDiscriminatorValues(discriminatedChildType) as discriminatorName, discriminatorValue>
         <#-- If the discriminator name matches that of another field, suppress the methods generation -->
         <#if !helper.isNonDiscriminatorField(discriminatorName)>
+    <#if discriminatorValue??>//${discriminatorValue}</#if>
+    //${discriminatorName}
     @JsonIgnore
     public ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])} get${discriminatorName?cap_first}() {
-        return <#if discriminatorValue??>${helper.escapeValue(helper.getDiscriminatorTypes()[discriminatorName],discriminatorValue)}<#else>${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if>;
+        return <#if helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName]) = "String"><#if discriminatorValue??>"${discriminatorValue}"<#else>${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if><#else><#if discriminatorValue??>${discriminatorValue}<#else>${helper.getNullValueForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])}</#if></#if>;
     }
         </#if>
     </#list>
@@ -202,15 +204,20 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${
         <#break>
     <#case "discriminator">
         <#assign discriminatorField = field>
-        <#assign simpleTypeReference = discriminatorField.type>
 
-        // Discriminator Field (${discriminatorField.name})        
-        <#if helper.getLanguageTypeNameForTypeReference(discriminatorField.type) = "String">
-            <#assign simpleTypeReference = discriminatorField.type>
-        lengthInBits += ${simpleTypeReference.getLength()};
+        // Discriminator Field (${discriminatorField.name})
+        <#if helper.isSimpleTypeReference(discriminatorField.type)>
+            <#if helper.getLanguageTypeNameForTypeReference(discriminatorField.type) = "String">
+                <#assign simpleTypeReference = discriminatorField.type>
+                lengthInBits += ${simpleTypeReference.getLength()};
+            <#else>
+                <#assign simpleTypeReference = discriminatorField.type>
+                lengthInBits += ${simpleTypeReference.sizeInBits};
+            </#if>
+        <#elseif helper.isEnumField(field)>
+            lengthInBits += ${helper.getEnumBaseTypeReference(discriminatorField.type).sizeInBits};
         <#else>
-            <#assign simpleTypeReference = discriminatorField.type>
-        lengthInBits += ${simpleTypeReference.sizeInBits};
+            lengthInBits += ${discriminatorField.name}.getLengthInBits();
         </#if>
         <#break>
     <#case "enum">
@@ -244,8 +251,13 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${
         // Optional Field (${optionalField.name})
         if(${optionalField.name} != null) {
         <#if helper.isSimpleTypeReference(optionalField.type)>
-            <#assign simpleTypeReference = optionalField.type>
-            lengthInBits += ${simpleTypeReference.sizeInBits};
+            <#if helper.getLanguageTypeNameForTypeReference(optionalField.type) = "String">
+                <#assign simpleTypeReference = optionalField.type>
+    lengthInBits += ${simpleTypeReference.getLength()};
+            <#else>
+                <#assign simpleTypeReference = optionalField.type>
+    lengthInBits += ${simpleTypeReference.sizeInBits};
+            </#if>
         <#elseif helper.isEnumField(field)>
             lengthInBits += ${helper.getEnumBaseTypeReference(optionalField.type).sizeInBits};
         <#else>
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
index d0b80c1..7312f35 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
@@ -187,7 +187,6 @@ public class MessageFormatListener extends MSpecBaseListener {
 
     @Override
     public void enterDiscriminatorField(MSpecParser.DiscriminatorFieldContext ctx) {
-        // Handle enum types.
         TypeReference type = getTypeReference(ctx.type);
         String name = getIdString(ctx.name);
         Field field = new DefaultDiscriminatorField(null, type, name);
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 4b5593d..af83533 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
@@ -18,6 +18,7 @@
  */
 package org.apache.plc4x.java.opcua.protocol;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
@@ -110,27 +111,25 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 NodeIdTwoByte authenticationToken = new NodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
                                                                     new TwoByteNodeId((short) 0));
 
-                ExpandedNodeId expandedNodeId = new ExpandedNodeIdFourByte(NodeIdType.nodeIdTypeFourByte,
+                ExpandedNodeId expandedNodeId = new ExpandedNodeIdFourByte(false,
                                                                     false,
-                                                                    false,
-                                                                    new FourByteNodeId((short) 0, 466),
-                                                                    new PascalString(-1,""),
-                                                                    1L);
+                                                                    new PascalString(-1,null),
+                                                                    1L,
+                                                                    new FourByteNodeId((short) 0, 466));
 
-                ExpandedNodeId extExpandedNodeId = new ExpandedNodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
-                                                                    false,
+                ExpandedNodeId extExpandedNodeId = new ExpandedNodeIdTwoByte(false,
                                                                     false,
-                                                                    new TwoByteNodeId((short) 0),
                                                                     null,
-                                                                    null);
+                                                                    null,
+                                                                    new TwoByteNodeId((short) 0));
 
-                ExtensionObject extObject = new ExtensionObject(extExpandedNodeId, (short) 0);
+                ExtensionObject extObject = new ExtensionObject(extExpandedNodeId, (short) 0, null, null);
 
                 RequestHeader requestHeader = new RequestHeader(authenticationToken,
-                                                                System.currentTimeMillis() * 10000L,
+                                                                (System.currentTimeMillis() * 10000) + 116444736000000000L,
                                                                 0L,
                                                                 0L,
-                                                                new PascalString(-1, ""),
+                                                                new PascalString(-1, null),
                                                                 10000L,
                                                                 extObject);
 
@@ -142,7 +141,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                                                                 0L,
                                                                 SecurityTokenRequestType.securityTokenRequestTypeIssue,
                                                                 MessageSecurityMode.messageSecurityModeNone,
-                                                                new PascalString(-1, ""),
+                                                                new PascalString(-1, null),
                                                                 36000000);
 
 
@@ -171,23 +170,23 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                         Integer nextSequenceNumber = opcuaOpenResponse.getSequenceNumber() + 1;
                         Integer nextRequestId = opcuaOpenResponse.getRequestId() + 1;
 
-                        NodeIdTwoByte authenticationToken2 = new NodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,                                                                            
+                        NodeIdTwoByte authenticationToken2 = new NodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
                                                                             new TwoByteNodeId((short) 0));
 
-                        ExpandedNodeId extExpandedNodeId2 = new ExpandedNodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
-                                                                            false,
+                        ExpandedNodeId extExpandedNodeId2 = new ExpandedNodeIdTwoByte(false,
                                                                             false,
-                                                                            new TwoByteNodeId((short) 0),
+                                                                            NodeIdType.nodeIdTypeTwoByte,
                                                                             null,
-                                                                            null);
+                                                                            null,
+                                                                            new TwoByteNodeId((short) 0));
 
                         ExtensionObject extObject2 = new ExtensionObject(extExpandedNodeId2, (short) 0);
 
                         RequestHeader requestHeader2 = new RequestHeader(authenticationToken2,
-                                                                        System.currentTimeMillis() * 10000L,
+                                                                        (System.currentTimeMillis() * 10000) + 116444736000000000L,
                                                                         0L,
                                                                         0L,
-                                                                        new PascalString(-1, ""),
+                                                                        new PascalString(-1, null),
                                                                         10000L,
                                                                         extObject2);
 
@@ -199,8 +198,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                                                                           true,
                                                                           new PascalString(2, "en"),
                                                                           new PascalString(text.length(), text));
-                        PascalString gatewayServerUri = new PascalString(-1, "");
-                        PascalString discoveryProfileUri = new PascalString(-1, "");
+                        PascalString gatewayServerUri = new PascalString(-1, null);
+                        PascalString discoveryProfileUri = new PascalString(-1, null);
                         int noOfDiscoveryUrls = -1;
                         PascalString discoveryUrls = null;
 
@@ -221,11 +220,11 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                                                                         (byte) 0,
                                                                         requestHeader2,
                                                                         clientDescription,
-                                                                        new PascalString(-1, ""),
+                                                                        new PascalString(-1, null),
                                                                         new PascalString(endpoint2.length(), endpoint2),
                                                                         new PascalString(sessionName.length(), sessionName),
                                                                         new PascalString(clientNonce.length(), clientNonce),
-                                                                        new PascalString(-1, ""),
+                                                                        new PascalString(-1, null),
                                                                         120000L,
                                                                         0L);
 
@@ -244,43 +243,59 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                                 LOGGER.debug("Got Create Session Response Connection Response");
                                 CreateSessionResponse createSessionResponse = (CreateSessionResponse) opcuaMessageResponse.getMessage();
 
-                                NodeIdTwoByte authenticationToken3 = (NodeIdTwoByte) createSessionResponse.getAuthenticationToken();
+                                NodeIdByteString authenticationToken3 = (NodeIdByteString) createSessionResponse.getAuthenticationToken();
                                 Integer tokenId2 = (int) opcuaMessageResponse.getSecureTokenId();
                                 Integer channelId2 = (int) opcuaMessageResponse.getSecureChannelId();
                                 Integer nextSequenceNumber2 = opcuaMessageResponse.getSequenceNumber() + 1;
                                 Integer nextRequestId2 = opcuaMessageResponse.getRequestId() + 1;
 
 
-                                ExpandedNodeId extExpandedNodeId3 = new ExpandedNodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
-                                                                                    false,
+                                ExpandedNodeId extExpandedNodeId3 = new ExpandedNodeIdTwoByte(false,
                                                                                     false,
-                                                                                    new TwoByteNodeId((short) 0),
+                                                                                    NodeIdType.nodeIdTypeTwoByte,
                                                                                     null,
-                                                                                    null);
+                                                                                    null,
+                                                                                    new TwoByteNodeId((short) 0));
+                                System.out.println("(((((((((((((((" + extExpandedNodeId3.getLengthInBytes());
 
                                 ExtensionObject extObject3 = new ExtensionObject(extExpandedNodeId3, (short) 0);
 
+                                System.out.println("(((((((((((((((" + extObject3.getLengthInBytes());
+                                System.out.println("(((((((((((((((" + authenticationToken3.getLengthInBytes());
+                                System.out.println("@@@@@@@@@@@@@@@@@" + authenticationToken3.getId().getIdentifier().getStringLength());
+                                System.out.println("@@@@@@@@@@@@@@@@@" + authenticationToken3.getId().getIdentifier().getStringValue().length());
+
                                 RequestHeader requestHeader3 = new RequestHeader(authenticationToken3,
-                                                                                System.currentTimeMillis() * 10000L,
+                                                                                (System.currentTimeMillis() * 10000) + 116444736000000000L,
                                                                                 1L,
                                                                                 0L,
-                                                                                new PascalString(-1, ""),
+                                                                                new PascalString(-1, null),
                                                                                 10000L,
                                                                                 extObject3);
 
-                                SignatureData clientSignature = new SignatureData(new PascalString(-1, ""), new PascalString(-1, ""));
+                                System.out.println("(((((((((((((((" + requestHeader3.getLengthInBytes());
 
-                                SignedSoftwareCertificate[] signedSoftwareCertificate = null;
+                                SignatureData clientSignature = new SignatureData(new PascalString(-1, null), new PascalString(-1, null));
 
-                                ExpandedNodeId extExpandedNodeId4 = new ExpandedNodeIdFourByte(NodeIdType.nodeIdTypeFourByte,
-                                                                                    false,
+                                System.out.println("(((((((((((((((" + clientSignature.getLengthInBytes());
+
+                                SignedSoftwareCertificate[] signedSoftwareCertificate = new SignedSoftwareCertificate[1];
+
+                                signedSoftwareCertificate[0] = new SignedSoftwareCertificate(new PascalString(-1, null), new PascalString(-1, null));
+
+                                ExpandedNodeId extExpandedNodeId4 = new ExpandedNodeIdFourByte(false,
                                                                                     false,
-                                                                                    new FourByteNodeId((short) 0,  321),
+                                                                                    NodeIdType.nodeIdTypeFourByte,
+                                                                                    null,
                                                                                     null,
-                                                                                    null);
+                                                                                    new FourByteNodeId((short) 1,  321));
 
+                                System.out.println("(((((((((((((((" + extExpandedNodeId4.getLengthInBytes());
 
-                                ExtensionObject useridentityToken = new ExtensionObject(extExpandedNodeId4, (short) 0);
+
+                                ExtensionObject useridentityToken = new ExtensionObject(extExpandedNodeId4, (short) 1);
+
+                                System.out.println("(((((((((((((((" + useridentityToken.getLengthInBytes());
 
                                 String endpoint3 = "opc.tcp://127.0.0.1:12687/plc4x";
 
@@ -289,12 +304,14 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                                                                                 requestHeader3,
                                                                                 clientSignature,
                                                                                 0,
-                                                                                signedSoftwareCertificate,
+                                                                                null,
                                                                                 0,
                                                                                 null,
                                                                                 useridentityToken,
                                                                                 clientSignature);
 
+                                System.out.println("(((((((((((((((" + activateSessionRequest.getLengthInBytes());
+
                                 OpcuaMessageRequest activateMessageRequest = new OpcuaMessageRequest("F",
                                                                                 channelId2,
                                                                                 tokenId2,
@@ -302,6 +319,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                                                                                 nextRequestId2,
                                                                                 activateSessionRequest);
 
+                                System.out.println("(((((((((((((((" + activateMessageRequest.getLengthInBytes());
+
                                 context.sendRequest(new OpcuaAPU(activateMessageRequest))
                                     .expectResponse(OpcuaAPU.class, REQUEST_TIMEOUT)
                                     .check(p -> p.getMessage() instanceof OpcuaMessageResponse)
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
index b534ec2..4fcfe44 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
@@ -44,7 +44,7 @@ public class ReadBuffer {
     }
 
     public ReadBuffer(byte[] input, boolean littleEndian) {
-        LOGGER.info("Creating read buffer " + input.length)
+        LOGGER.info("Creating read buffer " + input.length);
         ArrayByteInput abi = new ArrayByteInput(input);
         this.bi = new MyDefaultBitInput(abi);
         this.littleEndian = littleEndian;
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
index 1f6fa85..d05eb8e 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
@@ -28,8 +28,13 @@ import java.math.BigInteger;
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class WriteBuffer {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(WriteBuffer.class);
+
     private final ByteBuffer bb;
     private final BufferByteOutput bbo;
     private final MyDefaultBitOutput bo;
@@ -40,6 +45,7 @@ public class WriteBuffer {
     }
 
     public WriteBuffer(int size, boolean littleEndian) {
+        LOGGER.info("Creating write buffer " + size);
         bb = ByteBuffer.allocate(size);
         bbo = new BufferByteOutput(bb);
         bo = new MyDefaultBitOutput(bbo);
@@ -63,6 +69,7 @@ public class WriteBuffer {
 
     public void writeBit(boolean value) throws ParseException {
         try {
+            LOGGER.info("Writing Bit:- " + value);
             bo.writeBoolean(value);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
@@ -77,6 +84,7 @@ public class WriteBuffer {
             throw new ParseException("unsigned byte can only contain max 8 bits");
         }
         try {
+            LOGGER.info("Writing Usigned Byte:- " + value + ", " + bitLength + ", " + getPos());
             bo.writeByte(true, bitLength, value);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
@@ -91,6 +99,7 @@ public class WriteBuffer {
             throw new ParseException("unsigned short can only contain max 16 bits");
         }
         try {
+            LOGGER.info("Writing Unsigned Short:- " + value + ", " + bitLength + ", " + getPos());
             bo.writeShort(true, bitLength, value);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
@@ -105,6 +114,7 @@ public class WriteBuffer {
             throw new ParseException("unsigned int can only contain max 32 bits");
         }
         try {
+            LOGGER.info("Writing Unisgned Int:- " + value + ", " + bitLength + ", " + getPos());
             if(littleEndian) {
                 value = Integer.reverseBytes(value) >> 16;
             }
@@ -122,6 +132,7 @@ public class WriteBuffer {
             throw new ParseException("unsigned long can only contain max 63 bits");
         }
         try {
+            LOGGER.info("Writing Unsigned Long:- " + value + ", " + bitLength + ", " + getPos());
             if(littleEndian) {
                 value = Long.reverseBytes(value) >> 32;
             }
@@ -167,6 +178,7 @@ public class WriteBuffer {
             throw new ParseException("byte can only contain max 8 bits");
         }
         try {
+            LOGGER.info("Writing Byte:- " + value + ", " + bitLength + ", " + getPos());
             bo.writeByte(false, bitLength, value);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
@@ -181,6 +193,7 @@ public class WriteBuffer {
             throw new ParseException("short can only contain max 16 bits");
         }
         try {
+            LOGGER.info("Writing Short:- " + value + ", " + bitLength + ", " + getPos());
             if(littleEndian) {
                 value = Short.reverseBytes(value);
             }
@@ -198,6 +211,7 @@ public class WriteBuffer {
             throw new ParseException("int can only contain max 32 bits");
         }
         try {
+            LOGGER.info("Writing int:- " + value + ", " + bitLength + ", " + getPos());
             if(littleEndian) {
                 value = Integer.reverseBytes(value);
             }
@@ -215,6 +229,7 @@ public class WriteBuffer {
             throw new ParseException("long can only contain max 64 bits");
         }
         try {
+            LOGGER.info("Writing long:- " + value + ", " + bitLength + ", " + getPos());
             if(littleEndian) {
                 value = Long.reverseBytes(value);
             }
@@ -239,6 +254,7 @@ public class WriteBuffer {
         if (bitsExponent != 8 || bitsMantissa != 23) {
             throw new UnsupportedOperationException("Exponent and/or Mantissa non standard size");
         }
+        LOGGER.info("Writing float:- " + value);
         writeInt(1 + bitsExponent + bitsMantissa, Float.floatToRawIntBits(value));
     }
 
@@ -246,6 +262,7 @@ public class WriteBuffer {
         if (bitsExponent != 11 || bitsMantissa != 52) {
             throw new UnsupportedOperationException("Exponent and/or Mantissa non standard size");
         }
+        LOGGER.info("Writing double:- " + value);
         writeLong(1 + bitsExponent + bitsMantissa, Double.doubleToRawLongBits(value));
     }
 
@@ -254,12 +271,17 @@ public class WriteBuffer {
     }
 
     public void writeString(int bitLength, String encoding, String value) throws ParseException {
-        final byte[] bytes = value.getBytes(Charset.forName(encoding));
+        LOGGER.info("Writing String:- " + value + ", " + bitLength + ", " + getPos());
+        final byte[] bytes = value.getBytes(Charset.forName(encoding.replaceAll("[^a-zA-Z0-9]","")));
         try {
             int count = 0;
-            for (byte aByte : bytes) {                
+            for (byte aByte : bytes) {
+                if (count < (bitLength / 8) || (bitLength == -1)) {
+                    bo.writeByte(false, 8, aByte);
+                } else {
+                    break;
+                }
                 count += 1;
-                bo.writeByte(false, 8, aByte);
             }
         } catch (IOException e) {
            throw new ParseException("Error writing string", e);
diff --git a/protocols/opcua/src/main/xslt/opc-types.xsl b/protocols/opcua/src/main/xslt/opc-types.xsl
index a36a514..c675c8a 100644
--- a/protocols/opcua/src/main/xslt/opc-types.xsl
+++ b/protocols/opcua/src/main/xslt/opc-types.xsl
@@ -113,7 +113,7 @@
 ]
 
 [type 'TwoByteNodeId'
-    <xsl:apply-templates select="/opc:TypeDictionary/opc:StructuredType[@Name='TwoByteNodeId']"/>
+        [simple uint 8 'identifier']
 ]
 
 [type 'FourByteNodeId'
@@ -396,62 +396,44 @@
 ]
 
 [discriminatedType 'ExpandedNodeId'
-    [simple NodeIdType 'nodeIdType']
+    [simple bit 'namespaceURISpecified']
+    [simple bit 'serverIndexSpecified']
+    [discriminator NodeIdType 'nodeIdType']
     [typeSwitch 'nodeIdType'
         ['NodeIdType.nodeIdTypeTwoByte' ExpandedNodeIdTwoByte
-            [simple bit 'serverIndexSpecified']
-            [simple bit 'namespaceURISpecified']
             [simple TwoByteNodeId 'id']
-            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
-            [optional uint 32 'serverIndex' 'serverIndexSpecified']
         ]
         ['NodeIdType.nodeIdTypeFourByte' ExpandedNodeIdFourByte
-            [simple bit 'serverIndexSpecified']
-            [simple bit 'namespaceURISpecified']
             [simple FourByteNodeId 'id']
-            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
-            [optional uint 32 'serverIndex' 'serverIndexSpecified']
         ]
         ['NodeIdType.nodeIdTypeNumeric' ExpandedNodeIdNumeric
-            [simple bit 'serverIndexSpecified']
-            [simple bit 'namespaceURISpecified']
             [simple NumericNodeId 'id']
-            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
-            [optional uint 32 'serverIndex' 'serverIndexSpecified']
         ]
         ['NodeIdType.nodeIdTypeString' ExpandedNodeIdString
-            [simple bit 'serverIndexSpecified']
-            [simple bit 'namespaceURISpecified']
-            [reserved uint 6 '0x00']
             [simple StringNodeId 'id']
-            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
-            [optional uint 32 'serverIndex' 'serverIndexSpecified']
         ]
         ['NodeIdType.nodeIdTypeGuid' ExpandedNodeIdGuid
-            [simple bit 'serverIndexSpecified']
-            [simple bit 'namespaceURISpecified']
             [simple GuidNodeId 'id']
-            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
-            [optional uint 32 'serverIndex' 'serverIndexSpecified']
         ]
         ['NodeIdType.nodeIdTypeByteString' ExpandedNodeIdByteString
-            [simple bit 'serverIndexSpecified']
-            [simple bit 'namespaceURISpecified']
             [simple ByteStringNodeId 'id']
-            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
-            [optional uint 32 'serverIndex' 'serverIndexSpecified']
         ]
     ]
+    [optional PascalString 'namespaceURI' 'namespaceURISpecified']
+    [optional uint 32 'serverIndex' 'serverIndexSpecified']
 ]
 
-[type 'ExtensionObject'
+[discriminatedType 'ExtensionObject'
+    //A serialized object prefixed with its data type identifier.
     [simple ExpandedNodeId 'nodeId']
     [simple uint 8 'encodingMask']
+    [optional int 32 'bodyLength' 'encodingMask > 0']
+    [array uint 8 'body' count 'bodyLength']
 ]
 
 [type 'PascalString'
     [simple int 32 'stringLength']
-    [simple string 'stringLength == -1 ? 0 : stringLength * 8' 'stringValue']
+    [optional string 'stringLength == -1 ? 0 : stringLength * 8' 'UTF-8' 'stringValue' 'stringLength >= 0']
 ]
 
 [type 'LocalizedText'