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/10/17 16:48:17 UTC

[incubator-plc4x] 10/19: moved Request Builder factories to PlcConnection

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 e60f924c69be29890d62f3df6df4aeace6575965
Author: Andrey Skorikov <an...@codecentric.de>
AuthorDate: Thu Oct 4 15:22:12 2018 +0200

    moved Request Builder factories to PlcConnection
---
 .../azure/iothub/S7PlcToAzureIoTHubSample.java     |  2 +-
 .../dummydriver/connection/DummyConnection.java    | 32 +++++++++++++--------
 .../google/iotcore/S7PlcToGoogleIoTCoreSample.java |  2 +-
 .../plc4x/java/examples/helloplc4x/HelloPlc4x.java |  2 +-
 .../plc4x/java/examples/plclogger/PlcLogger.java   |  4 +--
 .../java/org/apache/plc4x/camel/Plc4XConsumer.java |  5 ++--
 .../apache/plc4x/camel/Plc4XPollingConsumer.java   |  2 +-
 .../java/org/apache/plc4x/camel/Plc4XProducer.java |  7 +++--
 .../java/org/apache/plc4x/camel/MockDriver.java    |  7 +++++
 .../org/apache/plc4x/camel/Plc4XEndpointTest.java  |  1 +
 .../org/apache/plc4x/camel/Plc4XProducerTest.java  |  7 +++++
 .../apache/plc4x/edgent/PlcConnectionAdapter.java  |  8 +++---
 .../apache/plc4x/edgent/mock/MockConnection.java   |  9 +++---
 .../java/org/apache/plc4x/kafka/Plc4xSinkTask.java |  2 +-
 .../org/apache/plc4x/kafka/Plc4xSourceTask.java    |  2 +-
 .../org/apache/plc4x/nifi/Plc4xSinkProcessor.java  |  6 ++--
 .../apache/plc4x/nifi/Plc4xSourceProcessor.java    |  6 ++--
 .../plc4x/java/api/connection/PlcConnection.java   |  6 ++--
 .../java/api/connection/PlcProprietarySender.java  |  1 -
 .../plc4x/java/api/connection/PlcReader.java       |  2 +-
 .../plc4x/java/api/connection/PlcSubscriber.java   |  4 +--
 .../plc4x/java/api/connection/PlcWriter.java       |  2 +-
 .../org/apache/plc4x/java/mock/MockConnection.java | 26 +++++++++++++++++
 .../ads/connection/AdsAbstractPlcConnection.java   | 29 +++++++++++++------
 .../ads/connection/AdsSerialPlcConnection.java     |  3 ++
 .../java/ads/connection/AdsTcpPlcConnection.java   | 14 +++++----
 .../apache/plc4x/java/ads/ManualPlc4XAdsTest.java  |  6 ++--
 .../ads/connection/AdsSerialPlcConnectionTest.java |  2 +-
 .../plc4x/java/base/connection/MockConnection.java | 26 ++++++++++++++++-
 .../connection/BaseEtherNetIpPlcConnection.java    | 20 +++++++------
 .../connection/EtherNetIpTcpPlcConnection.java     | 13 +++++++++
 .../java/ethernetip/ManualPlc4XEtherNetIpTest.java |  2 +-
 .../modbus/connection/BaseModbusPlcConnection.java | 30 ++++++++++++--------
 .../modbus/connection/ModbusTcpPlcConnection.java  |  3 ++
 .../plc4x/java/modbus/ManualPlc4XModbusTest.java   | 10 +++----
 .../connection/ModbusSerialPlcConnectionTest.java  |  2 +-
 .../plc4x/java/s7/connection/S7PlcConnection.java  | 30 ++++++++++++--------
 .../apache/plc4x/java/s7/issues/PLC4X47Test.java   |  2 +-
 .../org/apache/plc4x/java/test/TestConnection.java | 33 ++++++++++++++++------
 39 files changed, 258 insertions(+), 112 deletions(-)

diff --git a/examples/azure/src/main/java/org/apache/plc4x/java/examples/azure/iothub/S7PlcToAzureIoTHubSample.java b/examples/azure/src/main/java/org/apache/plc4x/java/examples/azure/iothub/S7PlcToAzureIoTHubSample.java
index 7bb03ec..a4f80cc 100644
--- a/examples/azure/src/main/java/org/apache/plc4x/java/examples/azure/iothub/S7PlcToAzureIoTHubSample.java
+++ b/examples/azure/src/main/java/org/apache/plc4x/java/examples/azure/iothub/S7PlcToAzureIoTHubSample.java
@@ -66,7 +66,7 @@ public class S7PlcToAzureIoTHubSample {
             PlcReader plcReader = plcConnection.getReader().orElseThrow(IllegalStateException::new);
 
             // Prepare a read request.
-            PlcReadRequest request = plcReader.readRequestBuilder().addItem(FIELD_NAME, addressString).build();
+            PlcReadRequest request = plcConnection.readRequestBuilder().get().addItem(FIELD_NAME, addressString).build();
 
             while (!Thread.currentThread().isInterrupted()) {
                 // Simulate telemetry.
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 4b7c00a..8fc73b4 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
@@ -23,10 +23,7 @@ import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelInitializer;
 import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.connection.PlcWriter;
-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.messages.*;
 import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
@@ -34,6 +31,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.net.InetAddress;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class DummyConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
@@ -58,9 +56,25 @@ public class DummyConnection extends AbstractPlcConnection implements PlcReader,
     }
 
     @Override
-    public PlcReadRequest.Builder readRequestBuilder() {
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
         // TODO: Implement this ...
-        return null;
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        // TODO: Implement this ...
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.empty();
     }
 
     @Override
@@ -74,12 +88,6 @@ public class DummyConnection extends AbstractPlcConnection implements PlcReader,
     }
 
     @Override
-    public PlcWriteRequest.Builder writeRequestBuilder() {
-        // TODO: Implement this ...
-        return null;
-    }
-
-    @Override
     public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
         CompletableFuture<InternalPlcWriteResponse> writeFuture = new CompletableFuture<>();
         PlcRequestContainer<InternalPlcWriteRequest, InternalPlcWriteResponse> container =
diff --git a/examples/google/src/main/java/org/apache/plc4x/java/examples/google/iotcore/S7PlcToGoogleIoTCoreSample.java b/examples/google/src/main/java/org/apache/plc4x/java/examples/google/iotcore/S7PlcToGoogleIoTCoreSample.java
index 29d25a3..fba969c 100644
--- a/examples/google/src/main/java/org/apache/plc4x/java/examples/google/iotcore/S7PlcToGoogleIoTCoreSample.java
+++ b/examples/google/src/main/java/org/apache/plc4x/java/examples/google/iotcore/S7PlcToGoogleIoTCoreSample.java
@@ -235,7 +235,7 @@ public class S7PlcToGoogleIoTCoreSample {
 
             PlcReader plcReader = plcConnection.getReader().orElseThrow(IllegalAccessError::new);
 
-            PlcReadRequest readRequest = plcReader.readRequestBuilder().addItem("outputs", "OUTPUTS/0").build();
+            PlcReadRequest readRequest = plcConnection.readRequestBuilder().get().addItem("outputs", "OUTPUTS/0").build();
 
             while (!Thread.currentThread().isInterrupted()) {
 
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
index d149ba5..402c856 100644
--- 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
@@ -57,7 +57,7 @@ public class HelloPlc4x {
 
                 // Create a new read request:
                 // - Give the single item requested the alias name "value"
-                PlcReadRequest.Builder builder = plcReader.readRequestBuilder();
+                PlcReadRequest.Builder builder = plcConnection.readRequestBuilder().get();
                 for (int i = 1; i < args.length; i++) {
                     builder.addItem("value-" + i, args[i]);
                 }
diff --git a/examples/plclogger/src/main/java/org/apache/plc4x/java/examples/plclogger/PlcLogger.java b/examples/plclogger/src/main/java/org/apache/plc4x/java/examples/plclogger/PlcLogger.java
index ffc14ec..bd2a066 100644
--- a/examples/plclogger/src/main/java/org/apache/plc4x/java/examples/plclogger/PlcLogger.java
+++ b/examples/plclogger/src/main/java/org/apache/plc4x/java/examples/plclogger/PlcLogger.java
@@ -18,8 +18,6 @@ under the License.
 */
 package org.apache.plc4x.java.examples.plclogger;
 
-import java.util.concurrent.TimeUnit;
-
 import org.apache.edgent.function.Supplier;
 import org.apache.edgent.providers.direct.DirectProvider;
 import org.apache.edgent.topology.TStream;
@@ -27,6 +25,8 @@ import org.apache.edgent.topology.Topology;
 import org.apache.plc4x.edgent.PlcConnectionAdapter;
 import org.apache.plc4x.edgent.PlcFunctions;
 
+import java.util.concurrent.TimeUnit;
+
 public class PlcLogger {
 
     public static void main(String[] args) throws Exception {
diff --git a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XConsumer.java b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XConsumer.java
index 7887f02..9ec281c 100644
--- a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XConsumer.java
+++ b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XConsumer.java
@@ -27,7 +27,6 @@ import org.apache.plc4x.java.api.connection.PlcConnection;
 import org.apache.plc4x.java.api.connection.PlcSubscriber;
 import org.apache.plc4x.java.api.exceptions.PlcException;
 import org.apache.plc4x.java.api.messages.*;
-import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -84,7 +83,7 @@ public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util
         PlcSubscriber plcSubscriber = plcConnection.getSubscriber().orElseThrow(
             () -> new PlcException("Connection doesn't support subscriptions."));
         // TODO: Is it correct to only support one field?
-        PlcSubscriptionRequest request = plcSubscriber.subscriptionRequestBuilder()
+        PlcSubscriptionRequest request = plcConnection.subscriptionRequestBuilder().get()
             .addCyclicField("default", fieldQuery, Duration.of(3, ChronoUnit.SECONDS)).build();
         PlcSubscriptionResponse plcSubscriptionResponse = plcSubscriber.subscribe(request).get();
         // TODO: we need to return the plcSubscriptionResponse here too as we need this to unsubscribe...
@@ -95,7 +94,7 @@ public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util
     protected void doStop() throws InterruptedException, ExecutionException, TimeoutException, PlcException {
         PlcSubscriber plcSubscriber = plcConnection.getSubscriber().orElseThrow(
             () -> new PlcException("Connection doesn't support subscriptions."));
-        PlcUnsubscriptionRequest request = plcSubscriber.unsubscriptionRequestBuilder().addHandles(subscriptionResponse.getSubscriptionHandles()).build();
+        PlcUnsubscriptionRequest request = plcConnection.unsubscriptionRequestBuilder().get().addHandles(subscriptionResponse.getSubscriptionHandles()).build();
         CompletableFuture<PlcUnsubscriptionResponse> unsubscriptionFuture = plcSubscriber.unsubscribe(request);
         PlcUnsubscriptionResponse unsubscriptionResponse = unsubscriptionFuture.get(5, TimeUnit.SECONDS);
         // TODO: Handle the response ...
diff --git a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XPollingConsumer.java b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XPollingConsumer.java
index 395398e..4aee7ad 100644
--- a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XPollingConsumer.java
+++ b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XPollingConsumer.java
@@ -55,7 +55,7 @@ public class Plc4XPollingConsumer extends ServiceSupport implements PollingConsu
         String plc4xURI = endpoint.getEndpointUri().replaceFirst("plc4x:/?/?", "");
         this.plcConnection = endpoint.getPlcDriverManager().getConnection(plc4xURI);
         this.plcReader = plcConnection.getReader().orElseThrow(() -> new PlcException("This connection doesn't support reading."));
-        readRequest = plcReader.readRequestBuilder().addItem("default", endpoint.getAddress()).build();
+        readRequest = plcConnection.readRequestBuilder().get().addItem("default", endpoint.getAddress()).build();
     }
 
     @Override
diff --git a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XProducer.java b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XProducer.java
index 01acff0..b4adbcc 100644
--- a/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XProducer.java
+++ b/integrations/apache-camel/src/main/java/org/apache/plc4x/camel/Plc4XProducer.java
@@ -34,14 +34,15 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 public class Plc4XProducer extends DefaultAsyncProducer {
     private PlcConnection plcConnection;
-    private PlcWriter plcWriter;
     private AtomicInteger openRequests;
 
     public Plc4XProducer(Plc4XEndpoint endpoint) throws PlcException {
         super(endpoint);
         String plc4xURI = endpoint.getEndpointUri().replaceFirst("plc4x:/?/?", "");
         plcConnection = endpoint.getPlcDriverManager().getConnection(plc4xURI);
-        plcWriter = plcConnection.getWriter().orElseThrow(() -> new PlcException("This connection doesn't support writing."));
+        if (!plcConnection.writeRequestBuilder().isPresent()) {
+            throw new PlcException("This connection (" + plc4xURI + ") doesn't support writing.");
+        }
         openRequests = new AtomicInteger();
     }
 
@@ -51,7 +52,6 @@ public class Plc4XProducer extends DefaultAsyncProducer {
         String fieldName = in.getHeader(Constants.FIELD_NAME_HEADER, String.class);
         String fieldQuery = in.getHeader(Constants.FIELD_QUERY_HEADER, String.class);
         Object body = in.getBody();
-        PlcWriteRequest.Builder builder = plcWriter.writeRequestBuilder();
         if (body instanceof List) {
             List<?> bodyList = in.getBody(List.class);
             Object[] values = bodyList.toArray();
@@ -61,6 +61,7 @@ public class Plc4XProducer extends DefaultAsyncProducer {
 //            builder.addItem(fieldName, fieldQuery, value);
         }
         PlcWriter plcWriter = plcConnection.getWriter().orElseThrow(() -> new IllegalArgumentException("Writer for driver not found"));
+        PlcWriteRequest.Builder builder = plcConnection.writeRequestBuilder().orElseThrow(() -> new IllegalArgumentException("Writer for driver not found"));
         CompletableFuture<? extends PlcWriteResponse> completableFuture = plcWriter.write(builder.build());
         int currentlyOpenRequests = openRequests.incrementAndGet();
         try {
diff --git a/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/MockDriver.java b/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/MockDriver.java
index fb99abe..9a3ea9e 100644
--- a/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/MockDriver.java
+++ b/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/MockDriver.java
@@ -21,10 +21,13 @@ package org.apache.plc4x.camel;
 import org.apache.plc4x.java.api.PlcDriver;
 import org.apache.plc4x.java.api.authentication.PlcAuthentication;
 import org.apache.plc4x.java.api.connection.PlcConnection;
+import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.connection.PlcSubscriber;
 import org.apache.plc4x.java.api.connection.PlcWriter;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
 import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.base.messages.DefaultPlcSubscriptionResponse;
 import org.apache.plc4x.java.base.messages.InternalPlcSubscriptionRequest;
 import org.slf4j.Logger;
@@ -59,6 +62,10 @@ public class MockDriver implements PlcDriver {
         // Mock a connection.
         PlcConnection plcConnectionMock = mock(PlcConnection.class, RETURNS_DEEP_STUBS);
         when(plcConnectionMock.getWriter()).thenReturn(Optional.of(mock(PlcWriter.class, RETURNS_DEEP_STUBS)));
+        when(plcConnectionMock.getReader()).thenReturn(Optional.of(mock(PlcReader.class, RETURNS_DEEP_STUBS)));
+        when(plcConnectionMock.readRequestBuilder()).thenReturn(Optional.of(mock(PlcReadRequest.Builder.class, RETURNS_DEEP_STUBS)));
+        when(plcConnectionMock.writeRequestBuilder()).thenReturn(Optional.of(mock(PlcWriteRequest.Builder.class, RETURNS_DEEP_STUBS)));
+        when(plcConnectionMock.subscriptionRequestBuilder()).thenReturn(Optional.of(mock(PlcSubscriptionRequest.Builder.class, RETURNS_DEEP_STUBS)));
 
         // Mock a typical subscriber.
         PlcSubscriber plcSubscriber = mock(PlcSubscriber.class, RETURNS_DEEP_STUBS);
diff --git a/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XEndpointTest.java b/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XEndpointTest.java
index d29b148..b849e2c 100644
--- a/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XEndpointTest.java
+++ b/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XEndpointTest.java
@@ -37,6 +37,7 @@ public class Plc4XEndpointTest {
         SUT = new Plc4XEndpoint("plc4x:mock:10.10.10.1/1/1", mock(Component.class));
     }
 
+    // TODO: figure out what this is
     @Test
     public void createProducer() throws Exception {
         assertThat(SUT.createProducer(), notNullValue());
diff --git a/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XProducerTest.java b/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XProducerTest.java
index f35ce3d..60706d6 100644
--- a/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XProducerTest.java
+++ b/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XProducerTest.java
@@ -23,6 +23,8 @@ import org.apache.camel.ExchangePattern;
 import org.apache.plc4x.java.PlcDriverManager;
 import org.apache.plc4x.java.api.connection.PlcConnection;
 import org.apache.plc4x.java.api.connection.PlcWriter;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -45,8 +47,13 @@ public class Plc4XProducerTest {
         Plc4XEndpoint endpointMock = mock(Plc4XEndpoint.class, RETURNS_DEEP_STUBS);
         when(endpointMock.getEndpointUri()).thenReturn("plc4x:mock:10.10.10.1/1/1");
         PlcDriverManager plcDriverManagerMock = mock(PlcDriverManager.class, RETURNS_DEEP_STUBS);
+
         when(plcDriverManagerMock.getConnection(anyString()).getWriter())
             .thenReturn(Optional.of(mock(PlcWriter.class, RETURNS_DEEP_STUBS)));
+
+        when(plcDriverManagerMock.getConnection(anyString()).writeRequestBuilder())
+            .thenReturn(Optional.of(mock(PlcWriteRequest.Builder.class, RETURNS_DEEP_STUBS)));
+
         when(endpointMock.getPlcDriverManager()).thenReturn(plcDriverManagerMock);
         SUT = new Plc4XProducer(endpointMock);
         testExchange = mock(Exchange.class, RETURNS_DEEP_STUBS);
diff --git a/integrations/apache-edgent/src/main/java/org/apache/plc4x/edgent/PlcConnectionAdapter.java b/integrations/apache-edgent/src/main/java/org/apache/plc4x/edgent/PlcConnectionAdapter.java
index 9ce5d92..4e1fbcd 100644
--- a/integrations/apache-edgent/src/main/java/org/apache/plc4x/edgent/PlcConnectionAdapter.java
+++ b/integrations/apache-edgent/src/main/java/org/apache/plc4x/edgent/PlcConnectionAdapter.java
@@ -104,8 +104,8 @@ public class PlcConnectionAdapter implements AutoCloseable {
     }
 
     public PlcReadRequest.Builder readRequestBuilder() throws PlcException {
-        return getConnection().getReader().orElseThrow(
-            () -> new PlcException("This connection doesn't support reading")).readRequestBuilder();
+        return getConnection().readRequestBuilder().orElseThrow(
+            () -> new PlcException("This connection doesn't support reading"));
     }
 
     Supplier<PlcReadResponse> newSupplier(PlcReadRequest readRequest) {
@@ -156,7 +156,7 @@ public class PlcConnectionAdapter implements AutoCloseable {
                 connection = getConnection();
                 PlcReader reader = connection.getReader()
                     .orElseThrow(() -> new PlcException("This connection doesn't support reading"));
-                PlcReadRequest readRequest = reader.readRequestBuilder().addItem(FIELD_NAME, fieldQuery).build();
+                PlcReadRequest readRequest = connection.readRequestBuilder().orElseThrow(() -> new PlcException("This connection doesn't support reading")).addItem(FIELD_NAME, fieldQuery).build();
                 PlcReadResponse readResponse = reader.read(readRequest).get();
                 Object value = null;
                 switch (clientDatatype) {
@@ -221,7 +221,7 @@ public class PlcConnectionAdapter implements AutoCloseable {
                 connection = getConnection();
                 PlcWriter writer = connection.getWriter()
                     .orElseThrow(() -> new PlcException("This connection doesn't support writing"));
-                PlcWriteRequest.Builder builder = writer.writeRequestBuilder();
+                PlcWriteRequest.Builder builder = connection.writeRequestBuilder().orElseThrow(() -> new PlcException("This connection doesn't support writing"));
                 PlcWriteRequest writeRequest = builder.build();
                 addItem(builder, clientDatatype, fieldQuery, fieldValue);
                 writer.write(writeRequest).get();
diff --git a/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java b/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
index e569e1e..f6de8d4 100644
--- a/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
+++ b/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
@@ -36,6 +36,7 @@ import org.apache.plc4x.java.base.messages.items.FieldItem;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class MockConnection extends org.apache.plc4x.java.base.connection.MockConnection implements PlcReader, PlcWriter {
@@ -67,8 +68,8 @@ public class MockConnection extends org.apache.plc4x.java.base.connection.MockCo
     }
 
     @Override
-    public PlcReadRequest.Builder readRequestBuilder() {
-        return new DefaultPlcReadRequest.Builder(this, new MockFieldHandler());
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
+        return Optional.of(new DefaultPlcReadRequest.Builder(this, new MockFieldHandler()));
     }
 
     @Override
@@ -90,8 +91,8 @@ public class MockConnection extends org.apache.plc4x.java.base.connection.MockCo
     }
 
     @Override
-    public PlcWriteRequest.Builder writeRequestBuilder() {
-        return new DefaultPlcWriteRequest.Builder(this, new MockFieldHandler());
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new MockFieldHandler()));
     }
 
     @SuppressWarnings("unchecked")
diff --git a/integrations/apache-kafka/src/main/java/org/apache/plc4x/kafka/Plc4xSinkTask.java b/integrations/apache-kafka/src/main/java/org/apache/plc4x/kafka/Plc4xSinkTask.java
index 648a32e..6829294 100644
--- a/integrations/apache-kafka/src/main/java/org/apache/plc4x/kafka/Plc4xSinkTask.java
+++ b/integrations/apache-kafka/src/main/java/org/apache/plc4x/kafka/Plc4xSinkTask.java
@@ -65,7 +65,7 @@ public class Plc4xSinkTask extends SinkTask {
         for (SinkRecord record: records) {
             String query = record.key().toString();
             Object value = record.value();
-            PlcWriteRequest.Builder builder = plcWriter.writeRequestBuilder();
+            PlcWriteRequest.Builder builder = plcConnection.writeRequestBuilder().get();
             PlcWriteRequest plcRequest = addToBuilder(builder, query, value).build();
             doWrite(plcRequest);
         }
diff --git a/integrations/apache-kafka/src/main/java/org/apache/plc4x/kafka/Plc4xSourceTask.java b/integrations/apache-kafka/src/main/java/org/apache/plc4x/kafka/Plc4xSourceTask.java
index 62fbb12..08b3ec1 100644
--- a/integrations/apache-kafka/src/main/java/org/apache/plc4x/kafka/Plc4xSourceTask.java
+++ b/integrations/apache-kafka/src/main/java/org/apache/plc4x/kafka/Plc4xSourceTask.java
@@ -86,7 +86,7 @@ public class Plc4xSourceTask extends SourceTask {
             .orElseThrow(() -> new ConnectException("PlcReader not available for this type of connection"));
 
 
-        PlcReadRequest.Builder builder = plcReader.readRequestBuilder();
+        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder().get();
         for (String query : queries) {
             builder.addItem(query, query);
         }
diff --git a/integrations/apache-nifi/nifi-plc4x-processors/src/main/java/org/apache/plc4x/nifi/Plc4xSinkProcessor.java b/integrations/apache-nifi/nifi-plc4x-processors/src/main/java/org/apache/plc4x/nifi/Plc4xSinkProcessor.java
index ab7b0a0..973855b 100644
--- a/integrations/apache-nifi/nifi-plc4x-processors/src/main/java/org/apache/plc4x/nifi/Plc4xSinkProcessor.java
+++ b/integrations/apache-nifi/nifi-plc4x-processors/src/main/java/org/apache/plc4x/nifi/Plc4xSinkProcessor.java
@@ -28,6 +28,7 @@ import org.apache.nifi.flowfile.FlowFile;
 import org.apache.nifi.processor.ProcessContext;
 import org.apache.nifi.processor.ProcessSession;
 import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.plc4x.java.api.connection.PlcConnection;
 import org.apache.plc4x.java.api.connection.PlcWriter;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteResponse;
@@ -51,11 +52,12 @@ public class Plc4xSinkProcessor extends BasePlc4xProcessor {
         }
 
         // Get an instance of a component able to write to a PLC.
-        PlcWriter writer = getConnection().getWriter().orElseThrow(
+        PlcConnection connection = getConnection();
+        PlcWriter writer = connection.getWriter().orElseThrow(
             () -> new ProcessException("Writing not supported by connection"));
 
         // Prepare the request.
-        PlcWriteRequest.Builder builder = writer.writeRequestBuilder();
+        PlcWriteRequest.Builder builder = connection.writeRequestBuilder().get();
         flowFile.getAttributes().forEach((field, value) -> {
             String address = getAddress(field);
             if(address != null) {
diff --git a/integrations/apache-nifi/nifi-plc4x-processors/src/main/java/org/apache/plc4x/nifi/Plc4xSourceProcessor.java b/integrations/apache-nifi/nifi-plc4x-processors/src/main/java/org/apache/plc4x/nifi/Plc4xSourceProcessor.java
index f3dbb59..190a00d 100644
--- a/integrations/apache-nifi/nifi-plc4x-processors/src/main/java/org/apache/plc4x/nifi/Plc4xSourceProcessor.java
+++ b/integrations/apache-nifi/nifi-plc4x-processors/src/main/java/org/apache/plc4x/nifi/Plc4xSourceProcessor.java
@@ -27,6 +27,7 @@ import org.apache.nifi.flowfile.FlowFile;
 import org.apache.nifi.processor.ProcessContext;
 import org.apache.nifi.processor.ProcessSession;
 import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.plc4x.java.api.connection.PlcConnection;
 import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
@@ -45,11 +46,12 @@ public class Plc4xSourceProcessor extends BasePlc4xProcessor {
     @Override
     public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
         // Get an instance of a component able to read from a PLC.
-        PlcReader reader = getConnection().getReader().orElseThrow(
+        PlcConnection connection = getConnection();
+        PlcReader reader = connection.getReader().orElseThrow(
             () -> new ProcessException("Writing not supported by connection"));
 
         // Prepare the request.
-        PlcReadRequest.Builder builder = reader.readRequestBuilder();
+        PlcReadRequest.Builder builder = connection.readRequestBuilder().get();
         getFields().forEach(field -> {
             String address = getAddress(field);
             if(address != null) {
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
index 4c2b197..66a3778 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
@@ -57,13 +57,15 @@ public interface PlcConnection extends AutoCloseable {
     @Override
     void close() throws Exception;
 
-    /*Optional<PlcReadRequest.Builder> readRequestBuilder();
+    Optional<PlcReadRequest.Builder> readRequestBuilder();
 
     Optional<PlcWriteRequest.Builder> writeRequestBuilder();
 
     Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder();
 
-    Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder();*/
+    Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder();
+
+    // the following methods should be moved to the SPI
 
     Optional<PlcReader> getReader();
 
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcProprietarySender.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcProprietarySender.java
index 2a053cb..80db408 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcProprietarySender.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcProprietarySender.java
@@ -24,6 +24,5 @@ import org.apache.plc4x.java.api.messages.PlcProprietaryResponse;
 import java.util.concurrent.CompletableFuture;
 
 public interface PlcProprietarySender {
-
     <T> CompletableFuture<PlcProprietaryResponse<T>> send(PlcProprietaryRequest proprietaryRequest);
 }
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcReader.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcReader.java
index b78d306..6d50da0 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcReader.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcReader.java
@@ -37,6 +37,6 @@ public interface PlcReader {
      */
     CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest);
 
-    PlcReadRequest.Builder readRequestBuilder();
+    //PlcReadRequest.Builder readRequestBuilder();
 
 }
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcSubscriber.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcSubscriber.java
index 1f582cb..d1c97ba 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcSubscriber.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcSubscriber.java
@@ -62,8 +62,8 @@ public interface PlcSubscriber {
      */
     void unregister(PlcConsumerRegistration registration);
 
-    PlcSubscriptionRequest.Builder subscriptionRequestBuilder();
+    //PlcSubscriptionRequest.Builder subscriptionRequestBuilder();
 
-    PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder();
+    //PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder();
 
 }
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcWriter.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcWriter.java
index b22977f..a4e44bf 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcWriter.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcWriter.java
@@ -37,6 +37,6 @@ public interface PlcWriter {
      */
     CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest);
 
-    PlcWriteRequest.Builder writeRequestBuilder();
+    //PlcWriteRequest.Builder writeRequestBuilder();
 
 }
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 0be37f9..fc52100 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,10 +22,15 @@ 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.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.model.PlcField;
 import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
 import org.apache.plc4x.java.base.connection.TestChannelFactory;
 
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class MockConnection extends AbstractPlcConnection {
@@ -38,6 +43,27 @@ public class MockConnection extends AbstractPlcConnection {
     }
 
     @Override
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+
+    @Override
     protected ChannelHandler getChannelHandler(CompletableFuture<Void> sessionSetupCompleteFuture) {
         return new ChannelInitializer() {
             @Override
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 5795a6f..de0e75d 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
@@ -43,6 +43,7 @@ import org.apache.plc4x.java.base.messages.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Optional;
 import java.util.concurrent.*;
 
 public abstract class AdsAbstractPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter, PlcProprietarySender {
@@ -106,8 +107,23 @@ public abstract class AdsAbstractPlcConnection extends AbstractPlcConnection imp
     }
 
     @Override
-    public PlcReadRequest.Builder readRequestBuilder() {
-        return new DefaultPlcReadRequest.Builder(this, new AdsPlcFieldHandler());
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
+        return Optional.of(new DefaultPlcReadRequest.Builder(this, new AdsPlcFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new AdsPlcFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.empty();
     }
 
     @Override
@@ -125,13 +141,8 @@ public abstract class AdsAbstractPlcConnection extends AbstractPlcConnection imp
     }
 
     @Override
-    public PlcWriteRequest.Builder writeRequestBuilder() {
-        return new DefaultPlcWriteRequest.Builder(this, new AdsPlcFieldHandler());
-    }
-
-    @Override
-    public <PROP_RESPONSE> CompletableFuture<PlcProprietaryResponse<PROP_RESPONSE>> send(PlcProprietaryRequest proprietaryRequest) {
-        CompletableFuture<InternalPlcProprietaryResponse<PROP_RESPONSE>> sendFuture = new CompletableFuture<>();
+    public <T> CompletableFuture<PlcProprietaryResponse<T>> send(PlcProprietaryRequest proprietaryRequest) {
+        CompletableFuture<InternalPlcProprietaryResponse<T>> sendFuture = new CompletableFuture<>();
         ChannelFuture channelFuture = channel.writeAndFlush(new PlcRequestContainer<>((InternalPlcProprietaryRequest) proprietaryRequest, sendFuture));
         channelFuture.addListener(future -> {
             if (!future.isSuccess()) {
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnection.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnection.java
index cb2d00a..3d4c8ba 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnection.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnection.java
@@ -28,9 +28,12 @@ import org.apache.plc4x.java.ads.protocol.Ads2PayloadProtocol;
 import org.apache.plc4x.java.ads.protocol.Payload2SerialProtocol;
 import org.apache.plc4x.java.ads.protocol.Plc4x2AdsProtocol;
 import org.apache.plc4x.java.ads.protocol.util.SingleMessageRateLimiter;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
+import org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest;
 import org.apache.plc4x.java.base.connection.SerialChannelFactory;
 import org.apache.plc4x.java.base.protocol.SingleItemToSingleRequestProtocol;
 
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class AdsSerialPlcConnection extends AdsAbstractPlcConnection {
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsTcpPlcConnection.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsTcpPlcConnection.java
index d88dee7..4d582e7 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsTcpPlcConnection.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsTcpPlcConnection.java
@@ -43,7 +43,6 @@ import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
-import org.apache.plc4x.java.base.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.base.model.InternalPlcConsumerRegistration;
 import org.apache.plc4x.java.base.model.InternalPlcSubscriptionHandle;
 import org.apache.plc4x.java.base.protocol.SingleItemToSingleRequestProtocol;
@@ -53,7 +52,10 @@ import org.slf4j.LoggerFactory;
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
@@ -311,13 +313,13 @@ public class AdsTcpPlcConnection extends AdsAbstractPlcConnection implements Plc
     }
 
     @Override
-    public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() {
-        return new DefaultPlcSubscriptionRequest.Builder(this, new AdsPlcFieldHandler());
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.of(new DefaultPlcSubscriptionRequest.Builder(this, new AdsPlcFieldHandler()));
     }
 
     @Override
-    public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() {
-        return new DefaultPlcUnsubscriptionRequest.Builder(this);
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.of(new DefaultPlcUnsubscriptionRequest.Builder(this));
     }
 
     @Override
diff --git a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/ManualPlc4XAdsTest.java b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/ManualPlc4XAdsTest.java
index ad56e01..6e99861 100644
--- a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/ManualPlc4XAdsTest.java
+++ b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/ManualPlc4XAdsTest.java
@@ -45,7 +45,7 @@ public class ManualPlc4XAdsTest {
 
             PlcReader reader = plcConnection.getReader().orElseThrow(() -> new RuntimeException("No Reader found"));
 
-            PlcReadRequest readRequest = reader.readRequestBuilder().addItem("station", "Allgemein_S2.Station:BYTE").build();
+            PlcReadRequest readRequest = plcConnection.readRequestBuilder().get().addItem("station", "Allgemein_S2.Station:BYTE").build();
             CompletableFuture<PlcReadResponse> response = reader.read(readRequest);
             PlcReadResponse readResponse = response.get();
             System.out.println("Response " + readResponse);
@@ -54,7 +54,7 @@ public class ManualPlc4XAdsTest {
 
             PlcSubscriber plcSubscriber = plcConnection.getSubscriber().orElseThrow(() -> new RuntimeException("Subscribe not available"));
 
-            PlcSubscriptionRequest subscriptionRequest = plcSubscriber.subscriptionRequestBuilder().addChangeOfStateField("stationChange", "Allgemein_S2.Station:BYTE").build();
+            PlcSubscriptionRequest subscriptionRequest = plcConnection.subscriptionRequestBuilder().get().addChangeOfStateField("stationChange", "Allgemein_S2.Station:BYTE").build();
             CompletableFuture<PlcSubscriptionResponse> subscribeResponse = plcSubscriber.subscribe(subscriptionRequest);
             PlcSubscriptionResponse plcSubscriptionResponse = subscribeResponse.get();
 
@@ -63,7 +63,7 @@ public class ManualPlc4XAdsTest {
             TimeUnit.SECONDS.sleep(5);
 
             plcSubscriber.unregister(plcConsumerRegistration);
-            PlcUnsubscriptionRequest unsubscriptionRequest = plcSubscriber.unsubscriptionRequestBuilder().addHandles(plcSubscriptionResponse.getSubscriptionHandles()).build();
+            PlcUnsubscriptionRequest unsubscriptionRequest = plcConnection.unsubscriptionRequestBuilder().get().addHandles(plcSubscriptionResponse.getSubscriptionHandles()).build();
             CompletableFuture<PlcUnsubscriptionResponse> unsubscriptionResponse = plcSubscriber.unsubscribe(unsubscriptionRequest);
 
             unsubscriptionResponse
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..624e607 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
@@ -76,7 +76,7 @@ public class AdsSerialPlcConnectionTest {
     @Test
     public void testRead() throws Exception {
         prepareSerialSimulator();
-        PlcReadRequest request = SUT.readRequestBuilder().addItem("test", "0/0:BYTE").build();
+        PlcReadRequest request = SUT.readRequestBuilder().get().addItem("test", "0/0:BYTE").build();
         CompletableFuture<PlcReadResponse> read = SUT.read(request);
         PlcReadResponse plcReadResponse = read.get(30, TimeUnit.SECONDS);
         assertNotNull(plcReadResponse);
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 3c64768..21d19d2 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
@@ -19,8 +19,12 @@ under the License.
 package org.apache.plc4x.java.base.connection;
 
 import io.netty.channel.ChannelHandler;
-import org.apache.plc4x.java.api.model.PlcField;
+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 java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class MockConnection extends AbstractPlcConnection {
@@ -34,6 +38,26 @@ public class MockConnection extends AbstractPlcConnection {
     }
 
     @Override
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
     protected ChannelHandler getChannelHandler(CompletableFuture<Void> sessionSetupCompleteFuture) {
         return null;
     }
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 ee81291..269b676 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
@@ -21,7 +21,10 @@ package org.apache.plc4x.java.ethernetip.connection;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.connection.PlcWriter;
-import org.apache.plc4x.java.api.messages.*;
+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.ChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
@@ -29,6 +32,7 @@ import org.apache.plc4x.java.ethernetip.netty.util.EnipPlcFieldHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public abstract class BaseEtherNetIpPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
@@ -56,8 +60,13 @@ public abstract class BaseEtherNetIpPlcConnection extends AbstractPlcConnection
     }
 
     @Override
-    public PlcReadRequest.Builder readRequestBuilder() {
-        return new DefaultPlcReadRequest.Builder(this, new EnipPlcFieldHandler());
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
+        return Optional.of(new DefaultPlcReadRequest.Builder(this, new EnipPlcFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new EnipPlcFieldHandler()));
     }
 
     @Override
@@ -75,11 +84,6 @@ public abstract class BaseEtherNetIpPlcConnection extends AbstractPlcConnection
     }
 
     @Override
-    public PlcWriteRequest.Builder writeRequestBuilder() {
-        return new DefaultPlcWriteRequest.Builder(this, new EnipPlcFieldHandler());
-    }
-
-    @Override
     public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
         CompletableFuture<InternalPlcWriteResponse> future = new CompletableFuture<>();
         PlcRequestContainer<InternalPlcWriteRequest, InternalPlcWriteResponse> container =
diff --git a/plc4j/protocols/ethernetip/src/main/java/org/apache/plc4x/java/ethernetip/connection/EtherNetIpTcpPlcConnection.java b/plc4j/protocols/ethernetip/src/main/java/org/apache/plc4x/java/ethernetip/connection/EtherNetIpTcpPlcConnection.java
index e14ac19..3f0ed79 100644
--- a/plc4j/protocols/ethernetip/src/main/java/org/apache/plc4x/java/ethernetip/connection/EtherNetIpTcpPlcConnection.java
+++ b/plc4j/protocols/ethernetip/src/main/java/org/apache/plc4x/java/ethernetip/connection/EtherNetIpTcpPlcConnection.java
@@ -19,6 +19,8 @@ under the License.
 package org.apache.plc4x.java.ethernetip.connection;
 
 import io.netty.channel.*;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
+import org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest;
 import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
 import org.apache.plc4x.java.base.events.ConnectEvent;
@@ -29,6 +31,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.net.InetAddress;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class EtherNetIpTcpPlcConnection extends BaseEtherNetIpPlcConnection {
@@ -53,6 +56,16 @@ public class EtherNetIpTcpPlcConnection extends BaseEtherNetIpPlcConnection {
     }
 
     @Override
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
     protected ChannelHandler getChannelHandler(CompletableFuture<Void> sessionSetupCompleteFuture) {
         return new ChannelInitializer() {
             @Override
diff --git a/plc4j/protocols/ethernetip/src/test/java/org/apache/plc4x/java/ethernetip/ManualPlc4XEtherNetIpTest.java b/plc4j/protocols/ethernetip/src/test/java/org/apache/plc4x/java/ethernetip/ManualPlc4XEtherNetIpTest.java
index ba08d13..949eaeb 100644
--- a/plc4j/protocols/ethernetip/src/test/java/org/apache/plc4x/java/ethernetip/ManualPlc4XEtherNetIpTest.java
+++ b/plc4j/protocols/ethernetip/src/test/java/org/apache/plc4x/java/ethernetip/ManualPlc4XEtherNetIpTest.java
@@ -37,7 +37,7 @@ public class ManualPlc4XEtherNetIpTest {
             // Get a reader instance.
             PlcReader reader = plcConnection.getReader().orElseThrow(() -> new RuntimeException("No Reader found"));
 
-            PlcReadRequest readRequest = reader.readRequestBuilder()
+            PlcReadRequest readRequest = plcConnection.readRequestBuilder().get()
                 .addItem("field", "#4#105#3").build();
 
             // Execute the read operation.
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 68e38a2..69e99fd 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
@@ -21,10 +21,7 @@ package org.apache.plc4x.java.modbus.connection;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.connection.PlcWriter;
-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.messages.*;
 import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
 import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
@@ -32,6 +29,7 @@ import org.apache.plc4x.java.modbus.util.ModbusPlcFieldHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public abstract class BaseModbusPlcConnection extends AbstractPlcConnection implements PlcReader, PlcWriter {
@@ -59,8 +57,23 @@ public abstract class BaseModbusPlcConnection extends AbstractPlcConnection impl
     }
 
     @Override
-    public PlcReadRequest.Builder readRequestBuilder() {
-        return new DefaultPlcReadRequest.Builder(this, new ModbusPlcFieldHandler());
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
+        return Optional.of(new DefaultPlcReadRequest.Builder(this, new ModbusPlcFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new ModbusPlcFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.empty();
     }
 
     @Override
@@ -78,11 +91,6 @@ public abstract class BaseModbusPlcConnection extends AbstractPlcConnection impl
     }
 
     @Override
-    public PlcWriteRequest.Builder writeRequestBuilder() {
-        return new DefaultPlcWriteRequest.Builder(this, new ModbusPlcFieldHandler());
-    }
-
-    @Override
     public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
         CompletableFuture<InternalPlcWriteResponse> future = new CompletableFuture<>();
         PlcRequestContainer<InternalPlcWriteRequest, InternalPlcWriteResponse> container =
diff --git a/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/connection/ModbusTcpPlcConnection.java b/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/connection/ModbusTcpPlcConnection.java
index 5e5be0c..8df399e 100644
--- a/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/connection/ModbusTcpPlcConnection.java
+++ b/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/connection/ModbusTcpPlcConnection.java
@@ -24,6 +24,8 @@ import com.digitalpetri.modbus.codec.ModbusTcpCodec;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelInitializer;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
+import org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest;
 import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
 import org.apache.plc4x.java.base.protocol.SingleItemToSingleRequestProtocol;
@@ -32,6 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.net.InetAddress;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class ModbusTcpPlcConnection extends BaseModbusPlcConnection {
diff --git a/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/ManualPlc4XModbusTest.java b/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/ManualPlc4XModbusTest.java
index 401c872..3f6c786 100644
--- a/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/ManualPlc4XModbusTest.java
+++ b/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/ManualPlc4XModbusTest.java
@@ -52,7 +52,7 @@ public class ManualPlc4XModbusTest {
             {
                 PlcReader reader = plcConnection.getReader().orElseThrow(() -> new RuntimeException("No Reader found"));
 
-                PlcReadRequest readRequest = reader.readRequestBuilder().addItem("randomRegister", "register:7[3]").build();
+                PlcReadRequest readRequest = plcConnection.readRequestBuilder().get().addItem("randomRegister", "register:7[3]").build();
                 PlcReadResponse readResponse = reader.read(readRequest).get();
                 System.out.println("Response " + readResponse);
                 readResponse.getAllByteArrays("randomRegister").stream()
@@ -66,7 +66,7 @@ public class ManualPlc4XModbusTest {
                 PlcReader reader = plcConnection.getReader().orElseThrow(() -> new RuntimeException("No Reader found"));
 
                 // Just dump the actual values
-                PlcReadRequest readRequest = reader.readRequestBuilder().addItem("randomRegister", "register:3[2]").build();
+                PlcReadRequest readRequest = plcConnection.readRequestBuilder().get().addItem("randomRegister", "register:3[2]").build();
                 PlcReadResponse readResponse = reader.read(readRequest).get();
                 System.out.println("Response " + readResponse);
                 Collection<Byte[]> randomRegisters = readResponse.getAllByteArrays("randomRegister");
@@ -90,7 +90,7 @@ public class ManualPlc4XModbusTest {
                 PlcReader reader = plcConnection.getReader().orElseThrow(() -> new RuntimeException("No Reader found"));
 
                 // Just dump the actual values
-                PlcReadRequest readRequest = reader.readRequestBuilder()
+                PlcReadRequest readRequest = plcConnection.readRequestBuilder().get()
                     .addItem("randomRegister1", "register:1[2]")
                     .addItem("randomRegister2", "register:10[3]")
                     .addItem("randomRegister3", "register:20[4]")
@@ -120,7 +120,7 @@ public class ManualPlc4XModbusTest {
             {
                 PlcReader reader = plcConnection.getReader().orElseThrow(() -> new RuntimeException("No Reader found"));
 
-                PlcReadRequest readRequest = reader.readRequestBuilder().addItem("randomCoil", "coil:1[9]").build();
+                PlcReadRequest readRequest = plcConnection.readRequestBuilder().get().addItem("randomCoil", "coil:1[9]").build();
                 PlcReadResponse readResponse = reader.read(readRequest).get();
                 System.out.println("Response " + readResponse);
                 readResponse.getAllBooleans("randomCoil").stream()
@@ -131,7 +131,7 @@ public class ManualPlc4XModbusTest {
             {
                 PlcWriter writer = plcConnection.getWriter().orElseThrow(() -> new RuntimeException("No Writer found"));
 
-                PlcWriteRequest writeRequest = writer.writeRequestBuilder().addItem("randomCoilField", "coil:1", true).build();
+                PlcWriteRequest writeRequest = plcConnection.writeRequestBuilder().get().addItem("randomCoilField", "coil:1", true).build();
                 PlcWriteResponse writeResponse = writer.write(writeRequest).get();
                 System.out.println("Response " + writeResponse);
             }
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..1179ee0 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
@@ -66,7 +66,7 @@ public class ModbusSerialPlcConnectionTest {
     @Test
     public void testRead() throws Exception {
         prepareSerialSimulator();
-        PlcReadRequest readRequest = SUT.readRequestBuilder().addItem("randomRead", "0/0").build();
+        PlcReadRequest readRequest = SUT.readRequestBuilder().get().addItem("randomRead", "0/0").build();
         CompletableFuture<PlcReadResponse> read = SUT.read(readRequest);
         PlcReadResponse plcReadResponse = read.get(30, TimeUnit.SECONDS);
         assertNotNull(plcReadResponse);
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 05c815a..090f803 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
@@ -25,10 +25,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.connection.PlcWriter;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-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.messages.*;
 import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
 import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.connection.TcpSocketChannelFactory;
@@ -51,6 +48,7 @@ import org.slf4j.LoggerFactory;
 
 import java.net.InetAddress;
 import java.util.Collections;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -237,8 +235,23 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
     }
 
     @Override
-    public PlcReadRequest.Builder readRequestBuilder() {
-        return new DefaultPlcReadRequest.Builder(this, new S7PlcFieldHandler());
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
+        return Optional.of(new DefaultPlcReadRequest.Builder(this, new S7PlcFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new S7PlcFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.empty();
     }
 
     @Override
@@ -256,11 +269,6 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
     }
 
     @Override
-    public PlcWriteRequest.Builder writeRequestBuilder() {
-        return new DefaultPlcWriteRequest.Builder(this, new S7PlcFieldHandler());
-    }
-
-    @Override
     public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
         CompletableFuture<InternalPlcWriteResponse> future = new CompletableFuture<>();
         PlcRequestContainer<InternalPlcWriteRequest, InternalPlcWriteResponse> container =
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/issues/PLC4X47Test.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/issues/PLC4X47Test.java
index 3683f83..100a677 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/issues/PLC4X47Test.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/issues/PLC4X47Test.java
@@ -38,7 +38,7 @@ public class PLC4X47Test {
         EmbeddedChannel channel = channelFactory.getChannel();*/
         S7PlcConnection connection = (S7PlcConnection) new PlcDriverManager().getConnection("s7://10.10.64.20/1/1");
 
-        PlcReadRequest.Builder builder = connection.readRequestBuilder();
+        PlcReadRequest.Builder builder = connection.readRequestBuilder().get();
         for (int i = 1; i <= 30; i++) {
             // just the first byte of each db
             builder.addItem("field-" + i, "%DB3.DB" + i + ":SINT");
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 1937676..68b1ba3 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,13 +20,18 @@ 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.connection.*;
+import org.apache.plc4x.java.api.connection.PlcConnection;
+import org.apache.plc4x.java.api.connection.PlcReader;
+import org.apache.plc4x.java.api.connection.PlcSubscriber;
+import org.apache.plc4x.java.api.connection.PlcWriter;
 import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.base.messages.*;
 import org.apache.plc4x.java.base.messages.items.FieldItem;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 /**
@@ -72,8 +77,23 @@ class TestConnection implements PlcConnection, PlcReader, PlcWriter {
     }
 
     @Override
-    public PlcReadRequest.Builder readRequestBuilder() {
-        return new DefaultPlcReadRequest.Builder(this, new TestFieldHandler());
+    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
+        return Optional.of(new DefaultPlcReadRequest.Builder(this, new TestFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
+        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new TestFieldHandler()));
+    }
+
+    @Override
+    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
+        return Optional.empty();
     }
 
     @Override
@@ -98,11 +118,6 @@ class TestConnection implements PlcConnection, PlcReader, PlcWriter {
     }
 
     @Override
-    public PlcWriteRequest.Builder writeRequestBuilder() {
-        return new DefaultPlcWriteRequest.Builder(this, new TestFieldHandler());
-    }
-
-    @Override
     public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
         if(!(writeRequest instanceof InternalPlcWriteRequest)) {
             throw new IllegalArgumentException("Read request doesn't implement InternalPlcWriteRequest");