You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sk...@apache.org on 2018/10/26 12:18:42 UTC

[incubator-plc4x] branch feature/connection-metadata created (now 479f3a7)

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

skorikov pushed a change to branch feature/connection-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git.


      at 479f3a7  removed optionals

This branch includes the following new commits:

     new 6565175  added metadata interface
     new eb1d272  added metadata operation
     new 19552c6  added UnsopportedOperationException
     new 479f3a7  removed optionals

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.



[incubator-plc4x] 02/04: added metadata operation

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

skorikov pushed a commit to branch feature/connection-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit eb1d27264698ec3aa45c5c38892490cfa3e28fef
Author: Andrey Skorikov <an...@codecentric.de>
AuthorDate: Fri Oct 26 11:59:56 2018 +0200

    added metadata operation
---
 .../apache/plc4x/edgent/mock/MockConnection.java   | 10 ++++++++++
 .../org/apache/plc4x/java/api/PlcConnection.java   |  6 ++++++
 .../ads/connection/AdsAbstractPlcConnection.java   | 10 ++++++++++
 .../base/connection/AbstractPlcConnection.java     | 23 +++++++++++++++++++++-
 .../connection/BaseEtherNetIpPlcConnection.java    | 10 ++++++++++
 .../modbus/connection/BaseModbusPlcConnection.java | 10 ++++++++++
 .../plc4x/java/s7/connection/S7PlcConnection.java  | 10 ++++++++++
 .../org/apache/plc4x/java/test/TestConnection.java | 23 +++++++++++++++++++++-
 .../connectionpool/PooledPlcDriverManagerTest.java | 23 +++++++++++++++++++++-
 9 files changed, 122 insertions(+), 3 deletions(-)

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 6ff75e5..f8b7bec 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
@@ -66,6 +66,16 @@ public class MockConnection extends org.apache.plc4x.java.base.connection.MockCo
     }
 
     @Override
+    public boolean canRead() {
+        return true;
+    }
+
+    @Override
+    public boolean canWrite() {
+        return true;
+    }
+
+    @Override
     public Optional<PlcReadRequest.Builder> readRequestBuilder() {
         return Optional.of(new DefaultPlcReadRequest.Builder(this, new MockFieldHandler()));
     }
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
index c1a78c5..59be9ce 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
@@ -23,6 +23,7 @@ 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.Optional;
 
@@ -57,6 +58,11 @@ public interface PlcConnection extends AutoCloseable {
     @Override
     void close() throws Exception;
 
+    /**
+     * Provides connection metadata.
+     */
+    PlcConnectionMetadata getMetadata();
+
     Optional<PlcReadRequest.Builder> readRequestBuilder();
 
     Optional<PlcWriteRequest.Builder> writeRequestBuilder();
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 5ac73ef..9853704 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
@@ -93,6 +93,16 @@ public abstract class AdsAbstractPlcConnection extends AbstractPlcConnection imp
     }
 
     @Override
+    public boolean canRead() {
+        return true;
+    }
+
+    @Override
+    public boolean canWrite() {
+        return true;
+    }
+
+    @Override
     public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
         mapFields(readRequest);
         CompletableFuture<InternalPlcReadResponse> readFuture = new CompletableFuture<>();
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
index 42989d6..61d3acf 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/AbstractPlcConnection.java
@@ -25,12 +25,13 @@ 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.metadata.PlcConnectionMetadata;
 
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
-public abstract class AbstractPlcConnection implements PlcConnection {
+public abstract class AbstractPlcConnection implements PlcConnection, PlcConnectionMetadata {
 
     /**
      * a {@link HashedWheelTimer} shall be only instantiated once.
@@ -101,6 +102,26 @@ public abstract class AbstractPlcConnection implements 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;
+    }
+
     public Channel getChannel() {
         return channel;
     }
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 80dd054..f370d64 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
@@ -60,6 +60,16 @@ public abstract class BaseEtherNetIpPlcConnection extends AbstractPlcConnection
     }
 
     @Override
+    public boolean canRead() {
+        return true;
+    }
+
+    @Override
+    public boolean canWrite() {
+        return true;
+    }
+
+    @Override
     public Optional<PlcReadRequest.Builder> readRequestBuilder() {
         return Optional.of(new DefaultPlcReadRequest.Builder(this, new EnipPlcFieldHandler()));
     }
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 2f983e7..5dd9cc7 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
@@ -57,6 +57,16 @@ public abstract class BaseModbusPlcConnection extends AbstractPlcConnection impl
     }
 
     @Override
+    public boolean canRead() {
+        return true;
+    }
+
+    @Override
+    public boolean canWrite() {
+        return true;
+    }
+
+    @Override
     public Optional<PlcReadRequest.Builder> readRequestBuilder() {
         return Optional.of(new DefaultPlcReadRequest.Builder(this, new ModbusPlcFieldHandler()));
     }
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 037beea..1c9c2d4 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
@@ -140,6 +140,16 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
     }
 
     @Override
+    public boolean canRead() {
+        return true;
+    }
+
+    @Override
+    public boolean canWrite() {
+        return true;
+    }
+
+    @Override
     protected ChannelHandler getChannelHandler(CompletableFuture<Void> sessionSetupCompleteFuture) {
         short calledTsapId = S7TsapIdEncoder.encodeS7TsapId(DeviceGroup.PG_OR_PC, 0, 0);
         short callingTsapId = S7TsapIdEncoder.encodeS7TsapId(DeviceGroup.OTHERS, rack, slot);
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 5d06baf..cad86a3 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
@@ -22,6 +22,7 @@ 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.messages.*;
+import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.base.messages.*;
 import org.apache.plc4x.java.base.messages.items.BaseDefaultFieldItem;
@@ -35,7 +36,7 @@ import java.util.concurrent.CompletableFuture;
  * Connection to a test device.
  * This class is not thread-safe.
  */
-class TestConnection implements PlcConnection, PlcReader, PlcWriter {
+class TestConnection implements PlcConnection, PlcConnectionMetadata, PlcReader, PlcWriter {
     private final TestDevice device;
     private boolean connected = false;
 
@@ -59,6 +60,26 @@ class TestConnection implements PlcConnection, PlcReader, PlcWriter {
     }
 
     @Override
+    public PlcConnectionMetadata getMetadata() {
+        return this;
+    }
+
+    @Override
+    public boolean canRead() {
+        return true;
+    }
+
+    @Override
+    public boolean canWrite() {
+        return true;
+    }
+
+    @Override
+    public boolean canSubscribe() {
+        return false;
+    }
+
+    @Override
     public Optional<PlcReadRequest.Builder> readRequestBuilder() {
         return Optional.of(new DefaultPlcReadRequest.Builder(this, new TestFieldHandler()));
     }
diff --git a/plc4j/utils/connection-pool/src/test/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManagerTest.java b/plc4j/utils/connection-pool/src/test/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManagerTest.java
index 86153df..cbbb908 100644
--- a/plc4j/utils/connection-pool/src/test/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManagerTest.java
+++ b/plc4j/utils/connection-pool/src/test/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManagerTest.java
@@ -28,6 +28,7 @@ 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 org.apache.plc4x.java.spi.PlcDriver;
 import org.assertj.core.api.WithAssertions;
 import org.junit.jupiter.api.AfterEach;
@@ -198,7 +199,7 @@ class PooledPlcDriverManagerTest implements WithAssertions {
         );
     }
 
-    class DummyPlcConnection implements PlcConnection {
+    class DummyPlcConnection implements PlcConnection, PlcConnectionMetadata {
 
         private final String url;
 
@@ -226,6 +227,26 @@ class PooledPlcDriverManagerTest implements WithAssertions {
         }
 
         @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 void close() throws Exception {
             throw new UnsupportedOperationException("this should never be called due to pool");
         }


[incubator-plc4x] 03/04: added UnsopportedOperationException

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

skorikov pushed a commit to branch feature/connection-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 19552c62320865eaddead8e18d61be155b3b8981
Author: Andrey Skorikov <an...@codecentric.de>
AuthorDate: Fri Oct 26 12:02:13 2018 +0200

    added UnsopportedOperationException
---
 .../java/api/exceptions/PlcUnsupportedOperationException.java    | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcUnsupportedOperationException.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcUnsupportedOperationException.java
new file mode 100644
index 0000000..1039d0e
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcUnsupportedOperationException.java
@@ -0,0 +1,9 @@
+package org.apache.plc4x.java.api.exceptions;
+
+public class PlcUnsupportedOperationException extends PlcRuntimeException {
+
+    public PlcUnsupportedOperationException(String message) {
+        super(message);
+    }
+
+}


[incubator-plc4x] 01/04: added metadata interface

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

skorikov pushed a commit to branch feature/connection-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 6565175ac08c812b667f92540299ea82cdbaaaed
Author: Andrey Skorikov <an...@codecentric.de>
AuthorDate: Fri Oct 26 11:52:37 2018 +0200

    added metadata interface
---
 .../java/api/metadata/PlcConnectionMetadata.java   | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/metadata/PlcConnectionMetadata.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/metadata/PlcConnectionMetadata.java
new file mode 100644
index 0000000..c434fc7
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/metadata/PlcConnectionMetadata.java
@@ -0,0 +1,24 @@
+package org.apache.plc4x.java.api.metadata;
+
+/**
+ * Information about connection capabilities.
+ * This includes connection and driver specific metadata.
+ */
+public interface PlcConnectionMetadata {
+
+    /**
+     * Indicates that the connection supports reading.
+     */
+    boolean canRead();
+
+    /**
+     * Indicates that the connection supports writing.
+     */
+    boolean canWrite();
+
+    /**
+     * Indicates that the connection supports subscription.
+     */
+    boolean canSubscribe();
+
+}


[incubator-plc4x] 04/04: removed optionals

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

skorikov pushed a commit to branch feature/connection-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 479f3a75e54704013d903f0a04f3f83420ec0900
Author: Andrey Skorikov <an...@codecentric.de>
AuthorDate: Fri Oct 26 13:30:07 2018 +0200

    removed optionals
---
 .../azure/iothub/S7PlcToAzureIoTHubSample.java     |  2 +-
 .../dummydriver/connection/DummyConnection.java    | 30 +++-------------
 .../google/iotcore/S7PlcToGoogleIoTCoreSample.java |  2 +-
 .../plc4x/java/examples/helloplc4x/HelloPlc4x.java |  6 ++--
 .../java/org/apache/plc4x/camel/Plc4XConsumer.java |  4 +--
 .../apache/plc4x/camel/Plc4XPollingConsumer.java   |  2 +-
 .../java/org/apache/plc4x/camel/Plc4XProducer.java |  4 +--
 .../java/org/apache/plc4x/camel/MockDriver.java    | 17 ++++-----
 .../org/apache/plc4x/camel/Plc4XProducerTest.java  |  5 +--
 .../apache/plc4x/edgent/PlcConnectionAdapter.java  |  9 +++--
 .../apache/plc4x/edgent/mock/MockConnection.java   |  9 +++--
 .../java/org/apache/plc4x/kafka/Plc4xSinkTask.java |  4 +--
 .../org/apache/plc4x/kafka/Plc4xSourceTask.java    |  4 +--
 .../org/apache/plc4x/nifi/Plc4xSinkProcessor.java  |  4 +--
 .../apache/plc4x/nifi/Plc4xSourceProcessor.java    |  4 +--
 .../org/apache/plc4x/java/api/PlcConnection.java   | 42 +++++++++++++---------
 .../org/apache/plc4x/java/mock/MockConnection.java | 29 +--------------
 .../ads/connection/AdsAbstractPlcConnection.java   | 22 +++---------
 .../java/ads/connection/AdsTcpPlcConnection.java   | 13 ++++---
 .../apache/plc4x/java/ads/ManualPlc4XAdsTest.java  |  6 ++--
 .../ads/connection/AdsSerialPlcConnectionTest.java |  2 +-
 .../base/connection/AbstractPlcConnection.java     | 25 +++++++++++++
 .../plc4x/java/base/connection/MockConnection.java | 25 -------------
 .../connection/BaseEtherNetIpPlcConnection.java    | 11 +++---
 .../connection/EtherNetIpTcpPlcConnection.java     | 13 -------
 .../java/ethernetip/ManualPlc4XEtherNetIpTest.java |  2 +-
 .../modbus/connection/BaseModbusPlcConnection.java | 26 +++++---------
 .../plc4x/java/modbus/ManualPlc4XModbusTest.java   | 10 +++---
 .../connection/ModbusSerialPlcConnectionTest.java  |  2 +-
 .../plc4x/java/s7/connection/S7PlcConnection.java  | 26 +++++---------
 .../apache/plc4x/java/s7/issues/PLC4X47Test.java   |  2 +-
 .../org/apache/plc4x/java/test/TestConnection.java | 17 ++++-----
 .../connectionpool/PooledPlcDriverManagerTest.java | 18 +++++-----
 .../apache/plc4x/java/opm/PlcEntityManager.java    |  8 ++---
 34 files changed, 160 insertions(+), 245 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 1d6d3fa..99f8156 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
@@ -61,7 +61,7 @@ public class S7PlcToAzureIoTHubSample {
             client.open();
 
             // Prepare a read request.
-            PlcReadRequest request = plcConnection.readRequestBuilder().get().addItem(FIELD_NAME, addressString).build();
+            PlcReadRequest request = plcConnection.readRequestBuilder().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 c5721ca..ed84e90 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
@@ -21,9 +21,10 @@ package org.apache.plc4x.java.examples.dummydriver.connection;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelInitializer;
-import org.apache.plc4x.java.base.messages.PlcReader;
-import org.apache.plc4x.java.base.messages.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.TcpSocketChannelFactory;
 import org.apache.plc4x.java.base.messages.*;
@@ -31,7 +32,6 @@ 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 {
@@ -56,28 +56,6 @@ public class DummyConnection extends AbstractPlcConnection implements PlcReader,
     }
 
     @Override
-    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
-        // TODO: Implement this ...
-        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
     public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
         CompletableFuture<InternalPlcReadResponse> readFuture = new CompletableFuture<>();
         PlcRequestContainer<InternalPlcReadRequest, InternalPlcReadResponse> 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 ba93c46..c56df29 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
@@ -238,7 +238,7 @@ public class S7PlcToGoogleIoTCoreSample {
         try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://10.10.64.20/1/1")) {
             logger.info("Connected");
 
-            PlcReadRequest readRequest = plcConnection.readRequestBuilder().get().addItem("outputs", "OUTPUTS/0").build();
+            PlcReadRequest readRequest = plcConnection.readRequestBuilder().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 f321248..20253e4 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
@@ -24,7 +24,6 @@ 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.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class HelloPlc4x {
@@ -45,15 +44,14 @@ public static void main(String[] args) throws Exception {
     try (PlcConnection plcConnection = new PlcDriverManager().getConnection(args[0])) {
 
         // Check if this connection support reading of data.
-        Optional<PlcReadRequest.Builder> builderOptional = plcConnection.readRequestBuilder();
-        if (!builderOptional.isPresent()) {
+        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 = builderOptional.get();
+        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
         for (int i = 1; i < args.length; i++) {
             builder.addItem("value-" + i, args[i]);
         }
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 23dd0eb..5b15464 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
@@ -79,7 +79,7 @@ public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util
     @Override
     protected void doStart() throws InterruptedException, ExecutionException, PlcException {
         // TODO: Is it correct to only support one field?
-        PlcSubscriptionRequest request = plcConnection.subscriptionRequestBuilder().get()
+        PlcSubscriptionRequest request = plcConnection.subscriptionRequestBuilder()
             .addCyclicField("default", fieldQuery, Duration.of(3, ChronoUnit.SECONDS)).build();
         subscriptionResponse = request.execute().get();
         // TODO: we need to return the plcSubscriptionResponse here too as we need this to unsubscribe...
@@ -89,7 +89,7 @@ public class Plc4XConsumer extends ServiceSupport implements Consumer, java.util
 
     @Override
     protected void doStop() throws InterruptedException, ExecutionException, TimeoutException, PlcException {
-        PlcUnsubscriptionRequest request = plcConnection.unsubscriptionRequestBuilder().get().addHandles(subscriptionResponse.getSubscriptionHandles()).build();
+        PlcUnsubscriptionRequest request = plcConnection.unsubscriptionRequestBuilder().addHandles(subscriptionResponse.getSubscriptionHandles()).build();
         CompletableFuture<? extends PlcUnsubscriptionResponse> unsubscriptionFuture = request.execute();
         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 ef2af6e..5467711 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
@@ -52,7 +52,7 @@ public class Plc4XPollingConsumer extends ServiceSupport implements PollingConsu
         this.exceptionHandler = new LoggingExceptionHandler(endpoint.getCamelContext(), getClass());
         String plc4xURI = endpoint.getEndpointUri().replaceFirst("plc4x:/?/?", "");
         this.plcConnection = endpoint.getPlcDriverManager().getConnection(plc4xURI);
-        this.requestBuilder = plcConnection.readRequestBuilder().orElseThrow(() -> new PlcException("This connection doesn't support reading."));
+        this.requestBuilder = plcConnection.readRequestBuilder();
     }
 
     @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 b737a63..d9f7077 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
@@ -39,7 +39,7 @@ public class Plc4XProducer extends DefaultAsyncProducer {
         super(endpoint);
         String plc4xURI = endpoint.getEndpointUri().replaceFirst("plc4x:/?/?", "");
         plcConnection = endpoint.getPlcDriverManager().getConnection(plc4xURI);
-        if (!plcConnection.writeRequestBuilder().isPresent()) {
+        if (!plcConnection.getMetadata().canWrite()) {
             throw new PlcException("This connection (" + plc4xURI + ") doesn't support writing.");
         }
         openRequests = new AtomicInteger();
@@ -59,7 +59,7 @@ public class Plc4XProducer extends DefaultAsyncProducer {
             Object value = in.getBody(Object.class);
 //            builder.addItem(fieldName, fieldQuery, value);
         }
-        PlcWriteRequest.Builder builder = plcConnection.writeRequestBuilder().orElseThrow(() -> new IllegalArgumentException("Writer for driver not found"));
+        PlcWriteRequest.Builder builder = plcConnection.writeRequestBuilder();
         CompletableFuture<? extends PlcWriteResponse> completableFuture = builder.build().execute();
         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 a34f93d..cb4e00b 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
@@ -18,18 +18,17 @@ under the License.
 */
 package org.apache.plc4x.camel;
 
-import org.apache.plc4x.java.spi.PlcDriver;
-import org.apache.plc4x.java.api.authentication.PlcAuthentication;
 import org.apache.plc4x.java.api.PlcConnection;
-import org.apache.plc4x.java.base.messages.PlcSubscriber;
+import org.apache.plc4x.java.api.authentication.PlcAuthentication;
 import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.base.messages.DefaultPlcSubscriptionResponse;
 import org.apache.plc4x.java.base.messages.InternalPlcSubscriptionRequest;
+import org.apache.plc4x.java.base.messages.PlcSubscriber;
+import org.apache.plc4x.java.spi.PlcDriver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.HashMap;
-import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -56,10 +55,12 @@ public class MockDriver implements PlcDriver {
     public PlcConnection connect(String url) {
         // Mock a connection.
         PlcConnection plcConnectionMock = mock(PlcConnection.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)));
-        when(plcConnectionMock.unsubscriptionRequestBuilder()).thenReturn(Optional.of(mock(PlcUnsubscriptionRequest.Builder.class, RETURNS_DEEP_STUBS)));
+        when(plcConnectionMock.getMetadata().canRead()).thenReturn(true);
+        when(plcConnectionMock.getMetadata().canWrite()).thenReturn(true);
+        when(plcConnectionMock.readRequestBuilder()).thenReturn(mock(PlcReadRequest.Builder.class, RETURNS_DEEP_STUBS));
+        when(plcConnectionMock.writeRequestBuilder()).thenReturn(mock(PlcWriteRequest.Builder.class, RETURNS_DEEP_STUBS));
+        when(plcConnectionMock.subscriptionRequestBuilder()).thenReturn(mock(PlcSubscriptionRequest.Builder.class, RETURNS_DEEP_STUBS));
+        when(plcConnectionMock.unsubscriptionRequestBuilder()).thenReturn(mock(PlcUnsubscriptionRequest.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/Plc4XProducerTest.java b/integrations/apache-camel/src/test/java/org/apache/plc4x/camel/Plc4XProducerTest.java
index f51a43d..22190a7 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
@@ -29,7 +29,6 @@ import org.junit.Test;
 import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Optional;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.mockito.Mockito.*;
@@ -46,8 +45,10 @@ public class Plc4XProducerTest {
         when(endpointMock.getEndpointUri()).thenReturn("plc4x:mock:10.10.10.1/1/1");
         PlcDriverManager plcDriverManagerMock = mock(PlcDriverManager.class, RETURNS_DEEP_STUBS);
 
+        when(plcDriverManagerMock.getConnection(anyString()).getMetadata().canRead()).thenReturn(true);
+        when(plcDriverManagerMock.getConnection(anyString()).getMetadata().canWrite()).thenReturn(true);
         when(plcDriverManagerMock.getConnection(anyString()).writeRequestBuilder())
-            .thenReturn(Optional.of(mock(PlcWriteRequest.Builder.class, RETURNS_DEEP_STUBS)));
+            .thenReturn(mock(PlcWriteRequest.Builder.class, RETURNS_DEEP_STUBS));
 
         when(endpointMock.getPlcDriverManager()).thenReturn(plcDriverManagerMock);
         SUT = new Plc4XProducer(endpointMock);
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 0f148d7..01ceb8d 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,7 @@ public class PlcConnectionAdapter implements AutoCloseable {
     }
 
     public PlcReadRequest.Builder readRequestBuilder() throws PlcException {
-        return getConnection().readRequestBuilder().orElseThrow(
-            () -> new PlcException("This connection doesn't support reading"));
+        return getConnection().readRequestBuilder();
     }
 
     Supplier<PlcReadResponse> newSupplier(PlcReadRequest readRequest) {
@@ -157,7 +156,7 @@ public class PlcConnectionAdapter implements AutoCloseable {
             PlcField field = null;
             try {
                 connection = getConnection();
-                PlcReadRequest readRequest = connection.readRequestBuilder().orElseThrow(() -> new PlcException("This connection doesn't support reading")).addItem(FIELD_NAME, fieldQuery).build();
+                PlcReadRequest readRequest = connection.readRequestBuilder().addItem(FIELD_NAME, fieldQuery).build();
                 PlcReadResponse readResponse = readRequest.execute().get();
                 Object value = null;
                 switch (clientDatatype) {
@@ -230,7 +229,7 @@ public class PlcConnectionAdapter implements AutoCloseable {
             PlcField field = null;
             try {
                 connection = getConnection();
-                PlcReadRequest readRequest = connection.readRequestBuilder().orElseThrow(() -> new PlcException("This connection doesn't support reading")).addItem(FIELD_NAME, fieldQuery).build();
+                PlcReadRequest readRequest = connection.readRequestBuilder().addItem(FIELD_NAME, fieldQuery).build();
                 PlcReadResponse readResponse = readRequest.execute().get();
                 Object value = null;
                 switch (clientDatatype) {
@@ -292,7 +291,7 @@ public class PlcConnectionAdapter implements AutoCloseable {
             PlcConnection connection = null;
             try {
                 connection = getConnection();
-                PlcWriteRequest.Builder builder = connection.writeRequestBuilder().orElseThrow(() -> new PlcException("This connection doesn't support writing"));
+                PlcWriteRequest.Builder builder = connection.writeRequestBuilder();
                 PlcWriteRequest writeRequest = builder.build();
                 addItem(builder, clientDatatype, fieldQuery, fieldValue);
                 writeRequest.execute().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 f8b7bec..d30a9bf 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
@@ -34,7 +34,6 @@ import org.apache.plc4x.java.base.messages.items.BaseDefaultFieldItem;
 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 {
@@ -76,8 +75,8 @@ public class MockConnection extends org.apache.plc4x.java.base.connection.MockCo
     }
 
     @Override
-    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
-        return Optional.of(new DefaultPlcReadRequest.Builder(this, new MockFieldHandler()));
+    public PlcReadRequest.Builder readRequestBuilder() {
+        return new DefaultPlcReadRequest.Builder(this, new MockFieldHandler());
     }
 
     @Override
@@ -99,8 +98,8 @@ public class MockConnection extends org.apache.plc4x.java.base.connection.MockCo
     }
 
     @Override
-    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
-        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new MockFieldHandler()));
+    public PlcWriteRequest.Builder writeRequestBuilder() {
+        return 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 4a13ee3..424e857 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
@@ -50,7 +50,7 @@ public class Plc4xSinkTask extends SinkTask {
 
         openConnection();
 
-        if (!plcConnection.writeRequestBuilder().isPresent()) {
+        if (!plcConnection.getMetadata().canWrite()) {
             throw new ConnectException("Writing not supported on this connection");
         }
     }
@@ -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 = plcConnection.writeRequestBuilder().get();
+            PlcWriteRequest.Builder builder = plcConnection.writeRequestBuilder();
             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 7a79f37..2b9d9f2 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
@@ -100,7 +100,7 @@ public class Plc4xSourceTask extends SourceTask {
 
         openConnection();
 
-        if (!plcConnection.readRequestBuilder().isPresent()) {
+        if (!plcConnection.getMetadata().canRead()) {
             throw new ConnectException("Reading not supported on this connection");
         }
 
@@ -180,7 +180,7 @@ public class Plc4xSourceTask extends SourceTask {
     }
 
     private PlcReadRequest createReadRequest() {
-        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder().get();
+        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
         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 d743e57..fbb64e2 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
@@ -52,12 +52,12 @@ public class Plc4xSinkProcessor extends BasePlc4xProcessor {
 
         // Get an instance of a component able to write to a PLC.
         PlcConnection connection = getConnection();
-        if (!connection.writeRequestBuilder().isPresent()) {
+        if (!connection.getMetadata().canWrite()) {
             throw new ProcessException("Writing not supported by connection");
         }
 
         // Prepare the request.
-        PlcWriteRequest.Builder builder = connection.writeRequestBuilder().get();
+        PlcWriteRequest.Builder builder = connection.writeRequestBuilder();
         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 09fabff..049eb1b 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
@@ -48,14 +48,14 @@ public class Plc4xSourceProcessor extends BasePlc4xProcessor {
         PlcConnection connection = getConnection();
 
         // Prepare the request.
-        if (!connection.readRequestBuilder().isPresent()) {
+        if (!connection.getMetadata().canRead()) {
             throw new ProcessException("Writing not supported by connection");
         }
 
         FlowFile flowFile = session.create();
         session.append(flowFile, out -> {
             try {
-                PlcReadRequest.Builder builder = connection.readRequestBuilder().get();
+                PlcReadRequest.Builder builder = connection.readRequestBuilder();
                 getFields().forEach(field -> {
                     String address = getAddress(field);
                     if(address != null) {
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
index 59be9ce..a4732e1 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
@@ -19,41 +19,35 @@ under the License.
 package org.apache.plc4x.java.api;
 
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+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.Optional;
-
 /**
  * Interface defining the most basic methods a PLC4X connection should support.
  * This generally handles the connection establishment itself and the parsing of
  * field address strings to the platform dependent PlcField instances.
- * <p>
- * The individual operations are then defined by other interfaces within this package.
  */
 public interface PlcConnection extends AutoCloseable {
 
     /**
-     * Established the connection to the remote PLC.
-     *
-     * @throws PlcConnectionException an exception if the connection attempt failed.
+     * Establishes the connection to the remote PLC.
+     * @throws PlcConnectionException if the connection attempt failed
      */
     void connect() throws PlcConnectionException;
 
     /**
-     * Returns true if the PlcConnection is connected to a remote PLC.
-     *
-     * @return true, if connected, false, if not.
+     * Indicates if the connection is established to a remote PLC.
+     * @return {@code true} if connected, {@code false} otherwise
      */
     boolean isConnected();
 
     /**
      * Closes the connection to the remote PLC.
-     *
-     * @throws Exception an exception if shutting down the connection failed.
+     * @throws Exception if shutting down the connection failed
      */
     @Override
     void close() throws Exception;
@@ -63,12 +57,28 @@ public interface PlcConnection extends AutoCloseable {
      */
     PlcConnectionMetadata getMetadata();
 
-    Optional<PlcReadRequest.Builder> readRequestBuilder();
+    /**
+     * Obtain read request builder.
+     * @throws PlcUnsupportedOperationException if the connection does not support reading
+     */
+    PlcReadRequest.Builder readRequestBuilder();
 
-    Optional<PlcWriteRequest.Builder> writeRequestBuilder();
+    /**
+     * Obtain write request builder.
+     * @throws PlcUnsupportedOperationException if the connection does not support writing
+     */
+    PlcWriteRequest.Builder writeRequestBuilder();
 
-    Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder();
+    /**
+     * Obtain subscription request builder.
+     * @throws PlcUnsupportedOperationException if the connection does not support subscription
+     */
+    PlcSubscriptionRequest.Builder subscriptionRequestBuilder();
 
-    Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder();
+    /**
+     * Obtain unsubscription request builder.
+     * @throws PlcUnsupportedOperationException if the connection does not support subscription
+     */
+    PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder();
 
 }
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 fc52100..d44fc5d 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,48 +22,21 @@ 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 {
 
     private final PlcAuthentication authentication;
 
-    public MockConnection(PlcAuthentication authentication) {
+    MockConnection(PlcAuthentication authentication) {
         super(new TestChannelFactory());
         this.authentication = authentication;
     }
 
     @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 9853704..22023cf 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
@@ -31,9 +31,6 @@ import org.apache.plc4x.java.ads.api.generic.types.Invoke;
 import org.apache.plc4x.java.ads.model.AdsPlcFieldHandler;
 import org.apache.plc4x.java.ads.model.DirectAdsField;
 import org.apache.plc4x.java.ads.model.SymbolicAdsField;
-import org.apache.plc4x.java.base.messages.PlcProprietarySender;
-import org.apache.plc4x.java.base.messages.PlcReader;
-import org.apache.plc4x.java.base.messages.PlcWriter;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.*;
@@ -43,7 +40,6 @@ 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 {
@@ -117,23 +113,13 @@ public abstract class AdsAbstractPlcConnection extends AbstractPlcConnection imp
     }
 
     @Override
-    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
-        return Optional.of(new DefaultPlcReadRequest.Builder(this, new AdsPlcFieldHandler()));
+    public PlcReadRequest.Builder readRequestBuilder() {
+        return 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();
+    public PlcWriteRequest.Builder writeRequestBuilder() {
+        return new DefaultPlcWriteRequest.Builder(this, new AdsPlcFieldHandler());
     }
 
     @Override
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 3b20fd1..06aa579 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
@@ -310,13 +310,18 @@ public class AdsTcpPlcConnection extends AdsAbstractPlcConnection implements Plc
     }
 
     @Override
-    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
-        return Optional.of(new DefaultPlcSubscriptionRequest.Builder(this, new AdsPlcFieldHandler()));
+    public boolean canSubscribe() {
+        return true;
     }
 
     @Override
-    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
-        return Optional.of(new DefaultPlcUnsubscriptionRequest.Builder(this));
+    public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() {
+        return new DefaultPlcSubscriptionRequest.Builder(this, new AdsPlcFieldHandler());
+    }
+
+    @Override
+    public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() {
+        return 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 f65d189..70a433f 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
@@ -49,7 +49,7 @@ public class ManualPlc4XAdsTest {
         try (PlcConnection plcConnection = new PlcDriverManager().getConnection(connectionUrl)) {
             System.out.println("PlcConnection " + plcConnection);
 
-            PlcReadRequest.Builder readRequestBuilder = plcConnection.readRequestBuilder().orElseThrow(RuntimeException::new);
+            PlcReadRequest.Builder readRequestBuilder = plcConnection.readRequestBuilder();
             PlcReadRequest readRequest = readRequestBuilder.addItem("station", "Allgemein_S2.Station:BYTE").build();
             CompletableFuture<? extends PlcReadResponse> response = readRequest.execute();
             PlcReadResponse readResponse = response.get();
@@ -58,7 +58,7 @@ public class ManualPlc4XAdsTest {
             stations.forEach(System.out::println);
 
             // 2. We build a subscription
-            PlcSubscriptionRequest.Builder subscriptionRequestBuilder = plcConnection.subscriptionRequestBuilder().orElseThrow(RuntimeException::new);
+            PlcSubscriptionRequest.Builder subscriptionRequestBuilder = plcConnection.subscriptionRequestBuilder();
             PlcSubscriptionRequest subscriptionRequest = subscriptionRequestBuilder.addChangeOfStateField("stationChange", "Allgemein_S2.Station:BYTE").build();
             PlcSubscriptionResponse plcSubscriptionResponse = subscriptionRequest.execute().get();
 
@@ -73,7 +73,7 @@ public class ManualPlc4XAdsTest {
             plcConsumerRegistrations.forEach(PlcConsumerRegistration::unregister);
 
             // we unsubscribe at the plc
-            PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder = plcConnection.unsubscriptionRequestBuilder().orElseThrow(RuntimeException::new);
+            PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder = plcConnection.unsubscriptionRequestBuilder();
             PlcUnsubscriptionRequest unsubscriptionRequest = unsubscriptionRequestBuilder.addHandles(plcSubscriptionResponse.getSubscriptionHandles()).build();
             CompletableFuture<PlcUnsubscriptionResponse> unsubscriptionResponse = unsubscriptionRequest.execute();
 
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 624e607..9b0a7f4 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().get().addItem("test", "0/0:BYTE").build();
+        PlcReadRequest request = SUT.readRequestBuilder().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/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
index 61d3acf..ea8ddcd 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/AbstractPlcConnection.java
@@ -25,6 +25,11 @@ 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;
@@ -122,6 +127,26 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect
         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/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 21d19d2..bbd489f 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,12 +19,7 @@ under the License.
 package org.apache.plc4x.java.base.connection;
 
 import io.netty.channel.ChannelHandler;
-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 {
@@ -38,26 +33,6 @@ 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 f370d64..56a6ddc 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
@@ -19,8 +19,6 @@ under the License.
 package org.apache.plc4x.java.ethernetip.connection;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.plc4x.java.base.messages.PlcReader;
-import org.apache.plc4x.java.base.messages.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;
@@ -32,7 +30,6 @@ 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 {
@@ -70,13 +67,13 @@ public abstract class BaseEtherNetIpPlcConnection extends AbstractPlcConnection
     }
 
     @Override
-    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
-        return Optional.of(new DefaultPlcReadRequest.Builder(this, new EnipPlcFieldHandler()));
+    public PlcReadRequest.Builder readRequestBuilder() {
+        return new DefaultPlcReadRequest.Builder(this, new EnipPlcFieldHandler());
     }
 
     @Override
-    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
-        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new EnipPlcFieldHandler()));
+    public PlcWriteRequest.Builder writeRequestBuilder() {
+        return new DefaultPlcWriteRequest.Builder(this, new EnipPlcFieldHandler());
     }
 
     @Override
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 3f0ed79..e14ac19 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,8 +19,6 @@ 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;
@@ -31,7 +29,6 @@ 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 {
@@ -56,16 +53,6 @@ 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 27d7f39..8fa2fbd 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
@@ -33,7 +33,7 @@ public class ManualPlc4XEtherNetIpTest {
         try (PlcConnection plcConnection = new PlcDriverManager().getConnection(connectionUrl)) {
             System.out.println("PlcConnection " + plcConnection);
 
-            PlcReadRequest readRequest = plcConnection.readRequestBuilder().orElseThrow(() -> new RuntimeException("Reading not supported"))
+            PlcReadRequest readRequest = plcConnection.readRequestBuilder()
                 .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 5dd9cc7..3d4ab33 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
@@ -19,9 +19,10 @@ under the License.
 package org.apache.plc4x.java.modbus.connection;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.plc4x.java.base.messages.PlcReader;
-import org.apache.plc4x.java.base.messages.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,7 +30,6 @@ 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 {
@@ -67,23 +67,13 @@ public abstract class BaseModbusPlcConnection extends AbstractPlcConnection impl
     }
 
     @Override
-    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
-        return Optional.of(new DefaultPlcReadRequest.Builder(this, new ModbusPlcFieldHandler()));
+    public PlcReadRequest.Builder readRequestBuilder() {
+        return 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();
+    public PlcWriteRequest.Builder writeRequestBuilder() {
+        return new DefaultPlcWriteRequest.Builder(this, new ModbusPlcFieldHandler());
     }
 
     @Override
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 ded2ea3..85c5f2c 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
@@ -48,7 +48,7 @@ public class ManualPlc4XModbusTest {
             System.out.println("PlcConnection " + plcConnection);
 
             {
-                PlcReadRequest readRequest = plcConnection.readRequestBuilder().orElseThrow(() -> new RuntimeException("No Reader found"))
+                PlcReadRequest readRequest = plcConnection.readRequestBuilder()
                 .addItem("randomRegister", "register:7[3]").build();
                 PlcReadResponse readResponse = readRequest.execute().get();
                 System.out.println("Response " + readResponse);
@@ -62,7 +62,7 @@ public class ManualPlc4XModbusTest {
                 // Read an int from 2 registers
 
                 // Just dump the actual values
-                PlcReadRequest readRequest = plcConnection.readRequestBuilder().orElseThrow(() -> new RuntimeException("No Reader found"))
+                PlcReadRequest readRequest = plcConnection.readRequestBuilder()
                     .addItem("randomRegister", "register:3[2]").build();
                 PlcReadResponse readResponse = readRequest.execute().get();
                 System.out.println("Response " + readResponse);
@@ -86,7 +86,7 @@ public class ManualPlc4XModbusTest {
                 // Read an int from 2 registers and multiple requests
 
                 // Just dump the actual values
-                PlcReadRequest readRequest = plcConnection.readRequestBuilder().orElseThrow(() -> new RuntimeException("No Reader found"))
+                PlcReadRequest readRequest = plcConnection.readRequestBuilder()
                     .addItem("randomRegister1", "register:1[2]")
                     .addItem("randomRegister2", "register:10[3]")
                     .addItem("randomRegister3", "register:20[4]")
@@ -114,7 +114,7 @@ public class ManualPlc4XModbusTest {
             }
 
             {
-                PlcReadRequest readRequest = plcConnection.readRequestBuilder().orElseThrow(() -> new RuntimeException("No Reader found"))
+                PlcReadRequest readRequest = plcConnection.readRequestBuilder()
                     .addItem("randomCoil", "coil:1[9]").build();
                 PlcReadResponse readResponse = readRequest.execute().get();
                 System.out.println("Response " + readResponse);
@@ -124,7 +124,7 @@ public class ManualPlc4XModbusTest {
             }
 
             {
-                PlcWriteRequest writeRequest = plcConnection.writeRequestBuilder().orElseThrow(() -> new RuntimeException("No Writer found"))
+                PlcWriteRequest writeRequest = plcConnection.writeRequestBuilder()
                     .addItem("randomCoilField", "coil:1", true).build();
                 PlcWriteResponse writeResponse = writeRequest.execute().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 1179ee0..519d4b9 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().get().addItem("randomRead", "0/0").build();
+        PlcReadRequest readRequest = SUT.readRequestBuilder().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 1c9c2d4..ab23437 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
@@ -22,10 +22,11 @@ import io.netty.channel.*;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.SystemConfiguration;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.plc4x.java.base.messages.PlcReader;
-import org.apache.plc4x.java.base.messages.PlcWriter;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-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.connection.TcpSocketChannelFactory;
@@ -48,7 +49,6 @@ 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;
@@ -245,23 +245,13 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
     }
 
     @Override
-    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
-        return Optional.of(new DefaultPlcReadRequest.Builder(this, new S7PlcFieldHandler()));
+    public PlcReadRequest.Builder readRequestBuilder() {
+        return 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();
+    public PlcWriteRequest.Builder writeRequestBuilder() {
+        return new DefaultPlcWriteRequest.Builder(this, new S7PlcFieldHandler());
     }
 
     @Override
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 100a677..3683f83 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().get();
+        PlcReadRequest.Builder builder = connection.readRequestBuilder();
         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 cad86a3..4a0199d 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
@@ -21,6 +21,7 @@ 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.types.PlcResponseCode;
@@ -80,23 +81,23 @@ class TestConnection implements PlcConnection, PlcConnectionMetadata, PlcReader,
     }
 
     @Override
-    public Optional<PlcReadRequest.Builder> readRequestBuilder() {
-        return Optional.of(new DefaultPlcReadRequest.Builder(this, new TestFieldHandler()));
+    public PlcReadRequest.Builder readRequestBuilder() {
+        return new DefaultPlcReadRequest.Builder(this, new TestFieldHandler());
     }
 
     @Override
-    public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
-        return Optional.of(new DefaultPlcWriteRequest.Builder(this, new TestFieldHandler()));
+    public PlcWriteRequest.Builder writeRequestBuilder() {
+        return new DefaultPlcWriteRequest.Builder(this, new TestFieldHandler());
     }
 
     @Override
-    public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
-        return Optional.empty();
+    public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() {
+        throw new PlcUnsupportedOperationException("The connection does not support subscription");
     }
 
     @Override
-    public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
-        return Optional.empty();
+    public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() {
+        throw new PlcUnsupportedOperationException("The connection does not support subscription");
     }
 
     @Override
diff --git a/plc4j/utils/connection-pool/src/test/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManagerTest.java b/plc4j/utils/connection-pool/src/test/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManagerTest.java
index cbbb908..6b8b91a 100644
--- a/plc4j/utils/connection-pool/src/test/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManagerTest.java
+++ b/plc4j/utils/connection-pool/src/test/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManagerTest.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.authentication.PlcAuthentication;
 import org.apache.plc4x.java.api.authentication.PlcUsernamePasswordAuthentication;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+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;
@@ -44,7 +45,6 @@ import org.slf4j.LoggerFactory;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.concurrent.*;
 import java.util.stream.IntStream;
 
@@ -252,23 +252,23 @@ class PooledPlcDriverManagerTest implements WithAssertions {
         }
 
         @Override
-        public Optional<PlcReadRequest.Builder> readRequestBuilder() {
-            return Optional.empty();
+        public PlcReadRequest.Builder readRequestBuilder() {
+            throw new PlcUnsupportedOperationException("The connection does not support reading");
         }
 
         @Override
-        public Optional<PlcWriteRequest.Builder> writeRequestBuilder() {
-            return Optional.empty();
+        public PlcWriteRequest.Builder writeRequestBuilder() {
+            throw new PlcUnsupportedOperationException("The connection does not support writing");
         }
 
         @Override
-        public Optional<PlcSubscriptionRequest.Builder> subscriptionRequestBuilder() {
-            return Optional.empty();
+        public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() {
+            throw new PlcUnsupportedOperationException("The connection does not support subscription");
         }
 
         @Override
-        public Optional<PlcUnsubscriptionRequest.Builder> unsubscriptionRequestBuilder() {
-            return Optional.empty();
+        public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() {
+            throw new PlcUnsupportedOperationException("The connection does not support subscription");
         }
 
         @Override
diff --git a/plc4j/utils/opm/src/main/java/org/apache/plc4x/java/opm/PlcEntityManager.java b/plc4j/utils/opm/src/main/java/org/apache/plc4x/java/opm/PlcEntityManager.java
index 2606400..8c11042 100644
--- a/plc4j/utils/opm/src/main/java/org/apache/plc4x/java/opm/PlcEntityManager.java
+++ b/plc4j/utils/opm/src/main/java/org/apache/plc4x/java/opm/PlcEntityManager.java
@@ -93,11 +93,11 @@ public class PlcEntityManager {
 
         try (PlcConnection connection = driverManager.getConnection(source)) {
 
-            if (!connection.readRequestBuilder().isPresent()) {
+            if (!connection.getMetadata().canRead()) {
                 throw new OPMException("Unable to get Reader for connection with url '" + source + "'");
             }
 
-            PlcReadRequest.Builder requestBuilder = connection.readRequestBuilder().get();
+            PlcReadRequest.Builder requestBuilder = connection.readRequestBuilder();
 
             // Do the necessary queries for all fields
             // HashMap<ReadRequestItem<?>, Field> requestItems = new HashMap<>();
@@ -249,7 +249,7 @@ public class PlcEntityManager {
         try (PlcConnection connection = driverManager.getConnection(plcEntity.value())) {
             // Catch the exception, if no reader present (see below)
             // Build the query
-            PlcReadRequest.Builder builder = connection.readRequestBuilder().get();
+            PlcReadRequest.Builder builder = connection.readRequestBuilder();
             for (Field field : superclass.getDeclaredFields()) {
                 // Check if the field has an annotation
                 PlcField plcField = field.getDeclaredAnnotation(PlcField.class);
@@ -294,7 +294,7 @@ public class PlcEntityManager {
             // Catch the exception, if no reader present (see below)
 
             // Assume to do the query here...
-            PlcReadRequest request = connection.readRequestBuilder().orElseThrow(IllegalStateException::new)
+            PlcReadRequest request = connection.readRequestBuilder()
                 .addItem(m.getName(), annotation.value())
                 .build();