You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2019/12/25 15:06:27 UTC

[plc4x] branch next-gen-core updated: Refactoring towards Generic Connections Part 5: - Extended ConnectionParser to support most of the generic types (boolean, String, int, double). - Introduced InstanceFactory to instantiate Classes (and Auto Inject Configuration Classes from Query Parameters, if existing) - Migrated Everything to InstanceFactory, e.g. many Classes now take a Class Object and no Instance - Migrated all existing Stuff to keep compatibility

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

jfeinauer pushed a commit to branch next-gen-core
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/next-gen-core by this push:
     new 3a132d1  Refactoring towards Generic Connections Part 5: - Extended ConnectionParser to support most of the generic types (boolean, String, int, double). - Introduced InstanceFactory to instantiate Classes (and Auto Inject Configuration Classes from Query Parameters, if existing) - Migrated Everything to InstanceFactory, e.g. many Classes now take a Class Object and no Instance - Migrated all existing Stuff to keep compatibility
3a132d1 is described below

commit 3a132d18dfb2d13aea4e224fab914a243b86ef2a
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Wed Dec 25 16:06:19 2019 +0100

    Refactoring towards Generic Connections Part 5:
    - Extended ConnectionParser to support most of the generic types (boolean, String, int, double).
    - Introduced InstanceFactory to instantiate Classes (and Auto Inject Configuration Classes from Query Parameters, if existing)
    - Migrated Everything to InstanceFactory, e.g. many Classes now take a Class Object and no Instance
    - Migrated all existing Stuff to keep compatibility
---
 plc4j/spi/pom.xml                                  |  6 ++
 ...lStackConfigurer.java => HasConfiguration.java} | 20 ++++--
 .../org/apache/plc4x/java/spi/InstanceFactory.java | 78 ++++++++++++++++++++++
 .../spi/connection/DefaultNettyPlcConnection.java  | 10 ++-
 .../java/spi/connection/GeneratedDriverBase.java   | 24 +++----
 .../spi/connection/ProtocolStackConfigurer.java    | 12 +++-
 .../spi/connection/SingleProtocolStackBuilder.java | 14 ++--
 .../connection/SingleProtocolStackConfigurer.java  | 26 +++++---
 .../BooleanDefaultValue.java}                      | 17 +++--
 .../plc4x/java/spi/parser/ConnectionParser.java    | 58 ++++++++++++----
 .../DoubleDefaultValue.java}                       | 17 +++--
 .../StringDefaultValue.java}                       | 17 +++--
 .../java/spi/parser/ConnectionParserTest.java      | 21 +++++-
 .../java/tcp/connection/TcpConfiguration.java      | 76 +++++++++++++++++++++
 .../tcp/connection/TcpSocketChannelFactory.java    | 25 ++++---
 .../apache/plc4x/java/knxnetip/KnxNetIpDriver.java | 12 ++--
 .../apache/plc4x/java/s7/readwrite/S7Driver.java   | 15 ++---
 .../s7/readwrite/connection/S7Configuration.java   | 69 +++++++++++++++++--
 .../s7/readwrite/protocol/S7ProtocolLogic.java     |  8 +--
 19 files changed, 408 insertions(+), 117 deletions(-)

diff --git a/plc4j/spi/pom.xml b/plc4j/spi/pom.xml
index f27bd21..aa9c7c7 100644
--- a/plc4j/spi/pom.xml
+++ b/plc4j/spi/pom.xml
@@ -52,6 +52,12 @@
     </dependency>
 
     <dependency>
+      <groupId>commons-beanutils</groupId>
+      <artifactId>commons-beanutils</artifactId>
+      <version>1.9.4</version>
+    </dependency>
+
+    <dependency>
       <groupId>io.vavr</groupId>
       <artifactId>vavr</artifactId>
       <version>0.10.2</version>
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/HasConfiguration.java
similarity index 60%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
copy to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/HasConfiguration.java
index 6e335f8..82fa877 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/HasConfiguration.java
@@ -17,14 +17,20 @@
  * under the License.
  */
 
-package org.apache.plc4x.java.spi.connection;
+package org.apache.plc4x.java.spi;
 
-import io.netty.channel.ChannelPipeline;
-import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.generation.Message;
+/**
+ * (Marker) Interface which can be used to tell PLC4X that a class (that is instantiated by PLC4X)
+ * has a Configuration.
+ * PLC4X will then try to Instantiate the Class and populate it based on Connection Parameters.
+ *
+ * @param <CONFIGURATION> Class of the Configuration
+ */
+public interface HasConfiguration<CONFIGURATION> {
 
-public interface ProtocolStackConfigurer<T extends Message> {
+    /**
+     * Is called directly after instantiation before the class is used somewhere.
+     */
+    void setConfiguration(CONFIGURATION configuration);
 
-    /** Applies the given Stack to the Pipeline and returns the wired instance */
-    Plc4xProtocolBase<T> apply(ChannelPipeline pipeline);
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/InstanceFactory.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/InstanceFactory.java
new file mode 100644
index 0000000..0390f23
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/InstanceFactory.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.plc4x.java.spi;
+
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.plc4x.java.spi.parser.ConnectionParser;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Optional;
+
+/**
+ * Generall Class which is used to create instances of Classes.
+ */
+public class InstanceFactory {
+
+    private final ConnectionParser parser;
+
+    public InstanceFactory(ConnectionParser parser) {
+        this.parser = parser;
+    }
+
+    public InstanceFactory() {
+        this(null);
+    }
+
+    public <T> T createInstance(Class<T> clazz) {
+        try {
+            T instance = clazz.newInstance();
+            // Inject Configuration, if wanted
+            if (ClassUtils.isAssignable(clazz, HasConfiguration.class)) {
+                Optional<ParameterizedType> typeOptional = Arrays.stream(clazz.getGenericInterfaces())
+                    .filter(type -> type instanceof ParameterizedType)
+                    .map(type -> ((ParameterizedType) type))
+                    .filter(type -> type.getRawType().equals(HasConfiguration.class))
+                    .findAny();
+                if (!typeOptional.isPresent()) {
+                    throw new IllegalStateException("This should never happen!");
+                }
+                Class<?> configurationClass = (Class<?>) typeOptional.get().getActualTypeArguments()[0];
+                // Try to get the Configuration
+                Object configuration;
+                if (parser != null) {
+                    configuration = parser.createConfiguration(configurationClass);
+                } else {
+                    configuration = configurationClass.newInstance();
+                }
+                ((HasConfiguration) instance).setConfiguration(configuration);
+                // System.out.println("The Configuration has to be of Type " + configurationType);
+            }
+            // Set all Properties
+            // transport.setProperties(parser.getProperties());
+            return instance;
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new IllegalStateException("Cannot Instantiate Transport '"
+                + clazz.getSimpleName()
+                + "'. Cannot access Default no Args Constructor.", e);
+        }
+    }
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
index 2e478c3..051cb14 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
@@ -30,6 +30,7 @@ import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcException;
 import org.apache.plc4x.java.api.exceptions.PlcIoException;
 import org.apache.plc4x.java.spi.GeneratedDriverByteToMessageCodec;
+import org.apache.plc4x.java.spi.InstanceFactory;
 import org.apache.plc4x.java.spi.Plc4xNettyWrapper;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.events.ConnectEvent;
@@ -55,6 +56,7 @@ public class DefaultNettyPlcConnection<BASE_PROTOCOL_CLASS extends Message> exte
     protected final boolean awaitSessionSetupComplete;
     protected Channel channel;
     protected boolean connected;
+    private InstanceFactory factory;
     private SocketAddress address;
     private ProtocolStackConfigurer stackConfigurer;
 
@@ -75,9 +77,10 @@ public class DefaultNettyPlcConnection<BASE_PROTOCOL_CLASS extends Message> exte
         this.connected = false;
     }
 
-    public DefaultNettyPlcConnection(SocketAddress address, ChannelFactory channelFactory, boolean awaitSessionSetupComplete, PlcFieldHandler handler,
+    public DefaultNettyPlcConnection(InstanceFactory factory, SocketAddress address, ChannelFactory channelFactory, boolean awaitSessionSetupComplete, PlcFieldHandler handler,
                                      ProtocolStackConfigurer stackConfigurer) {
         this(channelFactory, awaitSessionSetupComplete, handler);
+        this.factory = factory;
         this.address = address;
         this.stackConfigurer = stackConfigurer;
     }
@@ -158,6 +161,9 @@ public class DefaultNettyPlcConnection<BASE_PROTOCOL_CLASS extends Message> exte
         if (stackConfigurer == null) {
             throw new IllegalStateException("No Protocol Stack Configurer is given!");
         }
+        if (factory == null) {
+            throw new IllegalStateException("No Instance Factory is Present!");
+        }
         return new ChannelInitializer<Channel>() {
             @Override
             protected void initChannel(Channel channel) {
@@ -173,7 +179,7 @@ public class DefaultNettyPlcConnection<BASE_PROTOCOL_CLASS extends Message> exte
                         }
                     }
                 });
-                setProtocol(stackConfigurer.apply(pipeline));
+                setProtocol(stackConfigurer.apply(factory, pipeline));
             }
         };
     }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
index 8d61b8d..c3d4b20 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
@@ -23,44 +23,36 @@ import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.PlcDriver;
 import org.apache.plc4x.java.api.authentication.PlcAuthentication;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.spi.InstanceFactory;
 import org.apache.plc4x.java.spi.generation.Message;
 import org.apache.plc4x.java.spi.parser.ConnectionParser;
 
-public abstract class GeneratedDriverBase<CONFIGURATION, BASE_PACKET extends Message> implements PlcDriver {
+public abstract class GeneratedDriverBase<BASE_PACKET extends Message> implements PlcDriver {
 
     protected abstract int getDefaultPortIPv4();
 
-    protected abstract Class<CONFIGURATION> getConfigurationClass();
-
     protected abstract PlcFieldHandler getFieldHandler();
 
     protected abstract Class<? extends NettyChannelFactory> getTransportChannelFactory();
 
-    protected abstract ProtocolStackConfigurer<BASE_PACKET> getStackConfigurer(CONFIGURATION configuration);
+    protected abstract ProtocolStackConfigurer<BASE_PACKET> getStackConfigurer();
 
     @Override
     public PlcConnection connect(String url) throws PlcConnectionException {
         ConnectionParser parser = new ConnectionParser(getProtocolCode(), url);
-        CONFIGURATION configuration = parser.createConfiguration(getConfigurationClass());
+        InstanceFactory instanceFactory = new InstanceFactory(parser);
+        // CONFIGURATION configuration = parser.createConfiguration(getConfigurationClass());
 
         // Create Instance of Transport
-        NettyChannelFactory transport;
-        try {
-            transport = getTransportChannelFactory().newInstance();
-        } catch (InstantiationException | IllegalAccessException e) {
-            throw new IllegalStateException("Cannot Instantiate Transport '"
-                + getTransportChannelFactory().getSimpleName()
-                + "'. Cannot access Default no Args Constructor.", e);
-        }
-        // Set all Properties
-        transport.setProperties(parser.getProperties());
+        NettyChannelFactory transport = instanceFactory.createInstance(getTransportChannelFactory());
 
         return new DefaultNettyPlcConnection<>(
+            instanceFactory,
             parser.getSocketAddress(getDefaultPortIPv4()),
             transport,
             true,
             getFieldHandler(),
-            getStackConfigurer(configuration));
+            getStackConfigurer());
     }
 
     @Override
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
index 6e335f8..09f14fc 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
@@ -20,11 +20,21 @@
 package org.apache.plc4x.java.spi.connection;
 
 import io.netty.channel.ChannelPipeline;
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.plc4x.java.spi.InstanceFactory;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.generation.Message;
 
 public interface ProtocolStackConfigurer<T extends Message> {
 
     /** Applies the given Stack to the Pipeline and returns the wired instance */
-    Plc4xProtocolBase<T> apply(ChannelPipeline pipeline);
+    Plc4xProtocolBase<T> apply(InstanceFactory factory, ChannelPipeline pipeline);
+
+    /**
+     * @deprecated New Drivers should use the {@link #apply(InstanceFactory, ChannelPipeline)} method.
+     */
+    @Deprecated
+    default Plc4xProtocolBase<T> apply(ChannelPipeline pipeline) {
+        throw new NotImplementedException("");
+    }
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackBuilder.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackBuilder.java
index 5b4e253..2893cbb 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackBuilder.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackBuilder.java
@@ -34,31 +34,31 @@ import java.util.function.Function;
 public final class SingleProtocolStackBuilder<BASE_PAKET_CLASS extends Message> {
 
     private Class<BASE_PAKET_CLASS> basePaketClass;
-    private Plc4xProtocolBase<BASE_PAKET_CLASS> protocol;
-    private Function<ByteBuf, Integer> packetSizeEstimator;
-    private Consumer<ByteBuf> corruptPacketRemover;
+    private Class<? extends Plc4xProtocolBase<BASE_PAKET_CLASS>> protocol;
+    private Class<? extends Function<ByteBuf, Integer>> packetSizeEstimator;
+    private Class<? extends Consumer<ByteBuf>> corruptPacketRemover;
 
     SingleProtocolStackBuilder(Class<BASE_PAKET_CLASS> basePaketClass) {
         this.basePaketClass = basePaketClass;
     }
 
-    public SingleProtocolStackBuilder<BASE_PAKET_CLASS> withProtocol(Plc4xProtocolBase<BASE_PAKET_CLASS> protocol) {
+    public SingleProtocolStackBuilder<BASE_PAKET_CLASS> withProtocol(Class<? extends Plc4xProtocolBase<BASE_PAKET_CLASS>> protocol) {
         this.protocol = protocol;
         return this;
     }
 
-    public SingleProtocolStackBuilder<BASE_PAKET_CLASS> withPacketSizeEstimator(Function<ByteBuf, Integer> packetSizeEstimator) {
+    public SingleProtocolStackBuilder<BASE_PAKET_CLASS> withPacketSizeEstimator(Class<? extends Function<ByteBuf, Integer>> packetSizeEstimator) {
         this.packetSizeEstimator = packetSizeEstimator;
         return this;
     }
 
-    public SingleProtocolStackBuilder<BASE_PAKET_CLASS> withCorruptPacketRemover(Consumer<ByteBuf> corruptPacketRemover) {
+    public SingleProtocolStackBuilder<BASE_PAKET_CLASS> withCorruptPacketRemover(Class<? extends Consumer<ByteBuf>> corruptPacketRemover) {
         this.corruptPacketRemover = corruptPacketRemover;
         return this;
     }
 
     public SingleProtocolStackConfigurer<BASE_PAKET_CLASS> build() {
         assert this.protocol != null;
-        return new SingleProtocolStackConfigurer<>(basePaketClass, protocol, packetSizeEstimator, corruptPacketRemover);
+        return new SingleProtocolStackConfigurer<BASE_PAKET_CLASS>(basePaketClass, protocol, packetSizeEstimator, corruptPacketRemover);
     }
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurer.java
index edcd302..a401e3f 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurer.java
@@ -22,6 +22,7 @@ package org.apache.plc4x.java.spi.connection;
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelPipeline;
+import org.apache.plc4x.java.spi.InstanceFactory;
 import org.apache.plc4x.java.spi.Plc4xNettyWrapper;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.generation.Message;
@@ -35,16 +36,16 @@ import java.util.function.Function;
 public class SingleProtocolStackConfigurer<BASE_PAKET_CLASS extends Message> implements ProtocolStackConfigurer<BASE_PAKET_CLASS> {
 
     private final Class<BASE_PAKET_CLASS> basePaketClass;
-    private final Plc4xProtocolBase<BASE_PAKET_CLASS> protocol;
-    private final Function<ByteBuf, Integer> packetSizeEstimator;
-    private final Consumer<ByteBuf> corruptPacketRemover;
+    private final Class<? extends Plc4xProtocolBase<BASE_PAKET_CLASS>> protocolClass;
+    private final Class<? extends Function<ByteBuf, Integer>> packetSizeEstimator;
+    private final Class<? extends Consumer<ByteBuf>> corruptPacketRemover;
 
     /** Only accessible via Builder */
-    SingleProtocolStackConfigurer(Class<BASE_PAKET_CLASS> basePaketClass, Plc4xProtocolBase<BASE_PAKET_CLASS> protocol,
-                                  Function<ByteBuf, Integer> packetSizeEstimator,
-                                  Consumer<ByteBuf> corruptPacketRemover) {
+    SingleProtocolStackConfigurer(Class<BASE_PAKET_CLASS> basePaketClass, Class<? extends Plc4xProtocolBase<BASE_PAKET_CLASS>> protocol,
+                                  Class<? extends Function<ByteBuf, Integer>> packetSizeEstimator,
+                                  Class<? extends Consumer<ByteBuf>> corruptPacketRemover) {
         this.basePaketClass = basePaketClass;
-        this.protocol = protocol;
+        this.protocolClass = protocol;
         this.packetSizeEstimator = packetSizeEstimator;
         this.corruptPacketRemover = corruptPacketRemover;
     }
@@ -53,14 +54,17 @@ public class SingleProtocolStackConfigurer<BASE_PAKET_CLASS extends Message> imp
         return new SingleProtocolStackBuilder<>(basePaketClass);
     }
 
-    private ChannelHandler getMessageCodec() {
+    private ChannelHandler getMessageCodec(InstanceFactory instanceFactory) {
         ReflectionBasedIo<BASE_PAKET_CLASS> io = new ReflectionBasedIo<>(basePaketClass);
-        return new GeneratedProtocolMessageCodec<>(basePaketClass, io, io, packetSizeEstimator, corruptPacketRemover);
+        return new GeneratedProtocolMessageCodec<>(basePaketClass, io, io,
+            instanceFactory.createInstance(packetSizeEstimator),
+            instanceFactory.createInstance(corruptPacketRemover));
     }
 
     /** Applies the given Stack to the Pipeline */
-    @Override public Plc4xProtocolBase<BASE_PAKET_CLASS> apply(ChannelPipeline pipeline) {
-        pipeline.addLast(getMessageCodec());
+    @Override public Plc4xProtocolBase<BASE_PAKET_CLASS> apply(InstanceFactory factory, ChannelPipeline pipeline) {
+        pipeline.addLast(getMessageCodec(factory));
+        Plc4xProtocolBase<BASE_PAKET_CLASS> protocol = factory.createInstance(protocolClass);
         Plc4xNettyWrapper<BASE_PAKET_CLASS> context = new Plc4xNettyWrapper<>(pipeline, protocol, basePaketClass);
         pipeline.addLast(context);
         return protocol;
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/BooleanDefaultValue.java
similarity index 67%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
copy to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/BooleanDefaultValue.java
index 6e335f8..d517ea2 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/BooleanDefaultValue.java
@@ -17,14 +17,17 @@
  * under the License.
  */
 
-package org.apache.plc4x.java.spi.connection;
+package org.apache.plc4x.java.spi.parser;
 
-import io.netty.channel.ChannelPipeline;
-import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.generation.Message;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
-public interface ProtocolStackConfigurer<T extends Message> {
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BooleanDefaultValue {
+
+    boolean value();
 
-    /** Applies the given Stack to the Pipeline and returns the wired instance */
-    Plc4xProtocolBase<T> apply(ChannelPipeline pipeline);
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConnectionParser.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConnectionParser.java
index 9ad8f89..128e7a9 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConnectionParser.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConnectionParser.java
@@ -19,12 +19,14 @@
 
 package org.apache.plc4x.java.spi.parser;
 
+import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
@@ -109,11 +111,34 @@ public class ConnectionParser {
         return properties;
     }
 
+    private static Object getDefaultValueFromAnnotation(Field field) {
+        IntDefaultValue intDefaultValue = field.getAnnotation(IntDefaultValue.class);
+        if (intDefaultValue != null) {
+            return intDefaultValue.value();
+        }
+        BooleanDefaultValue booleanDefaultValue = field.getAnnotation(BooleanDefaultValue.class);
+        if (booleanDefaultValue != null) {
+            return booleanDefaultValue.value();
+        }
+        DoubleDefaultValue doubleDefaultValue = field.getAnnotation(DoubleDefaultValue.class);
+        if (doubleDefaultValue != null) {
+            return doubleDefaultValue.value();
+        }
+        StringDefaultValue stringDefaultValue = field.getAnnotation(StringDefaultValue.class);
+        if (stringDefaultValue != null) {
+            return stringDefaultValue.value();
+        }
+        return null;
+    }
+
     // TODO Respect Path Params
     public <T> T createConfiguration(Class<T> pClazz) {
         Map<String, Field> fieldMap = Arrays.stream(FieldUtils.getAllFields(pClazz))
             .filter(field -> field.getAnnotation(ConfigurationParameter.class) != null)
-            .collect(Collectors.toMap(Field::getName, Function.identity()));
+            .collect(Collectors.toMap(
+                field -> getConfigurationName(field, field.getName()),
+                Function.identity()
+            ));
 
         T instance;
         try {
@@ -141,17 +166,18 @@ public class ConnectionParser {
                     iter.remove();
                 } else {
                     // TODO Implement other types
-                    IntDefaultValue intDefaultValue = fieldMap.get(entry.getKey()).getAnnotation(IntDefaultValue.class);
-                    if (intDefaultValue != null) {
-                        final Field field = fieldMap.get(entry.getKey());
-                        field.setAccessible(true);
-                        if (field.getType().isAssignableFrom(String.class)) {
-                            //field.set(instance, stringListMap.get(entry.getKey()).get(0));
-                        } else if (field.getType().isAssignableFrom(int.class)) {
-                            field.setInt(instance, intDefaultValue.value());
+                    // Check IntDefaultValue
+                    Object defaultValue = getDefaultValueFromAnnotation(fieldMap.get(entry.getKey()));
+                    if (defaultValue != null) {
+                        try {
+                            PropertyUtils.setSimpleProperty(instance, fieldMap.get(entry.getKey()).getName(), defaultValue);
+                        } catch (InvocationTargetException | NoSuchMethodException e) {
+                            throw new IllegalStateException(String.format("Unable to inject Configuration into field '%s' on Configuration %s", entry.getKey(), pClazz.getSimpleName()), e);
                         }
-                        iter.remove();
                     }
+                    iter.remove();
+                    continue;
+
                 }
             }
 
@@ -159,8 +185,7 @@ public class ConnectionParser {
             List<String> missingFields = fieldMap.entrySet().stream()
                 .filter(entry -> entry.getValue().getAnnotation(Required.class) != null)
                 .map(entry -> entry.getValue().getAnnotation(ConfigurationParameter.class) != null ?
-                    // In Memory of S. Ruehl
-                    (StringUtils.isBlank(entry.getValue().getAnnotation(ConfigurationParameter.class).value()) ? entry.getKey() : entry.getValue().getAnnotation(ConfigurationParameter.class).value()) : entry.getKey())
+                    (getConfigurationName(entry.getValue(), entry.getKey())) : entry.getKey())
                 .collect(toList());
 
             if (missingFields.size() > 0) {
@@ -172,6 +197,15 @@ public class ConnectionParser {
         return instance;
     }
 
+    /** Extracts the Name from the configuration if given, uses given "name" otherwise */
+    private String getConfigurationName(Field field, String name) {
+        if (StringUtils.isBlank(field.getAnnotation(ConfigurationParameter.class).value())) {
+            return name;
+        } else {
+            return field.getAnnotation(ConfigurationParameter.class).value();
+        }
+    }
+
     /**
      * https://stackoverflow.com/questions/13592236/parse-a-uri-string-into-name-value-collection/13592567#13592567
      */
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/DoubleDefaultValue.java
similarity index 67%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
copy to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/DoubleDefaultValue.java
index 6e335f8..7ea4367 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/DoubleDefaultValue.java
@@ -17,14 +17,17 @@
  * under the License.
  */
 
-package org.apache.plc4x.java.spi.connection;
+package org.apache.plc4x.java.spi.parser;
 
-import io.netty.channel.ChannelPipeline;
-import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.generation.Message;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
-public interface ProtocolStackConfigurer<T extends Message> {
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DoubleDefaultValue {
+
+    double value();
 
-    /** Applies the given Stack to the Pipeline and returns the wired instance */
-    Plc4xProtocolBase<T> apply(ChannelPipeline pipeline);
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/StringDefaultValue.java
similarity index 67%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
copy to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/StringDefaultValue.java
index 6e335f8..163fc7a 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/StringDefaultValue.java
@@ -17,14 +17,17 @@
  * under the License.
  */
 
-package org.apache.plc4x.java.spi.connection;
+package org.apache.plc4x.java.spi.parser;
 
-import io.netty.channel.ChannelPipeline;
-import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.generation.Message;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
-public interface ProtocolStackConfigurer<T extends Message> {
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface StringDefaultValue {
+
+    String value();
 
-    /** Applies the given Stack to the Pipeline and returns the wired instance */
-    Plc4xProtocolBase<T> apply(ChannelPipeline pipeline);
 }
diff --git a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/parser/ConnectionParserTest.java b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/parser/ConnectionParserTest.java
index eb01835..b25756b 100644
--- a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/parser/ConnectionParserTest.java
+++ b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/parser/ConnectionParserTest.java
@@ -34,8 +34,8 @@ class ConnectionParserTest {
         ConnectionParser parser = new ConnectionParser("s7", "s7://192.168.167.1?rackId=1");
         PropertiesDescriptor properties = parser.createConfiguration(PropertiesDescriptor.class);
 
-        assertEquals(1, properties.rackId);
-        assertEquals(1, properties.slotId);
+        assertEquals(1, properties.getRackId());
+        assertEquals(1, properties.getSlotId());
     }
 
     @Test
@@ -46,7 +46,7 @@ class ConnectionParserTest {
         assertEquals(new InetSocketAddress("192.168.167.1", 102), inetSocketAddress);
     }
 
-    static class PropertiesDescriptor {
+    public static class PropertiesDescriptor {
 
         @ConfigurationParameter("rackId")
         @IntDefaultValue(1)
@@ -57,5 +57,20 @@ class ConnectionParserTest {
         @Required
         private int slotId;
 
+        public int getRackId() {
+            return rackId;
+        }
+
+        public void setRackId(int rackId) {
+            this.rackId = rackId;
+        }
+
+        public int getSlotId() {
+            return slotId;
+        }
+
+        public void setSlotId(int slotId) {
+            this.slotId = slotId;
+        }
     }
 }
\ No newline at end of file
diff --git a/plc4j/transports/tcp/src/main/java/org/apache/plc4x/java/tcp/connection/TcpConfiguration.java b/plc4j/transports/tcp/src/main/java/org/apache/plc4x/java/tcp/connection/TcpConfiguration.java
new file mode 100644
index 0000000..e0cea01
--- /dev/null
+++ b/plc4j/transports/tcp/src/main/java/org/apache/plc4x/java/tcp/connection/TcpConfiguration.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.plc4x.java.tcp.connection;
+
+import org.apache.plc4x.java.spi.parser.BooleanDefaultValue;
+import org.apache.plc4x.java.spi.parser.ConfigurationParameter;
+import org.apache.plc4x.java.spi.parser.IntDefaultValue;
+
+/**
+ * boolean keepalive = Boolean.parseBoolean(getPropertyOrDefault(SO_KEEPALIVE, "true"));
+ * boolean nodelay = Boolean.parseBoolean(getPropertyOrDefault(TCP_NODELAY, "true"));
+ * int connectTimeout = Integer.parseInt(getPropertyOrDefault(CONNECT_TIMEOUT_MILLIS, "1000"));
+ */
+public class TcpConfiguration {
+
+    @ConfigurationParameter("SO_KEEPALIVE")
+    @BooleanDefaultValue(true)
+    public boolean keepAlive = true;
+
+    @ConfigurationParameter("TCP_NODELAY")
+    @BooleanDefaultValue(true)
+    public boolean noDelay = true;
+
+    @ConfigurationParameter("CONNECT_TIMEOUT_MILLIS")
+    @IntDefaultValue(1000)
+    public int connectTimeout = 1000;
+
+    public boolean isKeepAlive() {
+        return keepAlive;
+    }
+
+    public void setKeepAlive(boolean keepAlive) {
+        this.keepAlive = keepAlive;
+    }
+
+    public boolean isNoDelay() {
+        return noDelay;
+    }
+
+    public void setNoDelay(boolean noDelay) {
+        this.noDelay = noDelay;
+    }
+
+    public int getConnectTimeout() {
+        return connectTimeout;
+    }
+
+    public void setConnectTimeout(int connectTimeout) {
+        this.connectTimeout = connectTimeout;
+    }
+
+    @Override public String toString() {
+        return "TcpConfiguration{" +
+            "keepAlive=" + keepAlive +
+            ", noDelay=" + noDelay +
+            ", connectTimeout=" + connectTimeout +
+            '}';
+    }
+}
diff --git a/plc4j/transports/tcp/src/main/java/org/apache/plc4x/java/tcp/connection/TcpSocketChannelFactory.java b/plc4j/transports/tcp/src/main/java/org/apache/plc4x/java/tcp/connection/TcpSocketChannelFactory.java
index 7653db0..b7d1488 100644
--- a/plc4j/transports/tcp/src/main/java/org/apache/plc4x/java/tcp/connection/TcpSocketChannelFactory.java
+++ b/plc4j/transports/tcp/src/main/java/org/apache/plc4x/java/tcp/connection/TcpSocketChannelFactory.java
@@ -30,6 +30,7 @@ import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.GenericFutureListener;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcException;
+import org.apache.plc4x.java.spi.HasConfiguration;
 import org.apache.plc4x.java.spi.connection.ChannelFactory;
 import org.apache.plc4x.java.spi.connection.NettyChannelFactory;
 import org.apache.plc4x.java.spi.connection.NettyPlcConnection;
@@ -42,13 +43,11 @@ import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.SocketAddress;
 
-public class TcpSocketChannelFactory extends NettyChannelFactory {
+public class TcpSocketChannelFactory extends NettyChannelFactory implements HasConfiguration<TcpConfiguration> {
 
     private static final Logger logger = LoggerFactory.getLogger(TcpSocketChannelFactory.class);
 
-    public static final String SO_KEEPALIVE = "SO_KEEPALIVE";
-    public static final String CONNECT_TIMEOUT_MILLIS = "CONNECT_TIMEOUT_MILLIS";
-    private static final String TCP_NODELAY = "TCP_NODELAY";
+    private TcpConfiguration configuration;
 
     public TcpSocketChannelFactory() {
         // Default Constructor
@@ -71,18 +70,22 @@ public class TcpSocketChannelFactory extends NettyChannelFactory {
     }
 
 
+    @Override public void setConfiguration(TcpConfiguration tcpConfiguration) {
+        configuration = tcpConfiguration;
+    }
+
     @Override public Class<? extends Channel> getChannel() {
         return NioSocketChannel.class;
     }
 
     @Override public void configureBootstrap(Bootstrap bootstrap) {
-        boolean keepalive = Boolean.parseBoolean(getPropertyOrDefault(SO_KEEPALIVE, "true"));
-        boolean nodelay = Boolean.parseBoolean(getPropertyOrDefault(TCP_NODELAY, "true"));
-        int connectTimeout = Integer.parseInt(getPropertyOrDefault(CONNECT_TIMEOUT_MILLIS, "1000"));
-        logger.info("Configuring Bootstrap with properties\n\t{} {}\n\t{} {}\n\t{} {}", SO_KEEPALIVE, keepalive, TCP_NODELAY, nodelay, CONNECT_TIMEOUT_MILLIS, connectTimeout);
-        bootstrap.option(ChannelOption.SO_KEEPALIVE, keepalive);
-        bootstrap.option(ChannelOption.TCP_NODELAY, nodelay);
-        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout);
+        if (configuration == null) {
+            this.configuration = new TcpConfiguration();
+        }
+        logger.info("Configuring Bootstrap with {}", configuration);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, configuration.isKeepAlive());
+        bootstrap.option(ChannelOption.TCP_NODELAY, configuration.isNoDelay());
+        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, configuration.getConnectTimeout());
     }
 
 }
diff --git a/sandbox/test-java-knxnetip-driver/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java b/sandbox/test-java-knxnetip-driver/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
index f39147e..eb666ac 100644
--- a/sandbox/test-java-knxnetip-driver/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
+++ b/sandbox/test-java-knxnetip-driver/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
@@ -32,7 +32,7 @@ import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 
 import java.util.function.Function;
 
-public class KnxNetIpDriver extends GeneratedDriverBase<KnxNetIpConfiguration, KNXNetIPMessage> {
+public class KnxNetIpDriver extends GeneratedDriverBase<KNXNetIPMessage> {
 
     public static final int KNXNET_IP_PORT = 3671;
 
@@ -50,10 +50,6 @@ public class KnxNetIpDriver extends GeneratedDriverBase<KnxNetIpConfiguration, K
         return KNXNET_IP_PORT;
     }
 
-    @Override protected Class<KnxNetIpConfiguration> getConfigurationClass() {
-        return KnxNetIpConfiguration.class;
-    }
-
     @Override protected PlcFieldHandler getFieldHandler() {
         return new KnxNetIpFieldHandler();
     }
@@ -62,10 +58,10 @@ public class KnxNetIpDriver extends GeneratedDriverBase<KnxNetIpConfiguration, K
         return UdpSocketChannelFactory.class;
     }
 
-    @Override protected ProtocolStackConfigurer<KNXNetIPMessage> getStackConfigurer(KnxNetIpConfiguration knxNetIpConfiguration) {
+    @Override protected ProtocolStackConfigurer<KNXNetIPMessage> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(KNXNetIPMessage.class)
-            .withProtocol(new KnxNetIpProtocolLogic(knxNetIpConfiguration))
-            .withPacketSizeEstimator((new PacketSizeEstimator()))
+            .withProtocol(KnxNetIpProtocolLogic.class)
+            .withPacketSizeEstimator(PacketSizeEstimator.class)
             .build();
     }
 
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
index 5e1765d..c7a869d 100644
--- a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
@@ -23,6 +23,7 @@ import org.apache.plc4x.java.api.PlcDriver;
 import org.apache.plc4x.java.s7.readwrite.connection.S7Configuration;
 import org.apache.plc4x.java.s7.readwrite.protocol.S7ProtocolLogic;
 import org.apache.plc4x.java.s7.readwrite.utils.S7PlcFieldHandler;
+import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.connection.NettyChannelFactory;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
@@ -34,7 +35,7 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 
 @Component(service = PlcDriver.class, immediate = true)
-public class S7Driver extends GeneratedDriverBase<S7Configuration, TPKTPacket> {
+public class S7Driver extends GeneratedDriverBase<TPKTPacket> {
 
     private static final int ISO_ON_TCP_PORT = 102;
 
@@ -52,10 +53,6 @@ public class S7Driver extends GeneratedDriverBase<S7Configuration, TPKTPacket> {
         return ISO_ON_TCP_PORT;
     }
 
-    @Override protected Class<S7Configuration> getConfigurationClass() {
-        return S7Configuration.class;
-    }
-
     @Override protected S7PlcFieldHandler getFieldHandler() {
         return new S7PlcFieldHandler();
     }
@@ -64,11 +61,11 @@ public class S7Driver extends GeneratedDriverBase<S7Configuration, TPKTPacket> {
         return TcpSocketChannelFactory.class;
     }
 
-    @Override protected ProtocolStackConfigurer<TPKTPacket> getStackConfigurer(S7Configuration configuration) {
+    @Override protected ProtocolStackConfigurer<TPKTPacket> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(TPKTPacket.class)
-            .withProtocol(new S7ProtocolLogic(configuration))
-            .withPacketSizeEstimator(new ByteLengthEstimator())
-            .withCorruptPacketRemover(new CorruptPackageCleaner())
+            .withProtocol(S7ProtocolLogic.class)
+            .withPacketSizeEstimator(ByteLengthEstimator.class)
+            .withCorruptPacketRemover(CorruptPackageCleaner.class)
             .build();
     }
 
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Configuration.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Configuration.java
index 20adeec..e3b47da 100644
--- a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Configuration.java
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Configuration.java
@@ -20,23 +20,82 @@
 package org.apache.plc4x.java.s7.readwrite.connection;
 
 import org.apache.plc4x.java.spi.parser.ConfigurationParameter;
+import org.apache.plc4x.java.spi.parser.IntDefaultValue;
 import org.apache.plc4x.java.spi.parser.Required;
 
 public class S7Configuration {
 
     @ConfigurationParameter("rackId")
-    public short rack = 1;
+    @IntDefaultValue(1)
+    public int rack = 1;
+
     @ConfigurationParameter("slotId")
-    public short slot = 1;
+    @IntDefaultValue(1)
+    public int slot = 1;
+
     @ConfigurationParameter
-    public short pduSize = 1024;
+    @IntDefaultValue(1024)
+    public int pduSize = 1024;
+
     @ConfigurationParameter
-    public short maxAmqCaller = 8;
+    @IntDefaultValue(8)
+    public int maxAmqCaller = 8;
+
     @ConfigurationParameter
-    public short maxAmqCallee = 8;
+    @IntDefaultValue(8)
+    public int maxAmqCallee = 8;
+
     @ConfigurationParameter
     public String controllerType;
 
+    public int getRack() {
+        return rack;
+    }
+
+    public void setRack(int rack) {
+        this.rack = rack;
+    }
+
+    public int getSlot() {
+        return slot;
+    }
+
+    public void setSlot(int slot) {
+        this.slot = slot;
+    }
+
+    public int getPduSize() {
+        return pduSize;
+    }
+
+    public void setPduSize(int pduSize) {
+        this.pduSize = pduSize;
+    }
+
+    public int getMaxAmqCaller() {
+        return maxAmqCaller;
+    }
+
+    public void setMaxAmqCaller(int maxAmqCaller) {
+        this.maxAmqCaller = maxAmqCaller;
+    }
+
+    public int getMaxAmqCallee() {
+        return maxAmqCallee;
+    }
+
+    public void setMaxAmqCallee(int maxAmqCallee) {
+        this.maxAmqCallee = maxAmqCallee;
+    }
+
+    public String getControllerType() {
+        return controllerType;
+    }
+
+    public void setControllerType(String controllerType) {
+        this.controllerType = controllerType;
+    }
+
     @Override
     public String toString() {
         return "Configuration{" +
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
index c927eb2..6d01afb 100644
--- a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
@@ -43,6 +43,7 @@ import org.apache.plc4x.java.s7.readwrite.utils.S7TsapIdEncoder;
 import org.apache.plc4x.java.s7data.readwrite.*;
 import org.apache.plc4x.java.s7data.readwrite.io.*;
 import org.apache.plc4x.java.spi.ConversationContext;
+import org.apache.plc4x.java.spi.HasConfiguration;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.messages.*;
 import org.apache.plc4x.java.spi.messages.items.*;
@@ -60,7 +61,7 @@ import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 
-public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
+public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> implements HasConfiguration<S7Configuration> {
 
     private static final Logger logger = LoggerFactory.getLogger(S7ProtocolLogic.class);
     public static final Duration REQUEST_TIMEOUT = Duration.ofMillis(10000);
@@ -75,14 +76,14 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
 
     private static final AtomicInteger tpduGenerator = new AtomicInteger(10);
 
-    public S7ProtocolLogic(S7Configuration configuration) {
+    @Override public void setConfiguration(S7Configuration configuration) {
         this.callingTsapId = S7TsapIdEncoder.encodeS7TsapId(DeviceGroup.PG_OR_PC, configuration.rack, configuration.slot);
         this.calledTsapId = S7TsapIdEncoder.encodeS7TsapId(DeviceGroup.OS, 0, 0);
         this.controllerType = configuration.controllerType == null ? S7ControllerType.ANY : S7ControllerType.valueOf(configuration.controllerType);
         if (this.controllerType == S7ControllerType.LOGO && configuration.pduSize == 1024) {
             configuration.pduSize = 480;
         }
-        this.cotpTpduSize = getNearestMatchingTpduSize(configuration.pduSize);
+        this.cotpTpduSize = getNearestMatchingTpduSize((short) configuration.getPduSize());
         this.pduSize = cotpTpduSize.getSizeInBytes() - 16;
         this.maxAmqCaller = configuration.maxAmqCaller;
         this.maxAmqCallee = configuration.maxAmqCallee;
@@ -619,5 +620,4 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
         }
         return null;
     }
-
 }