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

commit 773a691c89ac2b97682b5b631e13cf36afad3972
Author: hutcheb <[email protected]>
AuthorDate: Wed Apr 14 04:21:50 2021 -0400

    Looking at NodeId disriminator issue
---
 build-utils/language-java/pom.xml                  |   1 +
 .../language/java/JavaLanguageTemplateHelper.java  |  22 +
 .../templates/java/pojo-template.java.ftlh         |  25 +-
 .../definitions/DefaultComplexTypeDefinition.java  |   6 +
 plc4j/drivers/opcua/pom.xml                        |   6 +-
 .../opcua/connection/OpcuaTcpPlcConnection.java    | 919 ---------------------
 protocols/opcua/pom.xml                            |  10 +-
 .../src/main/resources/protocols/opcua/opcua.mspec |  10 -
 protocols/opcua/src/main/xslt/opc-types.xsl        |  67 +-
 9 files changed, 79 insertions(+), 987 deletions(-)

diff --git a/build-utils/language-java/pom.xml 
b/build-utils/language-java/pom.xml
index 85438f6..6735743 100644
--- a/build-utils/language-java/pom.xml
+++ b/build-utils/language-java/pom.xml
@@ -108,6 +108,7 @@
         <artifactId>maven-invoker-plugin</artifactId>
         <version>3.2.2</version>
         <configuration>
+          <skipInvocation>${skipTests}</skipInvocation>
           <debug>true</debug>
           <projectsDirectory>src/test/resources</projectsDirectory>
           
<cloneProjectsTo>${project.build.directory}/integration-tests</cloneProjectsTo>
diff --git 
a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
 
b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index 19bbedd..de22ad5 100644
--- 
a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ 
b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -503,23 +503,33 @@ public class JavaLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
     }
 
     public String toSerializationExpression(TypedField field, Term term, 
Argument[] serializerArgments) {
+        System.out.println(field);
+        System.out.println(term);
         return toExpression(field, term, term1 -> 
toVariableSerializationExpression(field, term1, serializerArgments));
     }
 
     private String toExpression(TypedField field, Term term, Function<Term, 
String> variableExpressionGenerator) {
+        System.out.println(field);
+        System.out.println(term);
+
         if (term == null) {
             return "";
         }
         if (term instanceof Literal) {
             if (term instanceof NullLiteral) {
+                System.out.println("Blah10");
                 return "null";
             } else if (term instanceof BooleanLiteral) {
+                System.out.println("Blah11");
                 return Boolean.toString(((BooleanLiteral) term).getValue());
             } else if (term instanceof NumericLiteral) {
+                System.out.println("Blah12");
                 return ((NumericLiteral) term).getNumber().toString();
             } else if (term instanceof StringLiteral) {
+                System.out.println("Blah13");
                 return "\"" + ((StringLiteral) term).getValue() + "\"";
             } else if (term instanceof VariableLiteral) {
+                System.out.println("Blah14");
                 VariableLiteral variableLiteral = (VariableLiteral) term;
                 // If this literal references an Enum type, then we have to 
output it differently.
                 if (getTypeDefinitions().get(variableLiteral.getName()) 
instanceof EnumTypeDefinition) {
@@ -533,6 +543,7 @@ public class JavaLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
                 throw new RuntimeException("Unsupported Literal type " + 
term.getClass().getName());
             }
         } else if (term instanceof UnaryTerm) {
+            System.out.println("Blah15");
             UnaryTerm ut = (UnaryTerm) term;
             Term a = ut.getA();
             switch (ut.getOperation()) {
@@ -546,6 +557,7 @@ public class JavaLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
                     throw new RuntimeException("Unsupported unary operation 
type " + ut.getOperation());
             }
         } else if (term instanceof BinaryTerm) {
+            System.out.println("Blah16");
             BinaryTerm bt = (BinaryTerm) term;
             Term a = bt.getA();
             Term b = bt.getB();
@@ -557,6 +569,7 @@ public class JavaLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
                     return "(" + toExpression(field, a, 
variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, b, 
variableExpressionGenerator) + ")";
             }
         } else if (term instanceof TernaryTerm) {
+            System.out.println("Blah17");
             TernaryTerm tt = (TernaryTerm) term;
             if ("if".equals(tt.getOperation())) {
                 Term a = tt.getA();
@@ -574,6 +587,7 @@ public class JavaLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
     private String toVariableParseExpression(TypedField field, Term term, 
Argument[] parserArguments) {
         VariableLiteral vl = (VariableLiteral) term;
         // CAST expressions are special as we need to add a ".class" to the 
second parameter in Java.
+        System.out.println("Blah1");
         if ("CAST".equals(vl.getName())) {
             StringBuilder sb = new StringBuilder(vl.getName());
             if ((vl.getArgs() == null) || (vl.getArgs().size() != 2)) {
@@ -642,10 +656,12 @@ public class JavaLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
         }
         // If we are accessing implicit fields, we need to rely on a local 
variable instead.
         else if (isVariableLiteralImplicitField(vl)) {
+            System.out.println("Blah2");
             return vl.getName();
         }
         // All uppercase names are not fields, but utility methods.
         else if (vl.getName().equals(vl.getName().toUpperCase())) {
+            System.out.println("Blah3");
             StringBuilder sb = new StringBuilder(vl.getName());
             if (vl.getArgs() != null) {
                 sb.append("(");
@@ -662,12 +678,18 @@ public class JavaLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
             if (vl.getIndex() != VariableLiteral.NO_INDEX) {
                 sb.append("[").append(vl.getIndex()).append("]");
             }
+            System.out.println("Blah4");
             return sb.toString() + ((vl.getChild() != null) ? "." + 
toVariableExpressionRest(vl.getChild()) : "");
         }
+        System.out.println("Blah5");
         return vl.getName() + ((vl.getChild() != null) ? "." + 
toVariableExpressionRest(vl.getChild()) : "");
     }
 
     private String toVariableSerializationExpression(TypedField field, Term 
term, Argument[] serialzerArguments) {
+        System.out.println(field);
+        System.out.println(term);
+        System.out.println(serialzerArguments);
+
         VariableLiteral vl = (VariableLiteral) term;
         if ("STATIC_CALL".equals(vl.getName())) {
             StringBuilder sb = new StringBuilder();
diff --git 
a/build-utils/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
 
b/build-utils/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
index dad0cf8..6e0aff3 100644
--- 
a/build-utils/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
+++ 
b/build-utils/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
@@ -23,7 +23,7 @@
 <#-- @ftlvariable name="protocolName" type="java.lang.String" -->
 <#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
 <#-- @ftlvariable name="helper" 
type="org.apache.plc4x.language.java.JavaLanguageTemplateHelper" -->
-<#-- @ftlvariable name="type" 
type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition"
 -->
+<#-- @ftlvariable name="type" 
type="org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.DefaultComplexTypeDefinition"
 -->
 <#-- Declare the name and type of variables declared locally inside the 
template -->
 <#-- @ftlvariable name="arrayField" 
type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
 <#-- @ftlvariable name="checksumField" 
type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
@@ -151,20 +151,24 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> 
abstract</#if> class ${
 </#list>
     }
 
+<#list type.getAbstractFields() as field>
+    public abstract ${helper.getLanguageTypeNameForField(field)}<#if 
field.loopType??>[]</#if> get${field.name?cap_first}();
+
+</#list>
+
 <#list type.propertyFields as field>
-    <#if helper.isAbstractField(field)>
-    public ${helper.getLanguageTypeNameForField(field)}<#if 
field.loopType??>[]</#if> abstract get${field.name?cap_first}();
-    <#else>
     public ${helper.getLanguageTypeNameForField(field)}<#if 
field.loopType??>[]</#if> get${field.name?cap_first}() {
         return ${field.name};
     }
-    </#if>
 
 </#list>
+
 <#list type.virtualFields as field>
+    <#if helper.isNonDiscriminatorField(field.name)>
     public ${helper.getLanguageTypeNameForField(field)}<#if 
field.loopType??>[]</#if> get${field.name?cap_first}() {
         return (${helper.getLanguageTypeNameForField(field)}) 
(${helper.toParseExpression(field, field.valueExpression, 
type.parserArguments)});
     }
+    </#if>
 
 </#list>
     @Override
@@ -216,9 +220,9 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> 
abstract</#if> class ${
         <#if helper.isSimpleTypeReference(discriminatorField.type)>
             <#assign simpleTypeReference = discriminatorField.type>
             <#if 
helper.getLanguageTypeNameForTypeReference(discriminatorField.type) = "String">
-                lengthInBits += 
${toSerializationExpression(discriminatorField, 
simpleTypeReference.getLengthExpression(), type.parserArguments)};
+        lengthInBits += ${helper.toSerializationExpression(discriminatorField, 
simpleTypeReference.getLengthExpression(), type.parserArguments)};
             <#else>
-                lengthInBits += ${simpleTypeReference.sizeInBits};
+        lengthInBits += ${simpleTypeReference.sizeInBits};
             </#if>
         <#elseif helper.isEnumField(field)>
             lengthInBits += 
${helper.getEnumBaseTypeReference(discriminatorField.type).sizeInBits};
@@ -258,12 +262,11 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> 
abstract</#if> class ${
         // Optional Field (${optionalField.name})
         if(${optionalField.name} != null) {
         <#if helper.isSimpleTypeReference(optionalField.type)>
+            <#assign simpleTypeReference = optionalField.type>
             <#if 
helper.getLanguageTypeNameForTypeReference(optionalField.type) = "String">
-                <#assign simpleTypeReference = optionalField.type>
-    lengthInBits += ${simpleTypeReference.getLength()};
+            lengthInBits += 
${helper.toSerializationExpression(discriminatorField, 
simpleTypeReference.getLengthExpression(), type.parserArguments)};
             <#else>
-                <#assign simpleTypeReference = optionalField.type>
-    lengthInBits += ${simpleTypeReference.sizeInBits};
+            lengthInBits += ${simpleTypeReference.sizeInBits};
             </#if>
         <#elseif helper.isEnumField(field)>
             lengthInBits += 
${helper.getEnumBaseTypeReference(optionalField.type).sizeInBits};
diff --git 
a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultComplexTypeDefinition.java
 
b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultComplexTypeDefinition.java
index 39d87f4..7ab0431 100644
--- 
a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultComplexTypeDefinition.java
+++ 
b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultComplexTypeDefinition.java
@@ -22,6 +22,7 @@ package 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions;
 import org.apache.plc4x.plugins.codegenerator.types.definitions.Argument;
 import 
org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition;
 import org.apache.plc4x.plugins.codegenerator.types.fields.*;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 
 import java.util.Collections;
 import java.util.LinkedList;
@@ -65,6 +66,11 @@ public class DefaultComplexTypeDefinition extends 
DefaultTypeDefinition implemen
             .collect(Collectors.toList());
     }
 
+    public List<AbstractField> getAbstractFields() {
+        return fields.stream().filter(field -> field instanceof 
AbstractField).map(
+            field -> (AbstractField) field).collect(Collectors.toList());
+    }
+
     @Override
     public List<VirtualField> getVirtualFields() {
         return fields.stream().filter(field -> (field instanceof 
VirtualField)).map(field -> (VirtualField) field)
diff --git a/plc4j/drivers/opcua/pom.xml b/plc4j/drivers/opcua/pom.xml
index 897ff1b..d23eab6 100644
--- a/plc4j/drivers/opcua/pom.xml
+++ b/plc4j/drivers/opcua/pom.xml
@@ -124,17 +124,17 @@
       <dependency>
         <groupId>org.apache.plc4x</groupId>
         <artifactId>plc4j-transport-tcp</artifactId>
-        <version>0.8.0-SNAPSHOT</version>
+        <version>0.9.0-SNAPSHOT</version>
       </dependency>
       <dependency>
         <groupId>org.apache.plc4x</groupId>
         <artifactId>plc4j-transport-serial</artifactId>
-        <version>0.8.0-SNAPSHOT</version>
+        <version>0.9.0-SNAPSHOT</version>
       </dependency>
       <dependency>
         <groupId>org.apache.plc4x</groupId>
         <artifactId>plc4j-transport-raw-socket</artifactId>
-        <version>0.8.0-SNAPSHOT</version>
+        <version>0.9.0-SNAPSHOT</version>
       </dependency>
 
 
diff --git 
a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java
 
b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java
deleted file mode 100644
index 458d5f1..0000000
--- 
a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/connection/OpcuaTcpPlcConnection.java
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
-
- */
-package org.apache.plc4x.java.opcua.connection;
-
-import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-import org.apache.plc4x.java.api.messages.*;
-import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
-import org.apache.plc4x.java.api.model.PlcField;
-import org.apache.plc4x.java.api.model.PlcSubscriptionField;
-import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
-import org.apache.plc4x.java.api.types.PlcResponseCode;
-import org.apache.plc4x.java.api.value.*;
-import org.apache.plc4x.java.opcua.protocol.OpcuaField;
-import org.apache.plc4x.java.opcua.protocol.OpcuaSubsriptionHandle;
-import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
-import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
-import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField;
-import org.apache.plc4x.java.spi.values.*;
-import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
-import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
-import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
-import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider;
-import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
-import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
-import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
-import org.eclipse.milo.opcua.stack.core.AttributeId;
-import org.eclipse.milo.opcua.stack.core.Identifiers;
-import org.eclipse.milo.opcua.stack.core.UaException;
-import org.eclipse.milo.opcua.stack.core.StatusCodes;
-import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
-import org.eclipse.milo.opcua.stack.core.types.builtin.*;
-import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.*;
-import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
-import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
-import org.eclipse.milo.opcua.stack.core.types.structured.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.math.BigInteger;
-import java.math.BigDecimal;
-import java.util.stream.Collectors;
-import java.net.InetAddress;
-import java.time.Duration;
-import java.time.LocalDateTime;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Predicate;
-
-import static 
org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
-import static 
org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ulong;
-
-/**
- * Corresponding implementaion for a TCP-based connection for an OPC UA server.
- * TODO: At the moment are just connections without any security mechanism 
possible
- * <p>
- */
-public class OpcuaTcpPlcConnection extends BaseOpcuaPlcConnection {
-
-    private static final int OPCUA_DEFAULT_TCP_PORT = 4840;
-
-    private static final Logger logger = 
LoggerFactory.getLogger(OpcuaTcpPlcConnection.class);
-    private final AtomicLong clientHandles = new AtomicLong(1L);
-    private InetAddress address;
-    private int requestTimeout = 5000;
-    private int port;
-    private String params;
-    private OpcUaClient client;
-    private boolean isConnected = false;
-
-    private OpcuaTcpPlcConnection(InetAddress address, String params, int 
requestTimeout) {
-        this(address, OPCUA_DEFAULT_TCP_PORT, params, requestTimeout);
-        logger.info("Configured OpcuaTcpPlcConnection with: host-name {}", 
address.getHostAddress());
-    }
-
-    private OpcuaTcpPlcConnection(InetAddress address, int port, String 
params, int requestTimeout) {
-        this(params);
-        logger.info("Configured OpcuaTcpPlcConnection with: host-name {}", 
address.getHostAddress());
-        this.address = address;
-        this.port = port;
-        this.params = params;
-        this.requestTimeout = requestTimeout;
-    }
-
-    private OpcuaTcpPlcConnection(String params) {
-        super(getOptionString(params));
-    }
-
-    public static OpcuaTcpPlcConnection of(InetAddress address, String params, 
int requestTimeout) {
-        return new OpcuaTcpPlcConnection(address, params, requestTimeout);
-    }
-
-    public static OpcuaTcpPlcConnection of(InetAddress address, int port, 
String params, int requestTimeout) {
-        return new OpcuaTcpPlcConnection(address, port, params, 
requestTimeout);
-    }
-
-    public static PlcValue encodePlcValue(DataValue value) {
-        ExpandedNodeId typeNode = value.getValue().getDataType().get();
-        Object objValue = value.getValue().getValue();
-
-        if (objValue.getClass().isArray()) {
-            Object[] objArray = (Object[]) objValue;
-            if (objArray[0] instanceof Boolean) {
-                Boolean[] obj = (Boolean[]) objValue;
-                List<PlcValue> plcValue;
-                {
-                    int itemCount = (int) obj.length;
-                    plcValue = new LinkedList<>();
-
-                    for(int curItem = 0; curItem < itemCount; curItem++) {
-                        plcValue.add(new PlcBOOL((Boolean) obj[curItem]));
-                    }
-                }
-                return new PlcList(plcValue);
-            } else if (objArray[0] instanceof Integer) {
-                Integer[] obj = (Integer[]) objValue;
-                List<PlcValue> plcValue;
-                {
-                    int itemCount = (int) obj.length;
-                    plcValue = new LinkedList<>();
-
-                    for(int curItem = 0; curItem < itemCount; curItem++) {
-                        plcValue.add(new PlcDINT((Integer) obj[curItem]));
-                    }
-                }
-                return new PlcList(plcValue);
-            } else if (objArray[0] instanceof Short) {
-                Short[] obj = (Short[]) objValue;
-                List<PlcValue> plcValue;
-                {
-                    int itemCount = (int) obj.length;
-                    plcValue = new LinkedList<>();
-
-                    for(int curItem = 0; curItem < itemCount; curItem++) {
-                        plcValue.add(new PlcINT((Short) obj[curItem]));
-                    }
-                }
-                return new PlcList(plcValue);
-            } else if (objArray[0] instanceof Byte) {
-                Byte[] obj = (Byte[]) objValue;
-                List<PlcValue> plcValue;
-                {
-                    int itemCount = (int) obj.length;
-                    plcValue = new LinkedList<>();
-
-                    for(int curItem = 0; curItem < itemCount; curItem++) {
-                        plcValue.add(new PlcSINT((Byte) obj[curItem]));
-                    }
-                }
-                return new PlcList(plcValue);
-            } else if (objArray[0] instanceof Long) {
-                Long[] obj = (Long[]) objValue;
-                List<PlcValue> plcValue;
-                {
-                    int itemCount = (int) obj.length;
-                    plcValue = new LinkedList<>();
-
-                    for(int curItem = 0; curItem < itemCount; curItem++) {
-                        plcValue.add(new PlcLINT((Long) obj[curItem]));
-                    }
-                }
-                return new PlcList(plcValue);
-            } else if (objArray[0] instanceof Float) {
-                Float[] obj = (Float[]) objValue;
-                List<PlcValue> plcValue;
-                {
-                    int itemCount = (int) obj.length;
-                    plcValue = new LinkedList<>();
-
-                    for(int curItem = 0; curItem < itemCount; curItem++) {
-                        plcValue.add(new PlcREAL((Float) obj[curItem]));
-                    }
-                }
-                return new PlcList(plcValue);
-            } else if (objArray[0] instanceof Double) {
-                Double[] obj = (Double[]) objValue;
-                List<PlcValue> plcValue;
-                {
-                    int itemCount = (int) obj.length;
-                    plcValue = new LinkedList<>();
-
-                    for(int curItem = 0; curItem < itemCount; curItem++) {
-                        plcValue.add(new PlcLREAL((Double) obj[curItem]));
-                    }
-                }
-                return new PlcList(plcValue);
-            } else if (objArray[0] instanceof String) {
-                String[] obj = (String[]) objValue;
-                List<PlcValue> plcValue;
-                {
-                    int itemCount = (int) obj.length;
-                    plcValue = new LinkedList<>();
-
-                    for(int curItem = 0; curItem < itemCount; curItem++) {
-                        plcValue.add(new PlcSTRING((String) obj[curItem]));
-                    }
-                }
-                return new PlcList(plcValue);
-            } else {
-                logger.warn("Node type for " + objArray[0].getClass() + " is 
not supported");
-                return null;
-            }
-
-        } else {
-            if (typeNode.equals(Identifiers.Boolean)) {
-                return new PlcBOOL((Boolean) objValue);
-            } else if (typeNode.equals(Identifiers.Integer)) {
-                return new PlcDINT((Integer) objValue);
-            } else if (typeNode.equals(Identifiers.Int16)) {
-                return new PlcINT((Short) objValue);
-            } else if (typeNode.equals(Identifiers.Int32)) {
-                return new PlcDINT((Integer) objValue);
-            } else if (typeNode.equals(Identifiers.Int64)) {
-                return new PlcLINT((Long) objValue);
-            } else if (typeNode.equals(Identifiers.UInteger)) {
-                return new PlcLINT((Long) objValue);
-            } else if (typeNode.equals(Identifiers.UInt16)) {
-                return new PlcUINT(((UShort) objValue).intValue());
-            } else if (typeNode.equals(Identifiers.UInt32)) {
-                return new PlcUDINT(((UInteger) objValue).longValue());
-            } else if (typeNode.equals(Identifiers.UInt64)) {
-                return new PlcULINT(new BigInteger(objValue.toString()));
-            } else if (typeNode.equals(Identifiers.Byte)) {
-                return new PlcINT(Short.valueOf(objValue.toString()));
-            } else if (typeNode.equals(Identifiers.Float)) {
-                return new PlcREAL((Float) objValue);
-            } else if (typeNode.equals(Identifiers.Double)) {
-                return new PlcLREAL((Double) objValue);
-            } else if (typeNode.equals(Identifiers.SByte)) {
-                return new PlcSINT((Byte) objValue);
-            } else {
-                return new PlcSTRING(objValue.toString());
-            }
-        }
-
-    }
-
-    public InetAddress getRemoteAddress() {
-        return address;
-    }
-
-    @Override
-    public void connect() throws PlcConnectionException {
-        List<EndpointDescription> endpoints = null;
-        EndpointDescription endpoint = null;
-
-        try {
-            endpoints = DiscoveryClient.getEndpoints(getEndpointUrl(address, 
port, getSubPathOfParams(params))).get();
-            //TODO Exception should be handeled better when the Discovery-API 
of Milo is stable
-        } catch (Exception ex) {
-            logger.info("Failed to discover Endpoint with enabled discovery. 
If the endpoint does not allow a correct discovery disable this option with the 
nDiscovery=true option. Failed Endpoint: {}", getEndpointUrl(address, port, 
params));
-
-            // try the explicit discovery endpoint as well
-            String discoveryUrl = getEndpointUrl(address, port, 
getSubPathOfParams(params));
-
-            if (!discoveryUrl.endsWith("/")) {
-                discoveryUrl += "/";
-            }
-            discoveryUrl += "discovery";
-
-            logger.info("Trying explicit discovery URL: {}", discoveryUrl);
-            try {
-                endpoints = DiscoveryClient.getEndpoints(discoveryUrl).get();
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                throw new PlcConnectionException("Unable to discover URL:" + 
discoveryUrl);
-            } catch (ExecutionException e) {
-                throw new PlcConnectionException("Unable to discover URL:" + 
discoveryUrl);
-            }
-
-        }
-        endpoint = endpoints.stream()
-            .filter(e -> 
e.getSecurityPolicyUri().equals(getSecurityPolicy().getUri()))
-            .filter(endpointFilter())
-            .findFirst()
-            .orElseThrow(() -> new PlcConnectionException("No desired 
endpoints from"));
-
-        if (this.skipDiscovery) {
-            //ApplicationDescription applicationDescription = new 
ApplicationDescription();
-            //endpoint = new 
EndpointDescription(address.getHostAddress(),applicationDescription , null, 
MessageSecurityMode.None, SecurityPolicy.None.getUri(), null , 
TransportProfile.TCP_UASC_UABINARY.getUri(), UByte.valueOf(0));// TODO hier 
machen wenn fertig
-            ApplicationDescription currentAD = endpoint.getServer();
-            ApplicationDescription withoutDiscoveryAD = new 
ApplicationDescription(
-                currentAD.getApplicationUri(),
-                currentAD.getProductUri(),
-                currentAD.getApplicationName(),
-                currentAD.getApplicationType(),
-                currentAD.getGatewayServerUri(),
-                currentAD.getDiscoveryProfileUri(),
-                new String[0]);
-            //try to replace the overhanded address
-            //any error will result in the overhanded address of the client
-            String newEndpointUrl = endpoint.getEndpointUrl(), prefix = "", 
suffix = "";
-            String splitterPrefix = "://";
-            String splitterSuffix = ":";
-            String[] prefixSplit = newEndpointUrl.split(splitterPrefix);
-            if (prefixSplit.length > 1) {
-                String[] suffixSplit = prefixSplit[1].split(splitterSuffix);
-                //reconstruct the uri
-                newEndpointUrl = "";
-                newEndpointUrl += prefixSplit[0] + splitterPrefix + 
address.getHostAddress();
-                for (int suffixCounter = 1; suffixCounter < 
suffixSplit.length; suffixCounter++) {
-                    newEndpointUrl += splitterSuffix + 
suffixSplit[suffixCounter];
-                }
-                // attach surounding prefix match
-                for (int prefixCounter = 2; prefixCounter < 
prefixSplit.length; prefixCounter++) {
-                    newEndpointUrl += splitterPrefix + 
prefixSplit[prefixCounter];
-                }
-            }
-
-            EndpointDescription noDiscoverEndpoint = new EndpointDescription(
-                newEndpointUrl,
-                withoutDiscoveryAD,
-                endpoint.getServerCertificate(),
-                endpoint.getSecurityMode(),
-                endpoint.getSecurityPolicyUri(),
-                endpoint.getUserIdentityTokens(),
-                endpoint.getTransportProfileUri(),
-                endpoint.getSecurityLevel());
-            endpoint = noDiscoverEndpoint;
-        }
-
-
-        OpcUaClientConfig config = OpcUaClientConfig.builder()
-            .setApplicationName(LocalizedText.english("eclipse milo opc-ua 
client of the apache PLC4X:PLC4J project"))
-            .setApplicationUri("urn:eclipse:milo:plc4x:client")
-            .setEndpoint(endpoint)
-            .setIdentityProvider(getIdentityProvider())
-            .setRequestTimeout(UInteger.valueOf(requestTimeout))
-            .build();
-
-        try {
-            this.client = OpcUaClient.create(config);
-            this.client.connect().get();
-            isConnected = true;
-        } catch (UaException e) {
-            isConnected = false;
-            String message = (config == null) ? "NULL" : config.toString();
-            throw new PlcConnectionException("The given input values are a not 
valid OPC UA connection configuration [CONFIG]: " + message);
-        } catch (InterruptedException e) {
-            isConnected = false;
-            Thread.currentThread().interrupt();
-            throw new PlcConnectionException("Error while creation of the 
connection because of : " + e.getMessage());
-        } catch (ExecutionException e) {
-            isConnected = false;
-            throw new PlcConnectionException("Error while creation of the 
connection because of : " + e.getMessage());
-        }
-    }
-
-    @Override
-    public boolean isConnected() {
-        return client != null && isConnected;
-    }
-
-    @Override
-    public void close() throws Exception {
-        if (client != null) {
-            client.disconnect().get();
-            isConnected = false;
-        }
-    }
-
-    @Override
-    public CompletableFuture<PlcSubscriptionResponse> 
subscribe(PlcSubscriptionRequest subscriptionRequest) {
-        CompletableFuture<PlcSubscriptionResponse> future = 
CompletableFuture.supplyAsync(() -> {
-            Map<String, ResponseItem<PlcSubscriptionHandle>> responseItems = 
new HashMap<>();
-            for (String fieldName : subscriptionRequest.getFieldNames()) {
-                final DefaultPlcSubscriptionField subscriptionField = 
(DefaultPlcSubscriptionField) subscriptionRequest.getField(fieldName);
-                final OpcuaField field = (OpcuaField) 
Objects.requireNonNull(subscriptionField.getPlcField());
-                long cycleTime = 
subscriptionField.getDuration().orElse(Duration.ofSeconds(1)).toMillis();
-                NodeId idNode = generateNodeId(field);
-                ReadValueId readValueId = new ReadValueId(
-                    idNode,
-                    AttributeId.Value.uid(), null, QualifiedName.NULL_VALUE);
-                UInteger clientHandle = uint(clientHandles.getAndIncrement());
-
-                MonitoringMode monitoringMode;
-                switch (subscriptionField.getPlcSubscriptionType()) {
-                    case CYCLIC:
-                        monitoringMode = MonitoringMode.Sampling;
-                        break;
-                    case CHANGE_OF_STATE:
-                        monitoringMode = MonitoringMode.Reporting;
-                        cycleTime = 
subscriptionField.getDuration().orElse(Duration.ofSeconds(0)).toMillis();
-                        break;
-                    case EVENT:
-                        monitoringMode = MonitoringMode.Reporting;
-                        break;
-                    default:
-                        monitoringMode = MonitoringMode.Reporting;
-                }
-
-                MonitoringParameters parameters = new MonitoringParameters(
-                    clientHandle,
-                    (double) cycleTime,     // sampling interval
-                    null,       // filter, null means use default
-                    uint(1),   // queue size
-                    true        // discard oldest
-                );
-
-                PlcSubscriptionHandle subHandle = null;
-                PlcResponseCode responseCode = PlcResponseCode.ACCESS_DENIED;
-                try {
-                    UaSubscription subscription = 
client.getSubscriptionManager().createSubscription(cycleTime).get();
-
-                    MonitoredItemCreateRequest request = new 
MonitoredItemCreateRequest(
-                        readValueId, monitoringMode, parameters);
-                    List<MonitoredItemCreateRequest> requestList = new 
LinkedList<>();
-                    requestList.add(request);
-                    OpcuaSubsriptionHandle subsriptionHandle = new 
OpcuaSubsriptionHandle(fieldName, clientHandle);
-                    BiConsumer<UaMonitoredItem, Integer> onItemCreated =
-                        (item, id) -> 
item.setValueConsumer(subsriptionHandle::onSubscriptionValue);
-
-                    List<UaMonitoredItem> items = 
subscription.createMonitoredItems(
-                        TimestampsToReturn.Both,
-                        requestList,
-                        onItemCreated
-                    ).get();
-
-                    subHandle = subsriptionHandle;
-                    responseCode = PlcResponseCode.OK;
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                    logger.warn("Unable to subscribe Elements because of: {}", 
e.getMessage());
-                } catch (ExecutionException e) {
-                    logger.warn("Unable to subscribe Elements because of: {}", 
e.getMessage());
-                }
-
-                responseItems.put(fieldName, new ResponseItem(responseCode, 
subHandle));
-            }
-            return new DefaultPlcSubscriptionResponse(subscriptionRequest, 
responseItems);
-        });
-
-        return future;
-    }
-
-    @Override
-    public CompletableFuture<PlcUnsubscriptionResponse> 
unsubscribe(PlcUnsubscriptionRequest unsubscriptionRequest) {
-        unsubscriptionRequest.getSubscriptionHandles().forEach(o -> {
-            OpcuaSubsriptionHandle opcSubHandle = (OpcuaSubsriptionHandle) o;
-            try {
-                
client.getSubscriptionManager().deleteSubscription(opcSubHandle.getClientHandle()).get();
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                logger.warn("Unable to unsubscribe Elements because of: {}", 
e.getMessage());
-            } catch (ExecutionException e) {
-                logger.warn("Unable to unsubscribe Elements because of: {}", 
e.getMessage());
-            }
-        });
-
-        return null;
-    }
-
-    @Override
-    public PlcConsumerRegistration register(Consumer<PlcSubscriptionEvent> 
consumer, Collection<PlcSubscriptionHandle> handles) {
-        List<PlcConsumerRegistration> registrations = new LinkedList<>();
-        // Register the current consumer for each of the given subscription 
handles
-        for (PlcSubscriptionHandle subscriptionHandle : handles) {
-            final PlcConsumerRegistration consumerRegistration = 
subscriptionHandle.register(consumer);
-            registrations.add(consumerRegistration);
-        }
-
-        return new DefaultPlcConsumerRegistration(this, consumer, 
handles.toArray(new PlcSubscriptionHandle[0]));
-    }
-
-    @Override
-    public void unregister(PlcConsumerRegistration registration) {
-        registration.unregister();
-    }
-
-    @Override
-    public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) 
{
-        CompletableFuture<PlcReadResponse> future = 
CompletableFuture.supplyAsync(() -> {
-            readRequest.getFields();
-            Map<String, ResponseItem<PlcValue>> fields = new HashMap<>();
-            List<NodeId> readValueIds = new LinkedList<>();
-            List<PlcField> readPLCValues = readRequest.getFields();
-            for (PlcField field : readPLCValues) {
-                NodeId idNode = generateNodeId((OpcuaField) field);
-                readValueIds.add(idNode);
-            }
-
-            CompletableFuture<List<DataValue>> dataValueCompletableFuture = 
client.readValues(0.0, TimestampsToReturn.Both, readValueIds);
-            List<DataValue> readValues = null;
-            try {
-                readValues = dataValueCompletableFuture.get();
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                logger.warn("Unable to read Elements because of: {}", 
e.getMessage());
-            } catch (ExecutionException e) {
-                logger.warn("Unable to read Elements because of: {}", 
e.getMessage());
-            }
-            for (int counter = 0; counter < readValueIds.size(); counter++) {
-                PlcResponseCode resultCode = PlcResponseCode.OK;
-                PlcValue stringItem = null;
-                if (readValues == null || readValues.size() <= counter ||
-                    
!readValues.get(counter).getStatusCode().equals(StatusCode.GOOD)) {
-                    resultCode = PlcResponseCode.NOT_FOUND;
-                } else {
-                    stringItem = encodePlcValue(readValues.get(counter));
-
-                }
-                ResponseItem<PlcValue> newPair = new 
ResponseItem<>(resultCode, stringItem);
-                fields.put((String) 
readRequest.getFieldNames().toArray()[counter], newPair);
-
-
-            }
-            return new DefaultPlcReadResponse(readRequest, fields);
-        });
-
-        return future;
-    }
-
-
-    @Override
-    public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest 
writeRequest) {
-        CompletableFuture<PlcWriteResponse> future;
-        future = CompletableFuture.supplyAsync(() -> {
-            List<PlcField> writePLCValues = writeRequest.getFields();
-            LinkedList<DataValue> values = new LinkedList<>();
-            LinkedList<NodeId> ids = new LinkedList<>();
-            LinkedList<String> names = new LinkedList<>();
-            Map<String, PlcResponseCode> fieldResponse = new HashMap<>();
-            for (String fieldName : writeRequest.getFieldNames()) {
-                OpcuaField uaField = (OpcuaField) 
writeRequest.getField(fieldName);
-                NodeId idNode = generateNodeId(uaField);
-                Object valueObject = 
writeRequest.getPlcValue(fieldName).getObject();
-                // Added small work around for handling BigIntegers as input 
type for UInt64
-                if (valueObject instanceof BigInteger) valueObject = 
ulong((BigInteger) valueObject);
-                Variant var = null;
-                if (valueObject instanceof ArrayList) {
-                    List<PlcValue> plcValueList = (List<PlcValue>) valueObject;
-                    String dataType = uaField.getPlcDataType();
-                    if (dataType.equals("NULL")) {
-                        if (plcValueList.get(0).getObject() instanceof 
Boolean) {
-                            dataType = "BOOL";
-                        } else if (plcValueList.get(0).getObject() instanceof 
Byte) {
-                            dataType = "SINT";
-                        } else if (plcValueList.get(0).getObject() instanceof 
Short) {
-                            dataType = "INT";
-                        } else if (plcValueList.get(0).getObject() instanceof 
Integer) {
-                            dataType = "DINT";
-                        } else if (plcValueList.get(0).getObject() instanceof 
Long) {
-                            dataType = "LINT";
-                        } else if (plcValueList.get(0).getObject() instanceof 
Float) {
-                            dataType = "REAL";
-                        } else if (plcValueList.get(0).getObject() instanceof 
Double) {
-                            dataType = "LREAL";
-                        } else if (plcValueList.get(0).getObject() instanceof 
String) {
-                            dataType = "STRING";
-                        }
-                    }
-                    switch (dataType) {
-                        case "BOOL":
-                        case "BIT":
-                            List<Boolean> booleanList = 
(plcValueList).stream().map(
-                                    x -> ((PlcBOOL) 
x).getBoolean()).collect(Collectors.toList());
-                            var = new Variant(booleanList.toArray(new 
Boolean[booleanList.size()]));
-                            break;
-                        case "BYTE":
-                        case "BITARR8":
-                            List<UByte> byteList = (plcValueList).stream().map(
-                                    x -> UByte.valueOf(((PlcBYTE) 
x).getShort())).collect(Collectors.toList());
-                            var = new Variant(byteList.toArray(new 
UByte[byteList.size()]));
-                            break;
-                        case "SINT":
-                        case "INT8":
-                            List<Byte> sintList = (plcValueList).stream().map(
-                                    x -> ((PlcSINT) 
x).getByte()).collect(Collectors.toList());
-                            var = new Variant(sintList.toArray(new 
Byte[sintList.size()]));
-                            break;
-                        case "USINT":
-                        case "UINT8":
-                        case "BIT8":
-                            List<UByte> usintList = 
(plcValueList).stream().map(
-                                    x -> UByte.valueOf(((PlcUSINT) 
x).getShort())).collect(Collectors.toList());
-                            var = new Variant(usintList.toArray(new 
UByte[usintList.size()]));
-                            break;
-                        case "INT":
-                        case "INT16":
-                            List<Short> intList = (plcValueList).stream().map(
-                                    x -> ((PlcINT) 
x).getShort()).collect(Collectors.toList());
-                            var = new Variant(intList.toArray(new 
Short[intList.size()]));
-                            break;
-                        case "UINT":
-                        case "UINT16":
-                            List<UShort> uintList = 
(plcValueList).stream().map(
-                                    x -> UShort.valueOf(((PlcUINT) 
x).getInteger())).collect(Collectors.toList());
-                            var = new Variant(uintList.toArray(new 
UShort[uintList.size()]));
-                            break;
-                        case "WORD":
-                        case "BITARR16":
-                            List<UShort> wordList = 
(plcValueList).stream().map(
-                                    x -> UShort.valueOf(((PlcWORD) 
x).getInteger())).collect(Collectors.toList());
-                            var = new Variant(wordList.toArray(new 
UShort[wordList.size()]));
-                            break;
-                        case "DINT":
-                        case "INT32":
-                            List<Integer> dintList = 
(plcValueList).stream().map(
-                                    x -> ((PlcDINT) 
x).getInteger()).collect(Collectors.toList());
-                            var = new Variant(dintList.toArray(new 
Integer[dintList.size()]));
-                            break;
-                        case "UDINT":
-                        case "UINT32":
-                            List<UInteger> udintList = 
(plcValueList).stream().map(
-                                    x -> UInteger.valueOf(((PlcUDINT) 
x).getLong())).collect(Collectors.toList());
-                            var = new Variant(udintList.toArray(new 
UInteger[udintList.size()]));
-                            break;
-                        case "DWORD":
-                        case "BITARR32":
-                            List<UInteger> dwordList = 
(plcValueList).stream().map(
-                                    x -> UInteger.valueOf(((PlcDWORD) 
x).getLong())).collect(Collectors.toList());
-                            var = new Variant(dwordList.toArray(new 
UInteger[dwordList.size()]));
-                            break;
-                        case "LINT":
-                        case "INT64":
-                            List<Long> lintList = (plcValueList).stream().map(
-                                    x -> ((PlcLINT) 
x).getLong()).collect(Collectors.toList());
-                            var = new Variant(lintList.toArray(new 
Long[lintList.size()]));
-                            break;
-                        case "ULINT":
-                        case "UINT64":
-                            List<ULong> ulintList = 
(plcValueList).stream().map(
-                                    x -> ULong.valueOf(((PlcULINT) 
x).getBigInteger())).collect(Collectors.toList());
-                            var = new Variant(ulintList.toArray(new 
ULong[ulintList.size()]));
-                            break;
-                        case "LWORD":
-                        case "BITARR64":
-                            List<ULong> lwordList = 
(plcValueList).stream().map(
-                                    x -> ULong.valueOf(((PlcLWORD) 
x).getBigInteger())).collect(Collectors.toList());
-                            var = new Variant(lwordList.toArray(new 
ULong[lwordList.size()]));
-                            break;
-                        case "REAL":
-                        case "FLOAT":
-                            List<Float> realList = (plcValueList).stream().map(
-                                    x -> ((PlcREAL) 
x).getFloat()).collect(Collectors.toList());
-                            var = new Variant(realList.toArray(new 
Float[realList.size()]));
-                            break;
-                        case "LREAL":
-                        case "DOUBLE":
-                            List<Double> lrealList = 
(plcValueList).stream().map(
-                                    x -> (Double) ((PlcLREAL) 
x).getDouble()).collect(Collectors.toList());
-                            var = new Variant(lrealList.toArray(new 
Double[lrealList.size()]));
-                            break;
-                        case "CHAR":
-                            List<String> charList = 
(plcValueList).stream().map(
-                                    x -> ((PlcCHAR) 
x).getString()).collect(Collectors.toList());
-                            var = new Variant(charList.toArray(new 
String[charList.size()]));
-                            break;
-                        case "WCHAR":
-                            List<String> wcharList = 
(plcValueList).stream().map(
-                                    x -> ((PlcWCHAR) 
x).getString()).collect(Collectors.toList());
-                            var = new Variant(wcharList.toArray(new 
String[wcharList.size()]));
-                            break;
-                        case "STRING":
-                            List<String> stringList = 
(plcValueList).stream().map(
-                                    x -> ((PlcSTRING) 
x).getString()).collect(Collectors.toList());
-                            var = new Variant(stringList.toArray(new 
String[stringList.size()]));
-                            break;
-                        case "WSTRING":
-                        case "STRING16":
-                            List<String> wstringList = 
(plcValueList).stream().map(
-                                    x -> (String) ((PlcSTRING) 
x).getString()).collect(Collectors.toList());
-                            var = new Variant(wstringList.toArray(new 
String[wstringList.size()]));
-                            break;
-                        case "DATE_AND_TIME":
-                            List<LocalDateTime> dateTimeList = 
(plcValueList).stream().map(
-                                    x -> ((PlcDATE_AND_TIME) 
x).getDateTime()).collect(Collectors.toList());
-                            var = new Variant(dateTimeList.toArray(new 
LocalDateTime[dateTimeList.size()]));
-                            break;
-                        default:
-                            logger.warn("Unsupported data type : {}, {}", 
plcValueList.get(0).getClass(), dataType);
-                    }
-                } else {
-                    String dataType = uaField.getPlcDataType();                
    
-                    PlcValue plcValue = (PlcValue) 
writeRequest.getPlcValue(fieldName);
-
-                    if (dataType.equals("NULL")) {
-                        if (plcValue.getObject() instanceof Boolean) {
-                            dataType = "BOOL";
-                        } else if (plcValue.getObject() instanceof Byte) {
-                            dataType = "SINT";
-                        } else if (plcValue.getObject() instanceof Short) {
-                            dataType = "INT";
-                        } else if (plcValue.getObject() instanceof Integer) {
-                            dataType = "DINT";
-                        } else if (plcValue.getObject() instanceof Long) {
-                            dataType = "LINT";
-                        } else if (plcValue.getObject() instanceof Float) {
-                            dataType = "REAL";
-                        } else if (plcValue.getObject() instanceof Double) {
-                            dataType = "LREAL";
-                        } else if (plcValue.getObject() instanceof String) {
-                            dataType = "STRING";
-                        }
-                    }
-                    switch (dataType) {
-                        case "BOOL":
-                        case "BIT":
-                            var = new Variant(plcValue.getBoolean());
-                            break;
-                        case "BYTE":
-                        case "BITARR8":
-                            var = new 
Variant(UByte.valueOf(plcValue.getShort()));
-                            break;
-                        case "SINT":
-                        case "INT8":
-                            var = new Variant(plcValue.getByte());
-                            break;
-                        case "USINT":
-                        case "UINT8":
-                        case "BIT8":
-                            var = new 
Variant(UByte.valueOf(plcValue.getShort()));
-                            break;
-                        case "INT":
-                        case "INT16":
-                            var = new Variant(plcValue.getShort());
-                            break;
-                        case "UINT":
-                        case "UINT16":
-                            var = new 
Variant(UShort.valueOf(plcValue.getInteger()));
-                            break;
-                        case "WORD":
-                        case "BITARR16":
-                            var = new 
Variant(UShort.valueOf(plcValue.getInteger()));
-                            break;
-                        case "DINT":
-                        case "INT32":
-                            var = new Variant(plcValue.getInteger());
-                            break;
-                        case "UDINT":
-                        case "UINT32":
-                            var = new 
Variant(UInteger.valueOf(plcValue.getLong()));
-                            break;
-                        case "DWORD":
-                        case "BITARR32":
-                            var = new 
Variant(UInteger.valueOf(plcValue.getLong()));
-                            break;
-                        case "LINT":
-                        case "INT64":
-                            var = new Variant(plcValue.getLong());
-                            break;
-                        case "ULINT":
-                        case "UINT64":
-                            var = new 
Variant(ULong.valueOf(plcValue.getBigInteger()));
-                            break;
-                        case "LWORD":
-                        case "BITARR64":
-                            var = new 
Variant(ULong.valueOf(plcValue.getBigInteger()));
-                            break;
-                        case "REAL":
-                        case "FLOAT":
-                            var = new Variant(plcValue.getFloat());
-                            break;
-                        case "LREAL":
-                        case "DOUBLE":
-                            var = new Variant(plcValue.getDouble());
-                            break;
-                        case "CHAR":
-                            var = new Variant(plcValue.getString());
-                            break;
-                        case "WCHAR":
-                            var = new Variant(plcValue.getString());
-                            break;
-                        case "STRING":
-                            var = new Variant(plcValue.getString());
-                            break;
-                        case "WSTRING":
-                        case "STRING16":
-                            var = new Variant(plcValue.getString());
-                            break;
-                        case "DATE_AND_TIME":
-                            var = new Variant(plcValue.getDateTime());
-                            break;
-                        default:
-                            logger.warn("Unsupported data type : {}, {}", 
plcValue.getClass(), dataType);
-                    }
-                }
-                DataValue value = new DataValue(var, StatusCode.GOOD, null, 
null);
-                ids.add(idNode);
-                names.add(fieldName);
-                values.add(value);
-            }
-            CompletableFuture<List<StatusCode>> opcRequest =
-                client.writeValues(ids, values);
-            List<StatusCode> statusCodes = null;
-            try {
-                statusCodes = opcRequest.get();
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                statusCodes = new LinkedList<>();
-                for (int counter = 0; counter < ids.size(); counter++) {
-                    ((LinkedList<StatusCode>) 
statusCodes).push(StatusCode.BAD);
-                }
-            } catch (ExecutionException e) {
-                statusCodes = new LinkedList<>();
-                for (int counter = 0; counter < ids.size(); counter++) {
-                    ((LinkedList<StatusCode>) 
statusCodes).push(StatusCode.BAD);
-                }
-            }
-
-            for (int counter = 0; counter < names.size(); counter++) {
-                final PlcResponseCode resultCode;
-                if (statusCodes != null && statusCodes.size() > counter) {
-                    Optional<String[]> status = 
StatusCodes.lookup(statusCodes.get(counter).getValue());
-                    if (status.isPresent()) {
-                        if (status.get()[0].equals("Good")) {
-                            resultCode = PlcResponseCode.OK;
-                        } else if (status.get()[0].equals("Uncertain")) {
-                            resultCode = PlcResponseCode.NOT_FOUND;
-                        } else if (status.get()[0].equals("Bad")) {
-                            resultCode = PlcResponseCode.INVALID_DATATYPE;
-                        } else if 
(status.get()[0].equals("Bad_NodeIdUnknown")) {
-                            resultCode = PlcResponseCode.NOT_FOUND;
-                        } else {
-                            resultCode = PlcResponseCode.ACCESS_DENIED;
-                        }
-                    } else {
-                        resultCode = PlcResponseCode.ACCESS_DENIED;
-                    }
-                } else {
-                    resultCode = PlcResponseCode.ACCESS_DENIED;
-                }
-                fieldResponse.put(names.get(counter), resultCode);
-            }
-            PlcWriteResponse response = new 
DefaultPlcWriteResponse(writeRequest, fieldResponse);
-            return response;
-        });
-
-
-        return future;
-    }
-
-
-    private NodeId generateNodeId(OpcuaField uaField) {
-        NodeId idNode = null;
-        switch (uaField.getIdentifierType()) {
-            case STRING_IDENTIFIER:
-                idNode = new NodeId(uaField.getNamespace(), 
uaField.getIdentifier());
-                break;
-            case NUMBER_IDENTIFIER:
-                idNode = new NodeId(uaField.getNamespace(), 
UInteger.valueOf(uaField.getIdentifier()));
-                break;
-            case GUID_IDENTIFIER:
-                idNode = new NodeId(uaField.getNamespace(), 
UUID.fromString(uaField.getIdentifier()));
-                break;
-            case BINARY_IDENTIFIER:
-                idNode = new NodeId(uaField.getNamespace(), new 
ByteString(uaField.getIdentifier().getBytes()));
-                break;
-
-            default:
-                idNode = new NodeId(uaField.getNamespace(), 
uaField.getIdentifier());
-        }
-
-        return idNode;
-    }
-
-    private String getEndpointUrl(InetAddress address, Integer port, String 
params) {
-        return "opc.tcp://" + address.getHostAddress() + ":" + port + "/" + 
params;
-    }
-
-    private Predicate<EndpointDescription> endpointFilter() {
-        return e -> true;
-    }
-
-    private SecurityPolicy getSecurityPolicy() {
-        return SecurityPolicy.None;
-    }
-
-    private IdentityProvider getIdentityProvider() {
-        return new AnonymousProvider();
-    }
-
-    private static String getSubPathOfParams(String params){
-        if(params.contains("=")){
-            if(params.contains("?")){
-                return params.split("\\?")[0];
-            }else{
-                return "";
-            }
-
-        }else {
-            return params;
-        }
-    }
-
-    private static String getOptionString(String params){
-        if(params.contains("=")){
-            if(params.contains("?")){
-                return params.split("\\?")[1];
-            }else{
-                return params;
-            }
-
-        }else {
-            return "";
-        }
-    }
-}
diff --git a/protocols/opcua/pom.xml b/protocols/opcua/pom.xml
index a055cc5..172539a 100644
--- a/protocols/opcua/pom.xml
+++ b/protocols/opcua/pom.xml
@@ -46,10 +46,12 @@
                   <goal>wget</goal>
                 </goals>
                 <configuration>
-                  
<url>https://opcfoundation.org/UA/schemas/1.04/Opc.Ua.Types.bsd</url>
+                  
<url>https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/v1.04/Schema/Opc.Ua.Types.bsd</url>
                   <unpack>false</unpack>
                   
<outputDirectory>${project.build.directory}/downloads</outputDirectory>
                   <outputFileName>Opc.Ua.Types.bsd</outputFileName>
+                  <skipCache>true</skipCache>
+                  <overwrite>true</overwrite>
                 </configuration>
               </execution>
             </executions>
@@ -66,7 +68,7 @@
                 <goal>wget</goal>
               </goals>
               <configuration>
-                
<url>https://opcfoundation.org/UA/schemas/1.04/StatusCode.csv</url>
+                
<url>https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/v1.04/Schema/StatusCode.csv</url>
                 <unpack>false</unpack>
                 
<outputDirectory>${project.build.directory}/downloads</outputDirectory>
                 <outputFileName>StatusCode.csv</outputFileName>
@@ -85,7 +87,7 @@
                   <goal>wget</goal>
                 </goals>
                 <configuration>
-                  
<url>https://opcfoundation.org/UA/schemas/1.04/Opc.Ua.NodeSet2.Services.xml</url>
+                  
<url>https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/v1.04/Schema/Opc.Ua.NodeSet2.Services.xml</url>
                   <unpack>false</unpack>
                   
<outputDirectory>${project.build.directory}/downloads</outputDirectory>
                   <outputFileName>Opc.Ua.NodeSet2.Services.xml</outputFileName>
@@ -104,7 +106,7 @@
                   <goal>wget</goal>
                 </goals>
                 <configuration>
-                  
<url>https://opcfoundation.org/UA/schemas/1.04/Opc.Ua.NodeIds.Services.csv</url>
+                  
<url>https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/v1.04/Schema/Opc.Ua.NodeIds.Services.csv</url>
                   <unpack>false</unpack>
                   
<outputDirectory>${project.build.directory}/downloads</outputDirectory>
                   <outputFileName>Opc.Ua.NodeIds.Services.csv</outputFileName>
diff --git a/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec 
b/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
index fa1e47e..d83dcd6 100644
--- a/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
+++ b/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
@@ -36,10 +36,6 @@
             [simple          int 32             'maxChunkCount']
             [simple          PascalString       'endpoint']
         ]
-        ['HEL','true'     OpcuaHelloResponse
-        ]
-        ['ACK','false'     OpcuaAcknowledgeRequest
-        ]
         ['ACK','true'     OpcuaAcknowledgeResponse
             [simple          string '8'         'chunk']
             [implicit        int 32             'messageSize' 'lengthInBytes']
@@ -49,10 +45,6 @@
             [simple          int 32             'maxMessageSize']
             [simple          int 32             'maxChunkCount']
         ]
-        ['ERR','false'     OpcuaErrorRequest
-        ]
-        ['ERR','true'     OpcuaErrorResponse
-        ]
         ['OPN','false'     OpcuaOpenRequest
             [simple          string '8'         'chunk']
             [implicit        int 32             'messageSize' 'lengthInBytes']
@@ -84,8 +76,6 @@
            [simple          int 32             'requestId']
            [simple          OpcuaMessage       'message']
        ]
-       ['CLO','true'     OpcuaCloseResponse
-       ]
        ['MSG','false'     OpcuaMessageRequest
            [simple          string '8'         'chunk']
            [implicit        int 32             'messageSize' 'lengthInBytes']
diff --git a/protocols/opcua/src/main/xslt/opc-types.xsl 
b/protocols/opcua/src/main/xslt/opc-types.xsl
index 0bd8728..65d491d 100644
--- a/protocols/opcua/src/main/xslt/opc-types.xsl
+++ b/protocols/opcua/src/main/xslt/opc-types.xsl
@@ -217,25 +217,8 @@
     <xsl:apply-templates 
select="/opc:TypeDictionary/opc:EnumeratedType[@Name='NodeIdType']"/>
 ]
 
-[type 'TwoByteNodeId'
-        [simple uint 8 'identifier']
-]
-
-[type 'FourByteNodeId'
-    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='FourByteNodeId']"/>
-]
 
-[type 'NumericNodeId'
-    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='NumericNodeId']"/>
-]
 
-[type 'StringNodeId'
-    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='StringNodeId']"/>
-]
-
-[type 'GuidNodeId'
-    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='GuidNodeId']"/>
-]
 
 [type 'ByteStringNodeId'
     [simple uint 16 'namespaceIndex']
@@ -384,55 +367,59 @@
     [array bit 'arrayDimensions' count 'noOfArrayDimensions == null ? 0 : 
noOfArrayDimensions']
 ]
 
-
-
-[discriminatedType 'NodeId'
-    [reserved int 2 '0x00']
-    [simple NodeIdType 'nodeIdType']
-    [typeSwitch 'nodeIdType'
-        ['NodeIdType.nodeIdTypeTwoByte' NodeIdTwoByte
-            [simple TwoByteNodeId 'id']
+[type 'NodeIdTypeDefinition' [NodeIdType 'nodeType']
+    [implicit nodeIdType 'type' 'nodeType']
+    [typeSwitch 'nodeType'
+        ['nodeIdTypeTwoByte' NodeIdTwoByte
+            [simple uint 8 'namespaceIndex']
+            [simple uint 8 'identifier']
         ]
-        ['NodeIdType.nodeIdTypeFourByte' NodeIdFourByte
+        ['nodeIdTypeFourByte' NodeIdFourByte
+            [simple uint 8 'namespaceIndex']
             [simple FourByteNodeId 'id']
         ]
-        ['NodeIdType.nodeIdTypeNumeric' NodeIdNumeric
+        ['nodeIdTypeNumeric' NodeIdNumeric
+            [simple uint 16 'namespaceIndex']
             [simple NumericNodeId 'id']
         ]
-        ['NodeIdType.nodeIdTypeString' NodeIdString
+        ['nodeIdTypeString' NodeIdString
+            [simple uint 16 'namespaceIndex']
             [simple StringNodeId 'id']
         ]
-        ['NodeIdType.nodeIdTypeGuid' NodeIdGuid
+        ['nodeIdTypeGuid' NodeIdGuid
+            [simple uint 16 'namespaceIndex']
             [simple GuidNodeId 'id']
         ]
-        ['NodeIdType.nodeIdTypeByteString' NodeIdByteString
+        ['nodeIdTypeByteString' NodeIdByteString
+            [simple uint 16 'namespaceIndex']
             [simple ByteStringNodeId 'id']
         ]
     ]
+
+[discriminatedType 'NodeId'
+    [reserved int 2 '0x00']
+    [implicit NodeIdType 'nodeId.nodeType']
+    [simple NodeIdTypeDefinition 'nodeId']
 ]
 
 [type 'ExpandedNodeId'
     [simple bit 'namespaceURISpecified']
     [simple bit 'serverIndexSpecified']
-    [simple NodeIdType 'nodeIdType']
-    [optional TwoByteNodeId 'idTwoByte' 'nodeIdType == 
NodeIdType.nodeIdTypeTwoByte']
-    [optional FourByteNodeId 'idFourByte' 'nodeIdType == 
NodeIdType.nodeIdTypeFourByte']
-    [optional NumericNodeId 'idNumeric' 'nodeIdType == 
NodeIdType.nodeIdTypeNumeric']
-    [optional StringNodeId 'idString' 'nodeIdType == 
NodeIdType.nodeIdTypeString']
-    [optional GuidNodeId 'idGuid' 'nodeIdType == NodeIdType.nodeIdTypeGuid']
-    [optional ByteStringNodeId 'idByteString' 'nodeIdType == 
NodeIdType.nodeIdTypeByteString']
+    [implicit NodeIdType 'nodeId.nodeType']
+    [simple NodeIdTypeDefinition 'nodeId']
     [optional PascalString 'namespaceURI' 'namespaceURISpecified']
     [optional uint 32 'serverIndex' 'serverIndexSpecified']
 ]
 
 [discriminatedType 'ExtensionObject'
     //A serialized object prefixed with its data type identifier.
-    [discriminator ExpandedNodeId 'nodeId']
+    [simple ExpandedNodeId 'nodeId']
+    [virtual string '-1' 'identifier' 'nodeId.id']
     [simple uint 8 'encodingMask']
     [optional int 32 'bodyLength' 'encodingMask > 0']
     [array int 8 'body' count 'bodyLength == null ? 0 : bodyLength']
-    [typeSwitch 'nodeId.nodeIdType','nodeId.idTwoByte.identifier'
-        ['NodeIdType.nodeIdTypeTwoByte','811' DataChangeNotification
+    [typeSwitch 'identifier'
+        ['811' DataChangeNotification
             <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='DataChangeNotification']"/>
         ]
     ]

Reply via email to