You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2018/04/13 14:50:08 UTC

[incubator-plc4x] 02/02: Made PLC4X able to react on connections reset by the remote side.

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

cdutz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 43124f1b6d1051e4f4ffed1e04796692d602c8cc
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Fri Apr 13 16:49:13 2018 +0200

    Made PLC4X able to react on connections reset by the remote side.
---
 plc4j/protocols/driver-bases/base/pom.xml             |  4 ++++
 .../java/base/connection/AbstractPlcConnection.java   |  9 +++++++--
 .../java/base/connection/TcpSocketChannelFactory.java |  5 +----
 .../apache/plc4x/java/s7/netty/Plc4XS7Protocol.java   | 19 +++++++++++++++----
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/plc4j/protocols/driver-bases/base/pom.xml b/plc4j/protocols/driver-bases/base/pom.xml
index 2dcbd0e..7581fb1 100644
--- a/plc4j/protocols/driver-bases/base/pom.xml
+++ b/plc4j/protocols/driver-bases/base/pom.xml
@@ -54,6 +54,10 @@
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
+      <artifactId>netty-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
       <artifactId>netty-transport</artifactId>
     </dependency>
 
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 fa8adfa..0af87d6 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,7 @@ import org.apache.plc4x.java.api.connection.PlcLister;
 import org.apache.plc4x.java.api.connection.PlcReader;
 import org.apache.plc4x.java.api.connection.PlcWriter;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.api.exceptions.PlcIoException;
 
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
@@ -47,7 +48,6 @@ public abstract class AbstractPlcConnection implements PlcConnection {
         this.connected = false;
     }
 
-
     @Override
     public void connect() throws PlcConnectionException {
         try {
@@ -58,7 +58,12 @@ public abstract class AbstractPlcConnection implements PlcConnection {
 
             // Have the channel factory create a new channel instance.
             channel = channelFactory.createChannel(getChannelHandler(sessionSetupCompleteFuture));
-
+            channel.closeFuture().addListener(future -> {
+                if(!sessionSetupCompleteFuture.isDone()) {
+                    sessionSetupCompleteFuture.completeExceptionally(
+                        new PlcIoException("Connection terminated by remote"));
+                }
+            });
             // Send an event to the pipeline telling the Protocol filters what's going on.
             sendChannelCreatedEvent();
 
diff --git a/plc4j/protocols/driver-bases/tcp/src/main/java/org/apache/plc4x/java/base/connection/TcpSocketChannelFactory.java b/plc4j/protocols/driver-bases/tcp/src/main/java/org/apache/plc4x/java/base/connection/TcpSocketChannelFactory.java
index 8cb8d08..00b660b 100644
--- a/plc4j/protocols/driver-bases/tcp/src/main/java/org/apache/plc4x/java/base/connection/TcpSocketChannelFactory.java
+++ b/plc4j/protocols/driver-bases/tcp/src/main/java/org/apache/plc4x/java/base/connection/TcpSocketChannelFactory.java
@@ -19,10 +19,7 @@ under the License.
 package org.apache.plc4x.java.base.connection;
 
 import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelOption;
+import io.netty.channel.*;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.nio.NioSocketChannel;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
index 1d41aea..80467c4 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
@@ -20,6 +20,7 @@ package org.apache.plc4x.java.s7.netty;
 
 import io.netty.channel.ChannelHandlerContext;
 import org.apache.plc4x.java.api.exceptions.PlcException;
+import org.apache.plc4x.java.api.exceptions.PlcIoException;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException;
 import org.apache.plc4x.java.api.messages.*;
@@ -49,6 +50,7 @@ import org.apache.plc4x.java.s7.netty.model.payloads.VarPayload;
 import org.apache.plc4x.java.s7.netty.model.payloads.items.VarPayloadItem;
 import org.apache.plc4x.java.s7.netty.model.types.*;
 
+import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -101,15 +103,24 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
                     PlcRequestContainer requestContainer = (PlcRequestContainer) request.getParent();
 
                     // Remove the current request from the unconfirmed requests list.
-                    if(requests.containsKey(request.getTpduReference())) {
-                        requests.remove(request.getTpduReference());
-                    }
+                    requests.remove(request.getTpduReference());
 
                     requestContainer.getResponseFuture().completeExceptionally(cause);
                 }
             }
+        } else if((cause instanceof IOException) && cause.getMessage().contains("Connection reset by peer")) {
+            if (!requests.isEmpty()) {
+                // If the connection is hung up, all still pending requests can be closed.
+                for (PlcRequestContainer requestContainer : requests.values()) {
+                    requestContainer.getResponseFuture().completeExceptionally(
+                        new PlcIoException("Connection terminated unexpectedly"));
+                }
+                // Clear the list
+                requests.clear();
+            }
+        } else {
+            super.exceptionCaught(ctx, cause);
         }
-        super.exceptionCaught(ctx, cause);
     }
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

-- 
To stop receiving notification emails like this one, please contact
cdutz@apache.org.