You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2018/11/02 16:55:34 UTC

[incubator-plc4x] branch master updated (e39cae0 -> b5453f2)

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

cdutz pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git.


    from e39cae0  Add simple mock driver (#38)
     new a3afd45  renamed AbstractPlcConnection to NettyPlcConnection
     new 89d8199  extracted AbstractPlcConnection class
     new 2bb806d  fixed hello plc4x example
     new b5453f2  - Added more tests for the Plc4XS7Protocol - Fixed a lot of little problems in the Plc4XS7Protocol - Implemented getAllObjects for DefaultPlcReadResponse

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../dummydriver/connection/DummyConnection.java    |   4 +-
 .../plc4x/java/examples/helloplc4x/HelloPlc4x.java | 110 +++++++
 .../org/apache/plc4x/java/mock/MockConnection.java |   4 +-
 .../ads/connection/AdsAbstractPlcConnection.java   |   4 +-
 .../ads/connection/AdsConnectionFactoryTest.java   |   6 +-
 .../ads/connection/AdsSerialPlcConnectionTest.java |   4 +-
 .../base/connection/AbstractPlcConnection.java     | 112 +------
 ...tPlcConnection.java => NettyPlcConnection.java} |  53 +---
 .../java/base/messages/DefaultPlcReadResponse.java |  10 +-
 .../plc4x/java/base/connection/MockConnection.java |   2 +-
 .../connection/BaseEtherNetIpPlcConnection.java    |   4 +-
 .../modbus/connection/BaseModbusPlcConnection.java |   4 +-
 .../connection/ModbusConnectionFactoryTest.java    |   6 +-
 .../connection/ModbusSerialPlcConnectionTest.java  |   4 +-
 plc4j/protocols/s7/pom.xml                         |  12 +
 .../plc4x/java/s7/connection/S7PlcConnection.java  |   4 +-
 .../plc4x/java/s7/netty/Plc4XS7Protocol.java       |  65 ++--
 .../plc4x/java/s7/netty/Plc4XS7ProtocolSpec.groovy | 278 +++++++++++++++++
 .../plc4x/java/s7/netty/Plc4XS7ProtocolTest.java   | 330 +++++++++------------
 ...spockframework.report.IReportCreator.properties |   0
 .../asciidoc/developers/implementing-drivers.adoc  |   2 +-
 .../org/apache/plc4x/java/test/TestConnection.java |  31 +-
 22 files changed, 624 insertions(+), 425 deletions(-)
 create mode 100644 examples/hello-plc4x/src/main/java/org/apache/plc4x/java/examples/helloplc4x/HelloPlc4x.java
 copy plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/{AbstractPlcConnection.java => NettyPlcConnection.java} (71%)
 create mode 100644 plc4j/protocols/s7/src/test/groovy/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolSpec.groovy
 copy plc4j/protocols/{driver-bases/base => s7}/src/test/resources/META-INF/services/com.athaydes.spockframework.report.IReportCreator.properties (100%)


[incubator-plc4x] 01/04: renamed AbstractPlcConnection to NettyPlcConnection

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit a3afd4574e438f0d238963b4950863cd971802bc
Author: Andrey Skorikov <an...@codecentric.de>
AuthorDate: Fri Oct 26 15:16:41 2018 +0200

    renamed AbstractPlcConnection to NettyPlcConnection
---
 .../plc4x/java/examples/dummydriver/connection/DummyConnection.java | 4 ++--
 .../src/test/java/org/apache/plc4x/java/mock/MockConnection.java    | 4 ++--
 .../apache/plc4x/java/ads/connection/AdsAbstractPlcConnection.java  | 4 ++--
 .../apache/plc4x/java/ads/connection/AdsConnectionFactoryTest.java  | 6 +++---
 .../plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java       | 4 ++--
 .../{AbstractPlcConnection.java => NettyPlcConnection.java}         | 6 +++---
 .../java/org/apache/plc4x/java/base/connection/MockConnection.java  | 2 +-
 .../java/ethernetip/connection/BaseEtherNetIpPlcConnection.java     | 4 ++--
 .../plc4x/java/modbus/connection/BaseModbusPlcConnection.java       | 4 ++--
 .../plc4x/java/modbus/connection/ModbusConnectionFactoryTest.java   | 6 +++---
 .../plc4x/java/modbus/connection/ModbusSerialPlcConnectionTest.java | 4 ++--
 .../java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java   | 4 ++--
 .../src/site/asciidoc/developers/implementing-drivers.adoc          | 2 +-
 13 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/connection/DummyConnection.java b/examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/connection/DummyConnection.java
index ed84e90..627ce55 100644
--- a/examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/connection/DummyConnection.java
+++ b/examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/connection/DummyConnection.java
@@ -25,7 +25,7 @@ import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteResponse;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
 import org.slf4j.Logger;
@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
 import java.net.InetAddress;
 import java.util.concurrent.CompletableFuture;
 
-public class DummyConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
+public class DummyConnection extends NettyPlcConnection implements PlcReader, PlcWriter {
 
     @SuppressWarnings("unused")
     private static final Logger logger = LoggerFactory.getLogger(DummyConnection.class);
diff --git a/plc4j/core/src/test/java/org/apache/plc4x/java/mock/MockConnection.java b/plc4j/core/src/test/java/org/apache/plc4x/java/mock/MockConnection.java
index d44fc5d..4662485 100644
--- a/plc4j/core/src/test/java/org/apache/plc4x/java/mock/MockConnection.java
+++ b/plc4j/core/src/test/java/org/apache/plc4x/java/mock/MockConnection.java
@@ -22,12 +22,12 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelInitializer;
 import org.apache.plc4x.java.api.authentication.PlcAuthentication;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.TestChannelFactory;
 
 import java.util.concurrent.CompletableFuture;
 
-public class MockConnection extends AbstractPlcConnection {
+public class MockConnection extends NettyPlcConnection {
 
     private final PlcAuthentication authentication;
 
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsAbstractPlcConnection.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsAbstractPlcConnection.java
index 22023cf..858a18f 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsAbstractPlcConnection.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsAbstractPlcConnection.java
@@ -34,7 +34,7 @@ import org.apache.plc4x.java.ads.model.SymbolicAdsField;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.*;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
 import org.slf4j.Logger;
@@ -42,7 +42,7 @@ import org.slf4j.LoggerFactory;
 
 import java.util.concurrent.*;
 
-public abstract class AdsAbstractPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter, PlcProprietarySender {
+public abstract class AdsAbstractPlcConnection extends NettyPlcConnection implements PlcReader, PlcWriter, PlcProprietarySender {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(AdsAbstractPlcConnection.class);
 
diff --git a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsConnectionFactoryTest.java b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsConnectionFactoryTest.java
index edd3850..82b4d38 100644
--- a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsConnectionFactoryTest.java
+++ b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsConnectionFactoryTest.java
@@ -21,7 +21,7 @@ package org.apache.plc4x.java.ads.connection;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.plc4x.java.ads.api.generic.types.AmsNetId;
 import org.apache.plc4x.java.ads.api.generic.types.AmsPort;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.SerialChannelFactory;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
 import org.junit.Test;
@@ -117,7 +117,7 @@ public class AdsConnectionFactoryTest {
 
     public void assertPort(AdsTcpPlcConnection adsTcpPlcConnection, int port) throws Exception {
         TcpSocketChannelFactory channelFactory = (TcpSocketChannelFactory) FieldUtils
-            .getDeclaredField(AbstractPlcConnection.class, "channelFactory", true)
+            .getDeclaredField(NettyPlcConnection.class, "channelFactory", true)
             .get(adsTcpPlcConnection);
         assertEquals(port, channelFactory.getPort());
     }
@@ -157,7 +157,7 @@ public class AdsConnectionFactoryTest {
 
     public void assertPort(AdsSerialPlcConnection adsSerialPlcConnection, String serialPort) throws Exception {
         SerialChannelFactory channelFactory = (SerialChannelFactory) FieldUtils
-            .getDeclaredField(AbstractPlcConnection.class, "channelFactory", true)
+            .getDeclaredField(NettyPlcConnection.class, "channelFactory", true)
             .get(adsSerialPlcConnection);
         assertEquals(serialPort, channelFactory.getSerialPort());
     }
diff --git a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java
index 9b0a7f4..8a24c99 100644
--- a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java
+++ b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java
@@ -30,7 +30,7 @@ import org.apache.plc4x.java.ads.api.serial.AmsSerialFrame;
 import org.apache.plc4x.java.ads.api.serial.types.*;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.SerialChannelFactory;
 import org.junit.After;
 import org.junit.Before;
@@ -83,7 +83,7 @@ public class AdsSerialPlcConnectionTest {
     }
 
     private void prepareSerialSimulator() throws Exception {
-        Field channelFactoryField = FieldUtils.getField(AbstractPlcConnection.class, "channelFactory", true);
+        Field channelFactoryField = FieldUtils.getField(NettyPlcConnection.class, "channelFactory", true);
         SerialChannelFactory serialChannelFactory = (SerialChannelFactory) channelFactoryField.get(SUT);
         SerialChannelFactory serialChannelFactorySpied = spy(serialChannelFactory);
         EmbeddedChannel embeddedChannel = new EmbeddedChannel(SUT.getChannelHandler(null));
diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/NettyPlcConnection.java
similarity index 95%
rename from plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java
rename to plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/NettyPlcConnection.java
index ea8ddcd..b271fb7 100644
--- a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/NettyPlcConnection.java
@@ -36,7 +36,7 @@ import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
-public abstract class AbstractPlcConnection implements PlcConnection, PlcConnectionMetadata {
+public abstract class NettyPlcConnection implements PlcConnection, PlcConnectionMetadata {
 
     /**
      * a {@link HashedWheelTimer} shall be only instantiated once.
@@ -52,11 +52,11 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect
 
     protected boolean connected;
 
-    protected AbstractPlcConnection(ChannelFactory channelFactory) {
+    protected NettyPlcConnection(ChannelFactory channelFactory) {
         this(channelFactory, false);
     }
 
-    protected AbstractPlcConnection(ChannelFactory channelFactory, boolean awaitSessionSetupComplete) {
+    protected NettyPlcConnection(ChannelFactory channelFactory, boolean awaitSessionSetupComplete) {
         this.channelFactory = channelFactory;
         this.awaitSessionSetupComplete = awaitSessionSetupComplete;
         this.connected = false;
diff --git a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java b/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java
index bbd489f..5d265b8 100644
--- a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java
+++ b/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/connection/MockConnection.java
@@ -22,7 +22,7 @@ import io.netty.channel.ChannelHandler;
 
 import java.util.concurrent.CompletableFuture;
 
-public class MockConnection extends AbstractPlcConnection {
+public class MockConnection extends NettyPlcConnection {
 
     public MockConnection() {
         super(new TestChannelFactory());
diff --git a/plc4j/protocols/ethernetip/src/main/java/org/apache/plc4x/java/ethernetip/connection/BaseEtherNetIpPlcConnection.java b/plc4j/protocols/ethernetip/src/main/java/org/apache/plc4x/java/ethernetip/connection/BaseEtherNetIpPlcConnection.java
index 56a6ddc..8e88331 100644
--- a/plc4j/protocols/ethernetip/src/main/java/org/apache/plc4x/java/ethernetip/connection/BaseEtherNetIpPlcConnection.java
+++ b/plc4j/protocols/ethernetip/src/main/java/org/apache/plc4x/java/ethernetip/connection/BaseEtherNetIpPlcConnection.java
@@ -23,7 +23,7 @@ import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteResponse;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
 import org.apache.plc4x.java.ethernetip.netty.util.EnipPlcFieldHandler;
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
 
 import java.util.concurrent.CompletableFuture;
 
-public abstract class BaseEtherNetIpPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
+public abstract class BaseEtherNetIpPlcConnection extends NettyPlcConnection implements PlcReader, PlcWriter {
 
     private static final Logger logger = LoggerFactory.getLogger(BaseEtherNetIpPlcConnection.class);
 
diff --git a/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/connection/BaseModbusPlcConnection.java b/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/connection/BaseModbusPlcConnection.java
index 3d4ab33..055eb3c 100644
--- a/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/connection/BaseModbusPlcConnection.java
+++ b/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/connection/BaseModbusPlcConnection.java
@@ -23,7 +23,7 @@ import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteResponse;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
 import org.apache.plc4x.java.modbus.util.ModbusPlcFieldHandler;
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
 
 import java.util.concurrent.CompletableFuture;
 
-public abstract class BaseModbusPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
+public abstract class BaseModbusPlcConnection extends NettyPlcConnection implements PlcReader, PlcWriter {
 
     private static final Logger logger = LoggerFactory.getLogger(BaseModbusPlcConnection.class);
 
diff --git a/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/connection/ModbusConnectionFactoryTest.java b/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/connection/ModbusConnectionFactoryTest.java
index c4e3711..e4dbc97 100644
--- a/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/connection/ModbusConnectionFactoryTest.java
+++ b/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/connection/ModbusConnectionFactoryTest.java
@@ -19,7 +19,7 @@
 package org.apache.plc4x.java.modbus.connection;
 
 import org.apache.commons.lang3.reflect.FieldUtils;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.SerialChannelFactory;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
 import org.junit.Test;
@@ -70,7 +70,7 @@ public class ModbusConnectionFactoryTest {
 
     public void assertPort(ModbusTcpPlcConnection modbusTcpPlcConnection, int port) throws Exception {
         TcpSocketChannelFactory channelFactory = (TcpSocketChannelFactory) FieldUtils
-            .getDeclaredField(AbstractPlcConnection.class, "channelFactory", true)
+            .getDeclaredField(NettyPlcConnection.class, "channelFactory", true)
             .get(modbusTcpPlcConnection);
         assertEquals(port, channelFactory.getPort());
     }
@@ -88,7 +88,7 @@ public class ModbusConnectionFactoryTest {
 
     public void assertPort(ModbusSerialPlcConnection modbusSerialPlcConnection, String serialPort) throws Exception {
         SerialChannelFactory channelFactory = (SerialChannelFactory) FieldUtils
-            .getDeclaredField(AbstractPlcConnection.class, "channelFactory", true)
+            .getDeclaredField(NettyPlcConnection.class, "channelFactory", true)
             .get(modbusSerialPlcConnection);
         assertEquals(serialPort, channelFactory.getSerialPort());
     }
diff --git a/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/connection/ModbusSerialPlcConnectionTest.java b/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/connection/ModbusSerialPlcConnectionTest.java
index 519d4b9..57aacf7 100644
--- a/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/connection/ModbusSerialPlcConnectionTest.java
+++ b/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/connection/ModbusSerialPlcConnectionTest.java
@@ -26,7 +26,7 @@ import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.commons.lang3.reflect.MethodUtils;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.SerialChannelFactory;
 import org.junit.After;
 import org.junit.Before;
@@ -73,7 +73,7 @@ public class ModbusSerialPlcConnectionTest {
     }
 
     private void prepareSerialSimulator() throws Exception {
-        Field channelFactoryField = FieldUtils.getField(AbstractPlcConnection.class, "channelFactory", true);
+        Field channelFactoryField = FieldUtils.getField(NettyPlcConnection.class, "channelFactory", true);
         SerialChannelFactory serialChannelFactory = (SerialChannelFactory) channelFactoryField.get(SUT);
         SerialChannelFactory serialChannelFactorySpied = spy(serialChannelFactory);
         EmbeddedChannel embeddedChannel = new EmbeddedChannel(SUT.getChannelHandler(null));
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
index fb8951b..adbe0ff 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
@@ -27,7 +27,7 @@ import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteResponse;
-import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
 import org.apache.plc4x.java.base.events.ConnectEvent;
@@ -73,7 +73,7 @@ import java.util.concurrent.TimeoutException;
  * where the {bit-offset} is optional.
  * All Available Memory Areas for this mode are defined in the {@link MemoryArea} enum.
  */
-public class S7PlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
+public class S7PlcConnection extends NettyPlcConnection implements PlcReader, PlcWriter {
 
     private static final int ISO_ON_TCP_PORT = 102;
 
diff --git a/plc4j/protocols/src/site/asciidoc/developers/implementing-drivers.adoc b/plc4j/protocols/src/site/asciidoc/developers/implementing-drivers.adoc
index 5c62a03..bed4d3c 100644
--- a/plc4j/protocols/src/site/asciidoc/developers/implementing-drivers.adoc
+++ b/plc4j/protocols/src/site/asciidoc/developers/implementing-drivers.adoc
@@ -198,7 +198,7 @@ If no form of `PlcAuthentication` is provided, the normal `connect` method is th
 If however authentication information is provided, the second connect method is used.
 However we still have to find and implement a protocol that actually supports authentication.
 
-The probably simplest way to implement a custom connection is to extend `org.apache.plc4x.java.base.connection.AbstractPlcConnection`.
+The probably simplest way to implement a custom connection is to extend `org.apache.plc4x.java.base.connection.NettyPlcConnection`.
 This allows passing in a `ChannelFactory` instance, which allows overriding the default communication channel used by the driver.
 
 An `AbstractPlcConnection` is required to implement a method called `getChannelHandler`.


[incubator-plc4x] 03/04: fixed hello plc4x example

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 2bb806d6644c65df3c63c2f9e3396094d10b55fd
Author: Andrey Skorikov <an...@codecentric.de>
AuthorDate: Fri Oct 26 16:26:30 2018 +0200

    fixed hello plc4x example
---
 .../plc4x/java/examples/helloplc4x/HelloPlc4x.java | 110 +++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/examples/hello-plc4x/src/main/java/org/apache/plc4x/java/examples/helloplc4x/HelloPlc4x.java b/examples/hello-plc4x/src/main/java/org/apache/plc4x/java/examples/helloplc4x/HelloPlc4x.java
new file mode 100644
index 0000000..1204bd3
--- /dev/null
+++ b/examples/hello-plc4x/src/main/java/org/apache/plc4x/java/examples/helloplc4x/HelloPlc4x.java
@@ -0,0 +1,110 @@
+/*
+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.examples.helloplc4x;
+
+import org.apache.plc4x.java.PlcDriverManager;
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.api.types.PlcResponseCode;
+
+import java.util.concurrent.CompletableFuture;
+
+public class HelloPlc4x {
+
+    /**
+     * Example code do demonstrate using PLC4X.
+     *
+     * @param args ignored.
+     */
+public static void main(String[] args) throws Exception {
+    if (args.length < 2) {
+        System.out.println("Usage: HelloPlc4x {connection-string} {address-string}+");
+        System.out.println("Example: HelloPlc4x s7://10.10.64.20/1/1 %Q0.0:BOOL %Q0:BYTE");
+        return;
+    }
+
+    // Establish a connection to the plc using the url provided as first argument
+    try (PlcConnection plcConnection = new PlcDriverManager().getConnection(args[0])) {
+
+        // Check if this connection support reading of data.
+        if (!plcConnection.getMetadata().canRead()) {
+            System.err.println("This connection doesn't support reading.");
+            return;
+        }
+
+        // Create a new read request:
+        // - Give the single item requested the alias name "value"
+        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
+        for (int i = 1; i < args.length; i++) {
+            builder.addItem("value-" + i, args[i]);
+        }
+
+        //////////////////////////////////////////////////////////
+        // Read synchronously ...
+        // NOTICE: the ".get()" immediately lets this thread pause until
+        // the response is processed and available.
+        System.out.println("Synchronous request ...");
+        PlcReadRequest syncReadRequest = builder.build();
+        PlcReadResponse syncResponse = syncReadRequest.execute().get();
+        // Simply iterating over the field names returned in the response.
+        printResponse(syncResponse);
+
+        //////////////////////////////////////////////////////////
+        // Read asynchronously ...
+        // Register a callback executed as soon as a response arrives.
+        System.out.println("Asynchronous request ...");
+        PlcReadRequest asyncReadRequest = builder.build();
+        CompletableFuture<? extends PlcReadResponse> asyncResponse = asyncReadRequest.execute();
+        asyncResponse.whenComplete((readResponse, throwable) -> {
+            if (readResponse != null) {
+                printResponse(readResponse);
+            } else {
+                System.err.println("An error occurred: " + throwable.getMessage());
+                throwable.printStackTrace();
+            }
+        });
+
+    }
+}
+
+private static void printResponse(PlcReadResponse response) {
+    for (String fieldName : response.getFieldNames()) {
+        if(response.getResponseCode(fieldName) == PlcResponseCode.OK) {
+            int numValues = response.getNumberOfValues(fieldName);
+            // If it's just one element, output just one single line.
+            if(numValues == 1) {
+                System.out.println("Value[" + fieldName + "]: " + response.getObject(fieldName));
+            }
+            // If it's more than one element, output each in a single row.
+            else {
+                System.out.println("Value[" + fieldName + "]:");
+                for(int i = 0; i < numValues; i++) {
+                    System.out.println(" - " + response.getObject(fieldName, i));
+                }
+            }
+        }
+        // Something went wrong, to output an error message instead.
+        else {
+            System.out.println("Error[" + fieldName + "]: " + response.getResponseCode(fieldName).name());
+        }
+    }
+}
+
+}


[incubator-plc4x] 04/04: - Added more tests for the Plc4XS7Protocol - Fixed a lot of little problems in the Plc4XS7Protocol - Implemented getAllObjects for DefaultPlcReadResponse

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit b5453f20bbf79a9fd1cfb421402b80ac6f22f50a
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Fri Nov 2 17:55:27 2018 +0100

    - Added more tests for the Plc4XS7Protocol
    - Fixed a lot of little problems in the Plc4XS7Protocol
    - Implemented getAllObjects for DefaultPlcReadResponse
---
 .../java/base/messages/DefaultPlcReadResponse.java |  10 +-
 plc4j/protocols/s7/pom.xml                         |  12 +
 .../plc4x/java/s7/netty/Plc4XS7Protocol.java       |  65 ++--
 .../plc4x/java/s7/netty/Plc4XS7ProtocolSpec.groovy | 278 +++++++++++++++++
 .../plc4x/java/s7/netty/Plc4XS7ProtocolTest.java   | 330 +++++++++------------
 ...spockframework.report.IReportCreator.properties |  66 +++++
 6 files changed, 541 insertions(+), 220 deletions(-)

diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadResponse.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadResponse.java
index 65c51ca..b51bfe1 100644
--- a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadResponse.java
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcReadResponse.java
@@ -97,7 +97,15 @@ public class DefaultPlcReadResponse implements InternalPlcReadResponse {
 
     @Override
     public Collection<Object> getAllObjects(String name) {
-        // TODO: Implement this ...
+        BaseDefaultFieldItem fieldInternal = getFieldInternal(name);
+        if (fieldInternal != null) {
+            int num = fieldInternal.getNumberOfValues();
+            List<Object> values = new ArrayList<>(num);
+            for (int i = 0; i < num; i++) {
+                values.add(fieldInternal.getObject(i));
+            }
+            return values;
+        }
         return null;
     }
 
diff --git a/plc4j/protocols/s7/pom.xml b/plc4j/protocols/s7/pom.xml
index af9ac3f..b684793 100644
--- a/plc4j/protocols/s7/pom.xml
+++ b/plc4j/protocols/s7/pom.xml
@@ -108,6 +108,18 @@
     </dependency>
 
     <dependency>
+      <groupId>org.spockframework</groupId>
+      <artifactId>spock-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.athaydes</groupId>
+      <artifactId>spock-reports</artifactId>
+      <version>1.6.1</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
       <groupId>org.apache.plc4x</groupId>
       <artifactId>plc4j-utils-test-utils</artifactId>
       <version>0.2.0-SNAPSHOT</version>
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
index 07f62b5..f4a40bf 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
@@ -21,7 +21,6 @@ package org.apache.plc4x.java.s7.netty;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
-import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.plc4x.java.api.exceptions.*;
@@ -156,7 +155,7 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
         for (String fieldName : readRequest.getFieldNames()) {
             PlcField field = readRequest.getField(fieldName);
             if (!(field instanceof S7Field)) {
-                throw new PlcException("The field should have been of type S7Field");
+                throw new PlcProtocolException("The field should have been of type S7Field");
             }
             S7Field s7Field = (S7Field) field;
 
@@ -459,13 +458,13 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
                         fieldItem = decodeReadResponseByteBitStringField(field, data);
                         break;
                     case WORD:  // 2 byte (16 bit)
-                        fieldItem = decodeReadResponseShortBitStringField(data);
+                        fieldItem = decodeReadResponseShortBitStringField(field, data);
                         break;
                     case DWORD:  // 4 byte (32 bit)
-                        fieldItem = decodeReadResponseIntegerBitStringField(data);
+                        fieldItem = decodeReadResponseIntegerBitStringField(field, data);
                         break;
                     case LWORD:  // 8 byte (64 bit)
-                        fieldItem = decodeReadResponseLongBitStringField(data);
+                        fieldItem = decodeReadResponseLongBitStringField(field, data);
                         break;
                     // -----------------------------------------
                     // Integers
@@ -540,39 +539,37 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
     }
 
     BaseDefaultFieldItem decodeReadResponseByteBitStringField(S7Field field, ByteBuf data) {
-        byte[] bytes = ArrayUtils.toPrimitive(readAllValues(Byte.class, field, i -> data.readByte()));
-        BitSet bitSet = BitSet.valueOf(bytes);
-        Boolean[] booleanValues = new Boolean[8 * bytes.length];
-        for(int i = 0; i < 8 * bytes.length; i++) {
-            booleanValues[i] = bitSet.get(i);
-        }
-        return new DefaultBooleanFieldItem(booleanValues);
+        byte[] bytes = new byte[field.getNumElements()];
+        data.readBytes(bytes);
+        return decodeBitStringField(bytes);
     }
 
-    BaseDefaultFieldItem decodeReadResponseShortBitStringField(ByteBuf data) {
-        BitSet bitSet = BitSet.valueOf(new byte[]{data.readByte(), data.readByte()});
-        Boolean[] booleanValues = new Boolean[8];
-        for(int i = 0; i < 16; i++) {
-            booleanValues[i] = bitSet.get(i);
-        }
-        return new DefaultBooleanFieldItem(booleanValues);
+    BaseDefaultFieldItem decodeReadResponseShortBitStringField(S7Field field, ByteBuf data) {
+        byte[] bytes = new byte[field.getNumElements() * 2];
+        data.readBytes(bytes);
+        return decodeBitStringField(bytes);
     }
 
-    BaseDefaultFieldItem decodeReadResponseIntegerBitStringField(ByteBuf data) {
-        BitSet bitSet = BitSet.valueOf(new byte[]{
-            data.readByte(), data.readByte(), data.readByte(), data.readByte()});
-        Boolean[] booleanValues = new Boolean[8];
-        for(int i = 0; i < 32; i++) {
-            booleanValues[i] = bitSet.get(i);
-        }
-        return new DefaultBooleanFieldItem(booleanValues);
+    BaseDefaultFieldItem decodeReadResponseIntegerBitStringField(S7Field field, ByteBuf data) {
+        byte[] bytes = new byte[field.getNumElements() * 4];
+        data.readBytes(bytes);
+        return decodeBitStringField(bytes);
+    }
+
+    BaseDefaultFieldItem decodeReadResponseLongBitStringField(S7Field field, ByteBuf data) {
+        byte[] bytes = new byte[field.getNumElements() * 8];
+        data.readBytes(bytes);
+        return decodeBitStringField(bytes);
     }
 
-    BaseDefaultFieldItem decodeReadResponseLongBitStringField(ByteBuf data) {
-        BitSet bitSet = BitSet.valueOf(new long[]{data.readLong()});
-        Boolean[] booleanValues = new Boolean[8];
-        for(int i = 0; i < 64; i++) {
-            booleanValues[i] = bitSet.get(i);
+    BaseDefaultFieldItem decodeBitStringField(byte[] bytes) {
+        BitSet bitSet = BitSet.valueOf(bytes);
+        Boolean[] booleanValues = new Boolean[8 * bytes.length];
+        int k = 0;
+        for(int i = bytes.length - 1; i >= 0; i--) {
+            for(int j = 0; j < 8; j++) {
+                booleanValues[k++] = bitSet.get(8 * i + j);
+            }
         }
         return new DefaultBooleanFieldItem(booleanValues);
     }
@@ -608,8 +605,8 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
     }
 
     BaseDefaultFieldItem decodeReadResponseSignedLongField(S7Field field, ByteBuf data) {
-        BigInteger[] bigIntegers = readAllValues(BigInteger.class, field, i -> readSigned64BitInteger(data));
-        return new DefaultBigIntegerFieldItem(bigIntegers);
+        Long[] longs = readAllValues(Long.class, field, i -> data.readLong());
+        return new DefaultLongFieldItem(longs);
     }
 
     BaseDefaultFieldItem decodeReadResponseUnsignedLongField(S7Field field, ByteBuf data) {
diff --git a/plc4j/protocols/s7/src/test/groovy/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolSpec.groovy b/plc4j/protocols/s7/src/test/groovy/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolSpec.groovy
new file mode 100644
index 0000000..75f7835
--- /dev/null
+++ b/plc4j/protocols/s7/src/test/groovy/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolSpec.groovy
@@ -0,0 +1,278 @@
+/*
+ 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.s7.netty
+
+import io.netty.channel.ChannelFuture
+import io.netty.channel.ChannelHandlerContext
+import io.netty.channel.ChannelOutboundHandlerAdapter
+import io.netty.channel.ChannelPromise
+import io.netty.channel.embedded.EmbeddedChannel
+import org.apache.plc4x.java.api.exceptions.PlcProtocolException
+import org.apache.plc4x.java.api.messages.PlcReadRequest
+import org.apache.plc4x.java.api.messages.PlcReadResponse
+import org.apache.plc4x.java.api.messages.PlcResponse
+import org.apache.plc4x.java.api.messages.PlcWriteRequest
+import org.apache.plc4x.java.api.types.PlcResponseCode
+import org.apache.plc4x.java.base.messages.*
+import org.apache.plc4x.java.s7.netty.model.messages.S7Message
+import org.apache.plc4x.java.s7.netty.model.messages.S7RequestMessage
+import org.apache.plc4x.java.s7.netty.model.messages.S7ResponseMessage
+import org.apache.plc4x.java.s7.netty.model.params.S7Parameter
+import org.apache.plc4x.java.s7.netty.model.params.VarParameter
+import org.apache.plc4x.java.s7.netty.model.params.items.S7AnyVarParameterItem
+import org.apache.plc4x.java.s7.netty.model.payloads.S7Payload
+import org.apache.plc4x.java.s7.netty.model.payloads.VarPayload
+import org.apache.plc4x.java.s7.netty.model.payloads.items.VarPayloadItem
+import org.apache.plc4x.java.s7.netty.model.types.*
+import org.apache.plc4x.java.s7.netty.util.S7PlcFieldHandler
+import spock.lang.Specification
+import spock.lang.Unroll
+
+import java.lang.reflect.Field
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.TimeUnit
+
+import static org.mockito.Mockito.mock
+
+class Plc4XS7ProtocolSpec extends Specification {
+
+    private EmbeddedChannel SUT
+    private PlcReadRequest.Builder readRequestBuilder
+    private PlcWriteRequest.Builder writeRequestBuilder
+    private CompletableFuture<S7Message> writeFuture
+    private CompletableFuture<PlcResponse> readFuture
+
+    @Unroll
+    def "Test encoding the different PLC read requests: '#address'"(String address, boolean expectedSuccess, MemoryArea expectedMemoryArea, int dataBlockNumber, int byteOffset, int bitOffset, int numItems, TransportSize datatype) {
+        setup:
+        initTest(null)
+        CompletableFuture<InternalPlcReadRequest> future = new CompletableFuture<>()
+        PlcRequestContainer container = new PlcRequestContainer(
+            (DefaultPlcReadRequest) readRequestBuilder.addItem("foo", address).build(), future)
+        ChannelFuture channelFuture = SUT.writeOneOutbound(container)
+        S7Message writtenMessage = writeFuture.get(100, TimeUnit.MILLISECONDS)
+        Throwable exception = channelFuture.cause()
+
+        expect:
+        assert channelFuture.isSuccess() == expectedSuccess
+        assert expectedSuccess ? exception == null : exception != null
+        assert expectedSuccess ? writtenMessage != null : writtenMessage == null
+        if(expectedSuccess)
+            assertReadRequestSuccess(writtenMessage, expectedMemoryArea, dataBlockNumber, byteOffset, bitOffset, numItems, datatype)
+        else
+            assertFailure(exception)
+
+        where:
+        address    | expectedSuccess | expectedMemoryArea | dataBlockNumber | byteOffset | bitOffset | numItems | datatype
+        "%Q0:BYTE" | true            | MemoryArea.OUTPUTS | 0               | 0          | 0         | 1        | TransportSize.BYTE
+    }
+
+    void assertReadRequestSuccess(S7Message writtenMessage, MemoryArea memoryArea, int dataBlockNumber, int byteOffset, int bitOffset, int numItems, TransportSize datatype) {
+        assert writtenMessage instanceof S7RequestMessage
+        assert writtenMessage.getParameters().size() == 1
+        assert writtenMessage.getPayloads().isEmpty()
+        assert writtenMessage.getParent() != null
+
+        assert writtenMessage.getParameters().get(0) instanceof VarParameter
+        VarParameter varParameter = (VarParameter) writtenMessage.getParameters().get(0)
+        assert varParameter.getItems().size() == 1
+
+        assert varParameter.getItems().get(0) instanceof S7AnyVarParameterItem
+        S7AnyVarParameterItem s7AnyVarParameterItem = (S7AnyVarParameterItem) varParameter.getItems().get(0)
+        assert s7AnyVarParameterItem.getSpecificationType() == SpecificationType.VARIABLE_SPECIFICATION
+        assert s7AnyVarParameterItem.getMemoryArea() == memoryArea
+        assert s7AnyVarParameterItem.getDataBlockNumber() == (short) dataBlockNumber
+        assert s7AnyVarParameterItem.getByteOffset() == (short) byteOffset
+        assert s7AnyVarParameterItem.getBitOffset() == (byte) bitOffset
+        assert s7AnyVarParameterItem.getNumElements() == numItems
+        assert s7AnyVarParameterItem.getDataType() == datatype
+    }
+
+    @Unroll
+    def "Test encoding the different PLC write requests: '#address'"(String address, Object value, boolean expectedSuccess, MemoryArea expectedMemoryArea, int dataBlockNumber, int byteOffset, int bitOffset, int numItems, TransportSize datatype) {
+        setup:
+        initTest(null)
+        CompletableFuture<InternalPlcWriteRequest> future = new CompletableFuture<>()
+        PlcRequestContainer container = new PlcRequestContainer(
+            (DefaultPlcWriteRequest) writeRequestBuilder.addItem("foo", address, value).build(), future)
+        ChannelFuture channelFuture = SUT.writeOneOutbound(container)
+        S7Message writtenMessage = writeFuture.get(100, TimeUnit.MILLISECONDS)
+        Throwable exception = channelFuture.cause()
+
+        expect:
+        assert channelFuture.isSuccess() == expectedSuccess
+        assert expectedSuccess ? exception == null : exception != null
+        assert expectedSuccess ? writtenMessage != null : writtenMessage == null
+        if(expectedSuccess)
+            assertWriteRequestSuccess(writtenMessage, expectedMemoryArea, dataBlockNumber, byteOffset, bitOffset, numItems, datatype)
+        else
+            assertFailure(exception)
+
+        where:
+        address             | value               || expectedSuccess | expectedMemoryArea | dataBlockNumber | byteOffset | bitOffset | numItems | datatype
+        "%Q3.4:BOOL"        | true                || true            | MemoryArea.OUTPUTS | 0               | 3          | 4         | 1        | TransportSize.BOOL
+        "%Q3:SINT"          | (byte) 0x42         || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.SINT
+        "%Q3:INT"           | (short) 0x4223      || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.INT
+        "%Q3:DINT"          | (int) 4223          || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.DINT
+        "%Q3:LINT"          | (long) 4223123      || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.LINT
+        "%Q3:USINT"         | (byte) 0x42         || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.USINT
+        "%Q3:UINT"          | (short) 0x4223      || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.UINT
+        "%Q3:UDINT"         | (int) 4223          || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.UDINT
+        "%Q3:ULINT"         | (long) 4223123      || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.ULINT
+        "%Q3:REAL"          | (float) 42.312      || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.REAL
+        "%Q3:LREAL"         | (double) 42.32      || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.LREAL
+        "%Q3:STRING"        | "foo"               || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.STRING
+        "%Q3:WSTRING"       | "bar"               || true            | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.WSTRING
+        //"%Q3:DATE_AND_TIME" | LocalDateTime.now() || false           | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.DATE_AND_TIME
+    }
+
+    void assertWriteRequestSuccess(S7Message writtenMessage, MemoryArea memoryArea, int dataBlockNumber, int byteOffset, int bitOffset, int numItems, TransportSize datatype) {
+        assert writtenMessage instanceof S7RequestMessage
+        assert writtenMessage.getParameters().size() == 1
+        assert writtenMessage.getPayloads().size() == 1
+        assert writtenMessage.getParent() != null
+
+        assert writtenMessage.getParameters().get(0) instanceof VarParameter
+        VarParameter varParameter = (VarParameter) writtenMessage.getParameters().get(0)
+        assert varParameter.getItems().size() == 1
+
+        assert varParameter.getItems().get(0) instanceof S7AnyVarParameterItem
+        S7AnyVarParameterItem s7AnyVarParameterItem = (S7AnyVarParameterItem) varParameter.getItems().get(0)
+        assert s7AnyVarParameterItem.getSpecificationType() == SpecificationType.VARIABLE_SPECIFICATION
+        assert s7AnyVarParameterItem.getMemoryArea() == memoryArea
+        assert s7AnyVarParameterItem.getDataBlockNumber() == (short) dataBlockNumber
+        assert s7AnyVarParameterItem.getByteOffset() == (short) byteOffset
+        assert s7AnyVarParameterItem.getBitOffset() == (byte) bitOffset
+        assert s7AnyVarParameterItem.getNumElements() == numItems
+        assert s7AnyVarParameterItem.getDataType() == datatype
+
+        assert writtenMessage.getPayloads().get(0) instanceof VarPayload
+        VarPayload varPayload = (VarPayload) writtenMessage.getPayloads().get(0)
+        assert varPayload.getItems().size() == 1
+    }
+
+
+
+    @Unroll
+    def "Test decoding the different PLC read responses: '#address'"(String address, MemoryArea memoryArea,
+                  int dataBlockNumber, int byteOffset, int bitOffset, int numItems, TransportSize datatype,
+                  DataTransportSize dataTransportSize, byte[] data, boolean expectedSuccess,
+                  PlcResponseCode expectedResponseCode, int expectedNumItems, Object[] expectedValues) {
+        setup:
+        initTest(address)
+        S7Parameter parameter = new VarParameter(ParameterType.READ_VAR, Collections.singletonList(
+            new S7AnyVarParameterItem(SpecificationType.VARIABLE_SPECIFICATION, memoryArea, datatype, numItems,
+                (short) dataBlockNumber, (short) byteOffset, (byte) bitOffset)))
+        S7Payload payload = new VarPayload(ParameterType.READ_VAR, Collections.singletonList(
+            new VarPayloadItem(DataTransportErrorCode.OK, dataTransportSize, data)))
+        // The tpdu has to match the id manually injected in the setup method.
+        S7Message response = new S7ResponseMessage(MessageType.JOB, (short) 1,
+            Collections.singletonList(parameter), Collections.singletonList(payload), (byte) 0, (byte) 0)
+        SUT.writeInbound(response)
+        PlcResponse receivedMessage = readFuture.get(100, TimeUnit.MILLISECONDS)
+
+        expect:
+        //assert expectedSuccess ? exception == null : exception != null
+        assert expectedSuccess ? receivedMessage != null : receivedMessage == null
+        if(expectedSuccess)
+            assertReadResponseSuccess(receivedMessage, expectedResponseCode, expectedNumItems, expectedValues)
+        else
+            assertFailure(exception)
+
+        where:
+
+        // Bit-String values
+        address      | memoryArea         | dataBlockNumber | byteOffset | bitOffset | numItems | datatype            | dataTransportSize                 | data                                             || expectedSuccess | expectedResponseCode | expectedNumItems | expectedValues
+        "%Q3.4:BOOL" | MemoryArea.OUTPUTS | 0               | 3          | 4         | 1        | TransportSize.BOOL  | DataTransportSize.BIT             | [0x01]                                           || true            | PlcResponseCode.OK   | 1                | [true]
+        "%Q3:BYTE"   | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.BYTE  | DataTransportSize.BYTE_WORD_DWORD | [0x23]                                           || true            | PlcResponseCode.OK   | 8                | [true, true, false, false, false, true, false, false]
+        "%Q3:WORD"   | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.WORD  | DataTransportSize.BYTE_WORD_DWORD | [0x43, 0xA1]                                     || true            | PlcResponseCode.OK   | 16               | [true, false, false, false, false, true, false, true, true, true, false, false, false, false, true, false]
+        "%Q3:DWORD"  | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.DWORD | DataTransportSize.BYTE_WORD_DWORD | [0x43, 0xA1, 0x11, 0xFA]                         || true            | PlcResponseCode.OK   | 32               | [false, true, false, true, true, true, true, true, true, false, false, false, true, false, false, false, true, false, false, false, false, true, false, true, true, true, false, false, false, false, true, false]
+        "%Q3:LWORD"  | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.LWORD | DataTransportSize.BYTE_WORD_DWORD | [0x43, 0xA1, 0x11, 0xFA, 0x53, 0x82, 0x13, 0x85] || true            | PlcResponseCode.OK   | 64               | [true, false, true, false, false, false, false, true, true, true, false, false, true, false, false, false, false, true, false, false, false, false, false, true, true, true, false, false, true, false, true, false, false, true [...]
+        // Integer values
+        //address    | memoryArea         | dataBlockNumber | byteOffset | bitOffset | numItems | datatype            | dataTransportSize                 | data                                             || expectedSuccess | expectedResponseCode | expectedNumItems | expectedValues
+        "%Q3:SINT"   | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.SINT  | DataTransportSize.INTEGER         | [0x43]                                           || true            | PlcResponseCode.OK   | 1                | [(byte) 0x43]
+        "%Q3:USINT"  | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.USINT | DataTransportSize.INTEGER         | [0xFF]                                           || true            | PlcResponseCode.OK   | 1                | [(short) 255]
+        "%Q3:INT"    | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.INT   | DataTransportSize.INTEGER         | [0x42, 0x23]                                     || true            | PlcResponseCode.OK   | 1                | [(short) 16931]
+        "%Q3:UINT"   | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.UINT  | DataTransportSize.INTEGER         | [0xFF, 0xFF]                                     || true            | PlcResponseCode.OK   | 1                | [(int) 65535]
+        "%Q3:DINT"   | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.DINT  | DataTransportSize.INTEGER         | [0x42, 0x23, 0x12, 0x74]                         || true            | PlcResponseCode.OK   | 1                | [(int) 1109594740]
+        "%Q3:UDINT"  | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.UDINT | DataTransportSize.INTEGER         | [0xFF, 0xFF, 0xFF, 0xFF]                         || true            | PlcResponseCode.OK   | 1                | [(long) 4294967295]
+        "%Q3:LINT"   | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.LINT  | DataTransportSize.INTEGER         | [0x43, 0xA1, 0x11, 0xFA, 0x53, 0x82, 0x13, 0x85] || true            | PlcResponseCode.OK   | 1                | [(long) 4873196038632117125]
+        //ULINT
+        // Floating point values
+        "%Q3:REAL"   | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.REAL  | DataTransportSize.REAL            | [0x42, 0x23, 0x12, 0x74]                         || true            | PlcResponseCode.OK   | 1                | [40.76802F]
+        "%Q3:LREAL"  | MemoryArea.OUTPUTS | 0               | 3          | 0         | 1        | TransportSize.LREAL | DataTransportSize.REAL            | [0x43, 0xA1, 0x11, 0xFA, 0x53, 0x82, 0x13, 0x85] || true            | PlcResponseCode.OK   | 1                | [6.150197049102015e+17D]
+    }
+
+    void assertReadResponseSuccess(PlcResponse receivedMessage, PlcResponseCode expectedResponseCode, int expectedNumItems, Object[] expectedValues) {
+        assert receivedMessage instanceof PlcReadResponse
+        PlcReadResponse readResponse = (PlcReadResponse) receivedMessage
+
+        assert readResponse.getNumberOfValues("bar") == expectedNumItems
+        assert readResponse.getResponseCode("bar") == expectedResponseCode
+        Object[] actualValues = readResponse.getAllObjects("bar")
+        if(expectedValues == null) {
+            assert actualValues == null
+        } else {
+            assert actualValues.length == expectedValues.length
+            for (int i = 0; i < actualValues.length; i++) {
+                assert actualValues[i].class == expectedValues[i].class
+                assert actualValues[i] == expectedValues[i]
+            }
+        }
+    }
+
+    void assertFailure(Throwable exception) {
+        assert exception != null
+        assert exception instanceof PlcProtocolException
+    }
+
+    void initTest(String address) {
+        writeFuture = new CompletableFuture<>()
+        readRequestBuilder = new DefaultPlcReadRequest.Builder(mock(PlcReader.class), new S7PlcFieldHandler())
+        writeRequestBuilder = new DefaultPlcWriteRequest.Builder(mock(PlcWriter.class), new S7PlcFieldHandler())
+
+        Plc4XS7Protocol protocol = new Plc4XS7Protocol()
+
+        if(address) {
+            readFuture = new CompletableFuture<>()
+            // Populate the 'requests' field with some manually crafted requests.
+            Field requestsFiled = Plc4XS7Protocol.class.getDeclaredField("requests")
+            requestsFiled.setAccessible(true)
+            Map<Short, PlcRequestContainer> requestMap = (Map<Short, PlcRequestContainer>) requestsFiled.get(protocol)
+            requestMap.put((short) 1, new PlcRequestContainer<>(readRequestBuilder.addItem("bar", address).build(), readFuture))
+            //requestMap.put((short) 2, new PlcRequestContainer<>(writeRequestBuilder.addItem("bar", address, 42).build(), readFuture))
+        }
+
+        SUT = new EmbeddedChannel(new ChannelOutboundHandlerAdapter() {
+            @Override
+            void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
+                if(msg instanceof S7Message) {
+                    writeFuture.complete((S7Message) msg)
+                    promise.setSuccess()
+                } else {
+                    promise.setFailure(new PlcProtocolException(
+                        "Got message of type " + msg.getClass().getSimpleName()))
+                }
+            }
+        }, protocol)
+    }
+
+
+}
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java
index 4d85bf4..152fb0f 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java
@@ -18,208 +18,168 @@ under the License.
 */
 package org.apache.plc4x.java.s7.netty;
 
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.embedded.EmbeddedChannel;
+import io.netty.handler.codec.EncoderException;
+import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
-import org.apache.plc4x.java.base.messages.InternalPlcRequest;
-import org.apache.plc4x.java.base.messages.PlcRequestContainer;
+import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.base.messages.*;
 import org.apache.plc4x.java.netty.NettyTestBase;
+import org.apache.plc4x.java.s7.netty.model.messages.S7Message;
+import org.apache.plc4x.java.s7.netty.model.messages.S7RequestMessage;
+import org.apache.plc4x.java.s7.netty.model.params.VarParameter;
+import org.apache.plc4x.java.s7.netty.model.params.items.S7AnyVarParameterItem;
+import org.apache.plc4x.java.s7.netty.model.payloads.VarPayload;
 import org.apache.plc4x.java.s7.netty.model.payloads.items.VarPayloadItem;
-import org.apache.plc4x.java.s7.netty.model.types.DataTransportErrorCode;
-import org.apache.plc4x.java.s7.netty.model.types.DataTransportSize;
+import org.apache.plc4x.java.s7.netty.model.types.*;
+import org.apache.plc4x.java.s7.netty.util.S7PlcFieldHandler;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import static org.hamcrest.Matchers.*;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
-import java.util.Calendar;
-import java.util.Objects;
-import java.util.function.Consumer;
-
-import static org.mockito.Mockito.*;
-
-@SuppressWarnings("unchecked")
-//@RunWith(Parameterized.class)
 public class Plc4XS7ProtocolTest extends NettyTestBase {
 
-/*    private Plc4XS7Protocol SUT;
-
-    @Rule
-    public ExpectedException expectedException = ExpectedException.none();
-    // TODO: implement these types
-    private List<String> notYetSupportedDataType = Stream.of(
-        Calendar.class,
-        GregorianCalendar.class,
-        BigInteger.class,
-        byte[].class,
-        Byte[].class
-    ).map(Class::getSimpleName).collect(Collectors.toList());
-
-    @Parameterized.Parameter
-    public Class<?> type;
-
-    @Parameterized.Parameter(1)
-    public S7Field field;
-
-    @Parameterized.Parameters(name = "{index} Type:{0} {1}")
-    public static Collection<Object[]> data() {
-        List<Object[]> arguments = new LinkedList<>();
-        // Build the cross product of all variables and field types.
-        streamOfPlc4XSupportedDataTypes()
-            .forEach(
-                aClass -> Arrays.asList(
-                    mock(S7Field.class))
-                    .forEach(field -> arguments.add(new Object[]{aClass, field}))
-            );
-        return arguments;
-    }
+    private EmbeddedChannel SUT;
+    private PlcReadRequest.Builder readRequestBuilder =
+        new DefaultPlcReadRequest.Builder(mock(PlcReader.class), new S7PlcFieldHandler());
+    private PlcWriteRequest.Builder writeRequestBuilder =
+        new DefaultPlcWriteRequest.Builder(mock(PlcWriter.class), new S7PlcFieldHandler());
+    private CompletableFuture<S7Message> writeFuture;
 
     @Before
     public void setUp() {
-        SUT = new Plc4XS7Protocol();
-    }
-
-    @Test
-    @Category(FastTests.class)
-    public void encode() throws Exception {
-        assumeThat(type + " not yet implemented", notYetSupportedDataType, not(hasItem(type.getSimpleName())));
-        // TODO: finish me
-        // Read Request Tests
-        {
-            LinkedList<Object> out = new LinkedList<>();
-            SUT.encode(null, createMockedContainer(new TypeSafePlcReadRequest(type, field)), out);
-            // TODO: finish the asserts
-            assertThat(out, hasSize(1));
-        }
-        // Write Request Tests
-        {
-            LinkedList<Object> out = new LinkedList<>();
-            SUT.encode(null, createMockedContainer(new TypeSafePlcWriteRequest(type, field, fakeValueFor(type))), out);
-            // TODO: finish the asserts
-            assertThat(out, hasSize(1));
-        }
-    }*/
-
-/*    @Test
-    @Category(FastTests.class)
-    public void decode() throws Exception {
-        assumeThat(type + " not yet implemented", notYetSupportedDataType, not(hasItem(type.getSimpleName())));
-        // Read Test
-        {
-            short fakeTpduReference = (short) 1;
-            {
-                // We need to put in a fake tpdu reference
-                Field requests = Plc4XS7Protocol.class.getDeclaredField("requests");
-                requests.setAccessible(true);
-                Map<Short, PlcRequestContainer> requestContainerMap = (Map<Short, PlcRequestContainer>) requests.get(SUT);
-                requestContainerMap.put(fakeTpduReference, createMockedContainer(new TypeSafePlcReadRequest(type, field)));
-            }
-            S7ResponseMessage msg = new S7ResponseMessage(
-                MessageType.ACK,
-                fakeTpduReference,
-                singletonList(mock(VarParameter.class)),
-                singletonList(new VarPayload(ParameterType.READ_VAR, singletonList(varPayloadItemFor(type)))),
-                (byte) 0x00,
-                (byte) 0x00);
-            LinkedList<Object> out = new LinkedList<>();
-            SUT.decode(null, msg, out);
-            // TODO: finish the asserts
-            assertThat(out, hasSize(0));
-        }
-        // Write Test
-        {
-            short fakeTpduReference = (short) 2;
-            {
-                // We need to put in a fake tpdu reference
-                Field requests = Plc4XS7Protocol.class.getDeclaredField("requests");
-                requests.setAccessible(true);
-                Map<Short, PlcRequestContainer> requestContainerMap = (Map<Short, PlcRequestContainer>) requests.get(SUT);
-                requestContainerMap.put(fakeTpduReference, createMockedContainer(new TypeSafePlcWriteRequest(type, field, fakeValueFor(type))));
+        writeFuture = new CompletableFuture<>();
+        SUT = new EmbeddedChannel(new ChannelOutboundHandlerAdapter() {
+            @Override
+            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
+                if(msg instanceof S7Message) {
+                    writeFuture.complete((S7Message) msg);
+                    promise.setSuccess();
+                } else {
+                    promise.setFailure(new PlcProtocolException(
+                        "Got message of type " + msg.getClass().getSimpleName()));
+                }
             }
-            S7ResponseMessage msg = new S7ResponseMessage(
-                MessageType.ACK,
-                fakeTpduReference,
-                singletonList(mock(VarParameter.class)),
-                singletonList(new VarPayload(ParameterType.WRITE_VAR, singletonList(varPayloadItemFor(type)))),
-                (byte) 0x00,
-                (byte) 0x00);
-            LinkedList<Object> out = new LinkedList<>();
-            SUT.decode(null, msg, out);
-            // TODO: finish the asserts
-            assertThat(out, hasSize(0));
-        }
-    }*/
-
-    private <T> T fakeValueFor(Class<T> type) {
-        if (type == Boolean.class) {
-            return (T) Boolean.TRUE;
-        } else if (type == Byte.class) {
-            return (T) Byte.valueOf((byte) 0x0000_0000);
-        } else if (type == Short.class) {
-            return (T) Short.valueOf((short) 123);
-        } else if (type == Calendar.class) {
-            return (T) Calendar.getInstance();
-        } else if (type == Float.class) {
-            return (T) Float.valueOf(123f);
-        } else if (type == Double.class) {
-            return (T) Double.valueOf(123f);
-        } else if (type == Integer.class) {
-            return (T) Integer.valueOf(123);
-        } else if (type == String.class) {
-            return (T) "string";
-        } else {
-            throw new IllegalArgumentException("Type t not supported " + type);
-        }
+        }, new Plc4XS7Protocol());
     }
 
-    private VarPayloadItem varPayloadItemFor(Class type) {
-        // TODO: Most of these are just some value. We have to check if this is actually correct.
-        final DataTransportSize size;
-        final byte[] data;
-        if (type == Boolean.class) {
-            size = DataTransportSize.BIT;
-            data = new byte[]{(byte) 0b0};
-        } else if (type == Byte.class) {
-            size = DataTransportSize.BYTE_WORD_DWORD;
-            data = new byte[]{(byte) 0b0000_0000};
-        } else if (type == Short.class) {
-            size = DataTransportSize.BYTE_WORD_DWORD;
-            data = new byte[]{(byte) 0b0000_0000, (byte) 0b0000_0000};
-        } else if (type == Calendar.class) {
-            size = DataTransportSize.BYTE_WORD_DWORD;
-            // TODO: what size is calender?
-            data = new byte[]{(byte) 0b0000_0000};
-        } else if (type == Float.class) {
-            size = DataTransportSize.REAL;
-            data = new byte[]{(byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000};
-        } else if (type == Double.class) {
-            size = DataTransportSize.REAL;
-            data = new byte[]{(byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000};
-        } else if (type == Integer.class) {
-            size = DataTransportSize.INTEGER;
-            data = new byte[]{(byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000};
-        } else if (type == String.class) {
-            size = DataTransportSize.BYTE_WORD_DWORD;
-            data = new byte[]{(byte) 0xDE, (byte) 0x23, (byte) 'S', (byte) 't', (byte) 'r', (byte) 'i', (byte) 'n', (byte) 'g', (byte) 0x0};
-        } else {
-            throw new IllegalArgumentException("Type t not supported " + type);
-        }
-        return new VarPayloadItem(DataTransportErrorCode.OK, size, data);
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testInvalidFieldType() {
+        CompletableFuture<InternalPlcReadRequest> future = new CompletableFuture<>();
+        DefaultPlcReadRequest readRequest = mock(DefaultPlcReadRequest.class);
+        when(readRequest.getFieldNames()).thenReturn(new LinkedHashSet<>(Collections.singleton("foo")));
+        when(readRequest.getField("foo")).thenReturn(mock(PlcField.class));
+        PlcRequestContainer container = new PlcRequestContainer(readRequest, future);
+        ChannelFuture channelFuture = SUT.writeOneOutbound(container);
+        assertThat("The promise should have been set to 'success'", channelFuture.isSuccess(), equalTo(false));
+
+        Throwable exception = channelFuture.cause();
+        assertThat("An exception should have been thrown", exception, notNullValue());
+        assertThat(exception, instanceOf(EncoderException.class));
+        EncoderException encoderException = (EncoderException) exception;
+        assertThat(encoderException.getCause(), instanceOf(PlcProtocolException.class));
     }
 
-    private <T extends InternalPlcRequest> PlcRequestContainer createMockedContainer(T initialRequest) {
-        return createMockedContainer(initialRequest, null);
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testSimpleReadVarRequest() throws InterruptedException, ExecutionException, TimeoutException {
+        CompletableFuture<InternalPlcReadRequest> future = new CompletableFuture<>();
+        PlcRequestContainer container = new PlcRequestContainer(
+            (DefaultPlcReadRequest) readRequestBuilder.addItem("foo", "%Q0:BYTE").build(), future);
+        ChannelFuture channelFuture = SUT.writeOneOutbound(container);
+        assertThat("The promise should have been set to 'success'", channelFuture.isSuccess(), equalTo(true));
+
+        Throwable exception = channelFuture.cause();
+        assertThat("No exception should have been thrown", exception, nullValue());
+
+        S7Message writtenMessage = writeFuture.get(100, TimeUnit.MILLISECONDS);
+        assertThat("The protocol layer should have output something", writtenMessage, notNullValue());
+        assertThat("The protocol layer should have output something", writtenMessage, instanceOf(S7RequestMessage.class));
+
+        assertThat("The message should have one parameter", writtenMessage.getParameters(), hasSize(1));
+        assertThat("The message should have no payload", writtenMessage.getPayloads(), empty());
+        assertThat("The request container should be assigned parent to the write message",
+            writtenMessage.getParent(), equalTo(container));
+
+        assertThat(writtenMessage.getParameters().get(0), instanceOf(VarParameter.class));
+        VarParameter varParameter = (VarParameter) writtenMessage.getParameters().get(0);
+        assertThat(varParameter.getItems(), hasSize(1));
+
+        assertThat(varParameter.getItems().get(0), instanceOf(S7AnyVarParameterItem.class));
+        S7AnyVarParameterItem s7AnyVarParameterItem = (S7AnyVarParameterItem) varParameter.getItems().get(0);
+        assertThat(s7AnyVarParameterItem.getSpecificationType(), equalTo(SpecificationType.VARIABLE_SPECIFICATION));
+        assertThat(s7AnyVarParameterItem.getMemoryArea(), equalTo(MemoryArea.OUTPUTS));
+        assertThat(s7AnyVarParameterItem.getDataBlockNumber(), equalTo((short) 0));
+        assertThat(s7AnyVarParameterItem.getByteOffset(), equalTo((short) 0));
+        assertThat(s7AnyVarParameterItem.getBitOffset(), equalTo((byte) 0));
+        assertThat(s7AnyVarParameterItem.getNumElements(), equalTo(1));
+        assertThat(s7AnyVarParameterItem.getDataType(), equalTo(TransportSize.BYTE));
     }
 
-    private <T extends InternalPlcRequest> PlcRequestContainer createMockedContainer(T initialRequest, Consumer<T> requestEnricher) {
-        Objects.requireNonNull(initialRequest);
-        PlcRequestContainer mock = mock(PlcRequestContainer.class, RETURNS_DEEP_STUBS);
-        if (requestEnricher != null) {
-            requestEnricher.accept(initialRequest);
-        }
-        when(mock.getRequest()).thenReturn(initialRequest);
-        if (PlcReadRequest.class.isAssignableFrom(initialRequest.getClass())) {
-            return mock;
-        } else if (PlcWriteRequest.class.isAssignableFrom(initialRequest.getClass())) {
-            return mock;
-        } else {
-            throw new IllegalArgumentException("Unsupported Type: " + initialRequest.getClass());
-        }
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testSimpleWriteVarRequest() throws InterruptedException, ExecutionException, TimeoutException {
+        CompletableFuture<InternalPlcWriteRequest> future = new CompletableFuture<>();
+        PlcRequestContainer container = new PlcRequestContainer(
+            (DefaultPlcWriteRequest) writeRequestBuilder.addItem("foo", "%Q0:BYTE", (byte) 0x42).build(), future);
+        ChannelFuture channelFuture = SUT.writeOneOutbound(container);
+        assertThat("The promise should have been set to 'success'", channelFuture.isSuccess(), equalTo(true));
+
+        Throwable exception = channelFuture.cause();
+        assertThat("No exception should have been thrown", exception, nullValue());
+
+        S7Message writtenMessage = writeFuture.get(100, TimeUnit.MILLISECONDS);
+        assertThat("The protocol layer should have output something", writtenMessage, notNullValue());
+        assertThat("The protocol layer should have output something", writtenMessage, instanceOf(S7RequestMessage.class));
+
+        assertThat("The message should have one parameter", writtenMessage.getParameters(), hasSize(1));
+        assertThat("The message should have one payload", writtenMessage.getPayloads(), hasSize(1));
+        assertThat("The request container should be assigned parent to the write message",
+            writtenMessage.getParent(), equalTo(container));
+
+        assertThat(writtenMessage.getParameters().get(0), instanceOf(VarParameter.class));
+        VarParameter varParameter = (VarParameter) writtenMessage.getParameters().get(0);
+        assertThat(varParameter.getItems(), hasSize(1));
+        assertThat(varParameter.getItems().get(0), instanceOf(S7AnyVarParameterItem.class));
+        S7AnyVarParameterItem s7AnyVarParameterItem = (S7AnyVarParameterItem) varParameter.getItems().get(0);
+        assertThat(s7AnyVarParameterItem.getSpecificationType(), equalTo(SpecificationType.VARIABLE_SPECIFICATION));
+        assertThat(s7AnyVarParameterItem.getMemoryArea(), equalTo(MemoryArea.OUTPUTS));
+        assertThat(s7AnyVarParameterItem.getDataBlockNumber(), equalTo((short) 0));
+        assertThat(s7AnyVarParameterItem.getByteOffset(), equalTo((short) 0));
+        assertThat(s7AnyVarParameterItem.getBitOffset(), equalTo((byte) 0));
+        assertThat(s7AnyVarParameterItem.getNumElements(), equalTo(1));
+        assertThat(s7AnyVarParameterItem.getDataType(), equalTo(TransportSize.BYTE));
+
+        assertThat(writtenMessage.getPayloads().get(0), instanceOf(VarPayload.class));
+        VarPayload varPayload = (VarPayload) writtenMessage.getPayloads().get(0);
+        assertThat(varPayload.getItems(), hasSize(1));
+        assertThat(varPayload.getItems().get(0), instanceOf(VarPayloadItem.class));
+        VarPayloadItem varPayloadItem = varPayload.getItems().get(0);
+        assertThat(varPayloadItem.getReturnCode(), equalTo(DataTransportErrorCode.RESERVED));
+        assertThat(varPayloadItem.getDataTransportSize(), equalTo(DataTransportSize.BYTE_WORD_DWORD));
+        assertThat(varPayloadItem.getData(), notNullValue());
+        assertThat(varPayloadItem.getData().length, equalTo(1));
+        assertThat(varPayloadItem.getData()[0], equalTo((byte) 0x42));
     }
 
 }
diff --git a/plc4j/protocols/s7/src/test/resources/META-INF/services/com.athaydes.spockframework.report.IReportCreator.properties b/plc4j/protocols/s7/src/test/resources/META-INF/services/com.athaydes.spockframework.report.IReportCreator.properties
new file mode 100644
index 0000000..0759363
--- /dev/null
+++ b/plc4j/protocols/s7/src/test/resources/META-INF/services/com.athaydes.spockframework.report.IReportCreator.properties
@@ -0,0 +1,66 @@
+#
+# 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.
+#
+
+# Name of the implementation class(es) of report creator(s) to enable (separate multiple entries with commas)
+# Currently supported classes are:
+#   1. com.athaydes.spockframework.report.internal.HtmlReportCreator
+#   2. com.athaydes.spockframework.report.template.TemplateReportCreator
+com.athaydes.spockframework.report.IReportCreator=com.athaydes.spockframework.report.internal.HtmlReportCreator
+
+# Set properties of the report creator
+# For the HtmlReportCreator, the only properties available are
+# (the location of the css files is relative to the classpath):
+com.athaydes.spockframework.report.internal.HtmlReportCreator.featureReportCss=spock-feature-report.css
+com.athaydes.spockframework.report.internal.HtmlReportCreator.summaryReportCss=spock-summary-report.css
+com.athaydes.spockframework.report.internal.HtmlReportCreator.printThrowableStackTrace=false
+com.athaydes.spockframework.report.internal.HtmlReportCreator.inlineCss=true
+com.athaydes.spockframework.report.internal.HtmlReportCreator.enabled=true
+# options are: "class_name_and_title", "class_name", "title"
+com.athaydes.spockframework.report.internal.HtmlReportCreator.specSummaryNameOption=class_name_and_title
+
+# exclude Specs Table of Contents
+com.athaydes.spockframework.report.internal.HtmlReportCreator.excludeToc=false
+
+# Output directory (where the spock reports will be created) - relative to working directory
+com.athaydes.spockframework.report.outputDir=target/spock-reports
+
+# Output directory where to store the aggregated JSON report (used to support parallel builds)
+com.athaydes.spockframework.report.aggregatedJsonReportDir=
+
+# If set to true, hides blocks which do not have any description
+com.athaydes.spockframework.report.hideEmptyBlocks=false
+
+# Set the name of the project under test so it can be displayed in the report
+com.athaydes.spockframework.report.projectName=
+
+# Set the version of the project under test so it can be displayed in the report
+com.athaydes.spockframework.report.projectVersion=Unknown
+
+# Show the source code for each block
+com.athaydes.spockframework.report.showCodeBlocks=false
+
+# Set the root location of the Spock test source code (only used if showCodeBlocks is 'true')
+com.athaydes.spockframework.report.testSourceRoots=src/test/groovy
+
+# Set properties specific to the TemplateReportCreator
+com.athaydes.spockframework.report.template.TemplateReportCreator.specTemplateFile=/templateReportCreator/spec-template.md
+com.athaydes.spockframework.report.template.TemplateReportCreator.reportFileExtension=md
+com.athaydes.spockframework.report.template.TemplateReportCreator.summaryTemplateFile=/templateReportCreator/summary-template.md
+com.athaydes.spockframework.report.template.TemplateReportCreator.summaryFileName=summary.md
+com.athaydes.spockframework.report.template.TemplateReportCreator.enabled=true
\ No newline at end of file


[incubator-plc4x] 02/04: extracted AbstractPlcConnection class

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 89d8199e12c463f87b06393d5ad64672fa3628b1
Author: Andrey Skorikov <an...@codecentric.de>
AuthorDate: Fri Oct 26 15:32:06 2018 +0200

    extracted AbstractPlcConnection class
---
 .../base/connection/AbstractPlcConnection.java     | 77 ++++++++++++++++++++++
 .../java/base/connection/NettyPlcConnection.java   | 49 +-------------
 .../org/apache/plc4x/java/test/TestConnection.java | 31 ++-------
 3 files changed, 84 insertions(+), 73 deletions(-)

diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java
new file mode 100644
index 0000000..2a19470
--- /dev/null
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/AbstractPlcConnection.java
@@ -0,0 +1,77 @@
+/*
+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.base.connection;
+
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.exceptions.PlcUnsupportedOperationException;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
+import org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
+
+/**
+ * Base class for implementing connections.
+ * Per default, all operations (read, write, subscribe) are unsupported.
+ * Concrete implementations should override the methods indicating connection capabilities
+ * and for obtaining respective request builders.
+ */
+public abstract class AbstractPlcConnection implements PlcConnection, PlcConnectionMetadata {
+
+    @Override
+    public PlcConnectionMetadata getMetadata() {
+        return this;
+    }
+
+    @Override
+    public boolean canRead() {
+        return false;
+    }
+
+    @Override
+    public boolean canWrite() {
+        return false;
+    }
+
+    @Override
+    public boolean canSubscribe() {
+        return false;
+    }
+
+    @Override
+    public PlcReadRequest.Builder readRequestBuilder() {
+        throw new PlcUnsupportedOperationException("The connection does not support reading");
+    }
+
+    @Override
+    public PlcWriteRequest.Builder writeRequestBuilder() {
+        throw new PlcUnsupportedOperationException("The connection does not support writing");
+    }
+
+    @Override
+    public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() {
+        throw new PlcUnsupportedOperationException("The connection does not support subscription");
+    }
+
+    @Override
+    public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() {
+        throw new PlcUnsupportedOperationException("The connection does not support subscription");
+    }
+
+}
diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/NettyPlcConnection.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/NettyPlcConnection.java
index b271fb7..7dbb258 100644
--- a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/NettyPlcConnection.java
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/connection/NettyPlcConnection.java
@@ -22,21 +22,14 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timer;
-import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcIoException;
-import org.apache.plc4x.java.api.exceptions.PlcUnsupportedOperationException;
-import org.apache.plc4x.java.api.messages.PlcReadRequest;
-import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
-import org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest;
-import org.apache.plc4x.java.api.messages.PlcWriteRequest;
-import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
 
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
-public abstract class NettyPlcConnection implements PlcConnection, PlcConnectionMetadata {
+public abstract class NettyPlcConnection extends AbstractPlcConnection {
 
     /**
      * a {@link HashedWheelTimer} shall be only instantiated once.
@@ -107,46 +100,6 @@ public abstract class NettyPlcConnection implements PlcConnection, PlcConnection
         return connected;
     }
 
-    @Override
-    public PlcConnectionMetadata getMetadata() {
-        return this;
-    }
-
-    @Override
-    public boolean canRead() {
-        return false;
-    }
-
-    @Override
-    public boolean canWrite() {
-        return false;
-    }
-
-    @Override
-    public boolean canSubscribe() {
-        return false;
-    }
-
-    @Override
-    public PlcReadRequest.Builder readRequestBuilder() {
-        throw new PlcUnsupportedOperationException("The connection does not support reading");
-    }
-
-    @Override
-    public PlcWriteRequest.Builder writeRequestBuilder() {
-        throw new PlcUnsupportedOperationException("The connection does not support writing");
-    }
-
-    @Override
-    public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() {
-        throw new PlcUnsupportedOperationException("The connection does not support subscription");
-    }
-
-    @Override
-    public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() {
-        throw new PlcUnsupportedOperationException("The connection does not support subscription");
-    }
-
     public Channel getChannel() {
         return channel;
     }
diff --git a/plc4j/protocols/test/src/main/java/org/apache/plc4x/java/test/TestConnection.java b/plc4j/protocols/test/src/main/java/org/apache/plc4x/java/test/TestConnection.java
index 4a0199d..50ef026 100644
--- a/plc4j/protocols/test/src/main/java/org/apache/plc4x/java/test/TestConnection.java
+++ b/plc4j/protocols/test/src/main/java/org/apache/plc4x/java/test/TestConnection.java
@@ -20,11 +20,12 @@ package org.apache.plc4x.java.test;
 
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.plc4x.java.api.PlcConnection;
-import org.apache.plc4x.java.api.exceptions.PlcUnsupportedOperationException;
-import org.apache.plc4x.java.api.messages.*;
-import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteResponse;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
+import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
 import org.apache.plc4x.java.base.messages.*;
 import org.apache.plc4x.java.base.messages.items.BaseDefaultFieldItem;
 
@@ -37,7 +38,7 @@ import java.util.concurrent.CompletableFuture;
  * Connection to a test device.
  * This class is not thread-safe.
  */
-class TestConnection implements PlcConnection, PlcConnectionMetadata, PlcReader, PlcWriter {
+class TestConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
     private final TestDevice device;
     private boolean connected = false;
 
@@ -61,11 +62,6 @@ class TestConnection implements PlcConnection, PlcConnectionMetadata, PlcReader,
     }
 
     @Override
-    public PlcConnectionMetadata getMetadata() {
-        return this;
-    }
-
-    @Override
     public boolean canRead() {
         return true;
     }
@@ -76,11 +72,6 @@ class TestConnection implements PlcConnection, PlcConnectionMetadata, PlcReader,
     }
 
     @Override
-    public boolean canSubscribe() {
-        return false;
-    }
-
-    @Override
     public PlcReadRequest.Builder readRequestBuilder() {
         return new DefaultPlcReadRequest.Builder(this, new TestFieldHandler());
     }
@@ -91,16 +82,6 @@ class TestConnection implements PlcConnection, PlcConnectionMetadata, PlcReader,
     }
 
     @Override
-    public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() {
-        throw new PlcUnsupportedOperationException("The connection does not support subscription");
-    }
-
-    @Override
-    public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() {
-        throw new PlcUnsupportedOperationException("The connection does not support subscription");
-    }
-
-    @Override
     public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
         if(!(readRequest instanceof InternalPlcReadRequest)) {
             throw new IllegalArgumentException("Read request doesn't implement InternalPlcReadRequest");