You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2023/06/07 07:32:53 UTC

[plc4x] 02/02: refactor(plc4j/udp-transport): Made it generally possible to open a UDP transport with a fixed local port

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

cdutz pushed a commit to branch chore/profinet-phase-3
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 8896bcbff664094a09854cedb351ff09b671eacb
Author: Christofer Dutz <cd...@apache.org>
AuthorDate: Wed Jun 7 09:32:41 2023 +0200

    refactor(plc4j/udp-transport): Made it generally possible to open a UDP transport with a fixed local port
---
 .../java/spi/connection/NettyChannelFactory.java     | 20 ++++++++++++--------
 .../plc4x/java/transport/udp/UdpChannelFactory.java  |  8 ++++++--
 .../plc4x/java/transport/udp/UdpTransport.java       | 15 +++++++++++----
 .../transport/udp/UdpTransportConfiguration.java     |  9 +++++++++
 4 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/NettyChannelFactory.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/NettyChannelFactory.java
index 2901877bef..5652882eec 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/NettyChannelFactory.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/NettyChannelFactory.java
@@ -44,13 +44,16 @@ public abstract class NettyChannelFactory implements ChannelFactory {
 
     private final Map<Channel, EventLoopGroup> eventLoops = new ConcurrentHashMap<>();
 
-    /**
-     * TODO should be removed together with the Constructor.
-     */
-    private final SocketAddress address;
+    private final SocketAddress localAddress;
+    private final SocketAddress remoteAddress;
+
+    protected NettyChannelFactory(SocketAddress remoteAddress) {
+        this(null, remoteAddress);
+    }
 
-    protected NettyChannelFactory(SocketAddress address) {
-        this.address = address;
+    protected NettyChannelFactory(SocketAddress localAddress, SocketAddress remoteAddress) {
+        this.localAddress = localAddress;
+        this.remoteAddress = remoteAddress;
     }
 
     /**
@@ -83,7 +86,7 @@ public abstract class NettyChannelFactory implements ChannelFactory {
      * Has to be in accordance with {@link #getChannel()}
      * otherwise a Runtime Exception will be produced by Netty
      * <p>
-     * By Default Nettys {@link NioEventLoopGroup} is used.
+     * By Default Netty's {@link NioEventLoopGroup} is used.
      * Transports which have to use a different EventLoopGroup have to override {#getEventLoopGroup()}.
      */
     public EventLoopGroup getEventLoopGroup() {
@@ -106,7 +109,8 @@ public abstract class NettyChannelFactory implements ChannelFactory {
             configureBootstrap(bootstrap);
             bootstrap.handler(channelHandler);
             // Start the client.
-            final ChannelFuture f = bootstrap.connect(address);
+            final ChannelFuture f = (localAddress == null) ?
+                bootstrap.connect(remoteAddress) : bootstrap.connect(remoteAddress, localAddress);
             f.addListener(future -> {
                 if (!future.isSuccess()) {
                     logger.info("Unable to connect, shutting down worker thread.");
diff --git a/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpChannelFactory.java b/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpChannelFactory.java
index d13053edff..7fc9fe2d1a 100644
--- a/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpChannelFactory.java
+++ b/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpChannelFactory.java
@@ -36,8 +36,12 @@ public class UdpChannelFactory extends NettyChannelFactory implements HasConfigu
 
     private UdpTransportConfiguration configuration;
 
-    public UdpChannelFactory(SocketAddress address) {
-        super(address);
+    public UdpChannelFactory(SocketAddress remoteAddress) {
+        super(remoteAddress);
+    }
+
+    public UdpChannelFactory(SocketAddress localAddress, SocketAddress remoteAddress) {
+        super(localAddress, remoteAddress);
     }
 
     @Override
diff --git a/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpTransport.java b/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpTransport.java
index 8579c70f76..2d90a352de 100644
--- a/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpTransport.java
+++ b/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpTransport.java
@@ -62,20 +62,27 @@ public class UdpTransport implements Transport, HasConfiguration<UdpTransportCon
 
         // If the port wasn't specified, try to get a default port from the configuration.
         int port;
+        int localPort = UdpTransportConfiguration.NO_DEFAULT_PORT;
         if(portString != null) {
             port = Integer.parseInt(portString);
-        } else if ((configuration != null) &&
-            (configuration.getDefaultPort() != UdpTransportConfiguration.NO_DEFAULT_PORT)) {
+        } else if ((configuration != null) &&  (configuration.getDefaultPort() != UdpTransportConfiguration.NO_DEFAULT_PORT)) {
             port = configuration.getDefaultPort();
         } else {
             throw new PlcRuntimeException("No port defined");
         }
+        if (configuration != null) {
+            localPort = configuration.getLocalPort();
+        }
 
         // Create the fully qualified remote socket address which we should connect to.
-        SocketAddress address = new InetSocketAddress((ip == null) ? hostname : ip, port);
+        SocketAddress remoteAddress = new InetSocketAddress((ip == null) ? hostname : ip, port);
+        if(localPort != UdpTransportConfiguration.NO_DEFAULT_PORT) {
+            SocketAddress localAddress = new InetSocketAddress(localPort);
+            return new UdpChannelFactory(localAddress, remoteAddress);
+        }
 
         // Initialize the channel factory with the default socket address we want to connect to.
-        return new UdpChannelFactory(address);
+        return new UdpChannelFactory(remoteAddress);
     }
 
 }
diff --git a/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpTransportConfiguration.java b/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpTransportConfiguration.java
index 2c26fdf2f8..8d35b04fdf 100644
--- a/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpTransportConfiguration.java
+++ b/plc4j/transports/udp/src/main/java/org/apache/plc4x/java/transport/udp/UdpTransportConfiguration.java
@@ -28,4 +28,13 @@ public interface UdpTransportConfiguration extends TransportConfiguration {
         return NO_DEFAULT_PORT;
     }
 
+    /**
+     * Most transports don't care about the local port, but some do.
+     * This option allows forcing a local port number to be used.
+     * @return local port number
+     */
+    default int getLocalPort() {
+        return NO_DEFAULT_PORT;
+    }
+
 }