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:46 UTC

[incubator-plc4x] 04/04: removed optionals

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();