You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@plc4x.apache.org by GitBox <gi...@apache.org> on 2018/10/25 16:02:24 UTC

[GitHub] sruehl closed pull request #26: connection manager for connection pool initial version

sruehl closed pull request #26: connection manager for connection pool initial version
URL: https://github.com/apache/incubator-plc4x/pull/26
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/plc4j/core/src/main/java/org/apache/plc4x/java/PlcDriverManager.java b/plc4j/core/src/main/java/org/apache/plc4x/java/PlcDriverManager.java
index 8539a61e8..5eb10d024 100644
--- a/plc4j/core/src/main/java/org/apache/plc4x/java/PlcDriverManager.java
+++ b/plc4j/core/src/main/java/org/apache/plc4x/java/PlcDriverManager.java
@@ -29,7 +29,7 @@ Licensed to the Apache Software Foundation (ASF) under one
 import java.util.Map;
 import java.util.ServiceLoader;
 
-public class PlcDriverManager {
+public class PlcDriverManager implements PlcDriverManagerInterface {
 
     private Map<String, PlcDriver> driverMap = null;
 
@@ -57,6 +57,7 @@ public PlcDriverManager(ClassLoader classLoader) {
      * @return PlcConnection object.
      * @throws PlcConnectionException an exception if the connection attempt failed.
      */
+    @Override
     public PlcConnection getConnection(String url) throws PlcConnectionException {
         PlcDriver driver = getDriver(url);
         PlcConnection connection = driver.connect(url);
@@ -72,6 +73,7 @@ public PlcConnection getConnection(String url) throws PlcConnectionException {
      * @return PlcConnection object.
      * @throws PlcConnectionException an exception if the connection attempt failed.
      */
+    @Override
     public PlcConnection getConnection(String url, PlcAuthentication authentication) throws PlcConnectionException {
         PlcDriver driver = getDriver(url);
         PlcConnection connection = driver.connect(url, authentication);
diff --git a/plc4j/core/src/main/java/org/apache/plc4x/java/PlcDriverManagerInterface.java b/plc4j/core/src/main/java/org/apache/plc4x/java/PlcDriverManagerInterface.java
new file mode 100644
index 000000000..c9b8ef261
--- /dev/null
+++ b/plc4j/core/src/main/java/org/apache/plc4x/java/PlcDriverManagerInterface.java
@@ -0,0 +1,29 @@
+/*
+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;
+
+import org.apache.plc4x.java.api.authentication.PlcAuthentication;
+import org.apache.plc4x.java.api.connection.PlcConnection;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+
+public interface PlcDriverManagerInterface {
+    PlcConnection getConnection(String url) throws PlcConnectionException;
+
+    PlcConnection getConnection(String url, PlcAuthentication authentication) throws PlcConnectionException;
+}
diff --git a/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/ConnectionProxy.java b/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/ConnectionProxy.java
new file mode 100644
index 000000000..b1188d5c9
--- /dev/null
+++ b/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/ConnectionProxy.java
@@ -0,0 +1,24 @@
+/*
+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.connectionpool;
+
+import org.apache.plc4x.java.api.connection.PlcConnection;
+
+public interface ConnectionProxy extends PlcConnection {
+}
\ No newline at end of file
diff --git a/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/PlcConnectionManager.java b/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/PlcConnectionManager.java
new file mode 100644
index 000000000..fc3ff0114
--- /dev/null
+++ b/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/PlcConnectionManager.java
@@ -0,0 +1,154 @@
+/*
+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.connectionpool;
+
+import org.apache.plc4x.java.PlcDriverManager;
+import org.apache.plc4x.java.PlcDriverManagerInterface;
+import org.apache.plc4x.java.api.authentication.PlcAuthentication;
+import org.apache.plc4x.java.api.connection.PlcConnection;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.exceptions.NoConnectionAvailableException;
+import org.apache.plc4x.java.exceptions.NotConnectedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.PreDestroy;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Plc Connection Manager to act as a controller to give threads access to a connection in the pool only if it is not
+ * used by a different thread
+ */
+public class PlcConnectionManager implements PlcDriverManagerInterface {
+    private static final Logger logger = LoggerFactory.getLogger(PlcConnectionManager.class);
+    //TODO: implement connection Pool with more than one connection
+    private Map<String, PlcConnection> connections = new HashMap<>();
+    private Map<String, Boolean> isBlockedMap = new HashMap<>();
+    private PlcDriverManager plcDriverManager;
+
+
+    public PlcConnectionManager(Map<String, PlcConnection> connectionProxyMap, Map<String, Boolean> isBlockedMap) {
+        this.connections = connectionProxyMap;
+        this.isBlockedMap = isBlockedMap;
+        plcDriverManager = new PlcDriverManager();
+    }
+
+
+    /**
+     * Connects to a PLC using the given plc connection string when no connection was requested jet and builds the pool.
+     * Else it return the connection from the pool in a connection proxy.
+     *
+     * @param connectionString plc url with protocol prefix to select correct connection
+     * @return PlcConnection in a proxy
+     * @throws PlcConnectionException if connection was unsuccessfull, or the connection all other connections are
+     * being used by different threads
+     */
+    @Override
+    public PlcConnection getConnection(String connectionString) throws PlcConnectionException {
+        if (!connections.containsKey(connectionString)) {
+            connections.put(connectionString,plcDriverManager.getConnection(connectionString));
+            isBlockedMap.put(connectionString, false);
+        }
+        if (connections.containsKey(connectionString) && isBlockedMap.containsKey(connectionString)) {
+            // TODO: await set time till connection maybe available
+            if (!isBlockedMap.get(connectionString)) {
+                return tryConnect(connectionString);
+            } else {
+                throw new NoConnectionAvailableException("Connection not available");
+            }
+        } else {
+            throw new NotConnectedException("Connection was not possible in the first place");
+        }
+    }
+
+    /**
+     * Connects to a PLC using the given plc connection string and authentification when no connection was requested jet and builds the pool.
+     * Else it return the connection from the pool in a connection proxy.
+     *
+     * @param connectionString plc url with protocol prefix to select correct connection
+     * @param authentication authentication credentials.
+     * @return PlcConnection in a proxy
+     * @throws PlcConnectionException if connection was unsuccessfull, or the connection all other connections are
+     * being used by different threads
+     */
+    @Override
+    public PlcConnection getConnection(String connectionString, PlcAuthentication authentication) throws PlcConnectionException {
+        if (!connections.containsKey(connectionString)) {
+            connections.put(connectionString,plcDriverManager.getConnection(connectionString,authentication));
+            isBlockedMap.put(connectionString, false);
+        }
+        if (connections.containsKey(connectionString) && isBlockedMap.containsKey(connectionString)) {
+            // TODO: await set time till connection maybe available
+            if (!isBlockedMap.get(connectionString)) {
+                return tryConnect(connectionString);
+            } else {
+                throw new NoConnectionAvailableException("Connection not available");
+            }
+        } else {
+            throw new NotConnectedException("Connection was not possible in the first place");
+        }
+    }
+
+    /**
+     * helper function to check if the connection can be established if it is not already established
+     * and get the available connection from map and return a proxy that tells this manager when the connection is closed
+     *
+     * @param connectionString of source
+     * @return PlcConnection to return in getConnection
+     * @throws NotConnectedException if connection could not be established
+     */
+    private PlcConnectionProxy tryConnect(String connectionString) throws NotConnectedException {
+        try {
+            if (connections.get(connectionString).isConnected()) {
+                isBlockedMap.put(connectionString, true);
+                return new PlcConnectionProxy(this, connectionString, connections.get(connectionString));
+            } else {
+                connections.get(connectionString).connect();
+                isBlockedMap.put(connectionString, true);
+                return new PlcConnectionProxy(this, connectionString, connections.get(connectionString));
+            }
+        } catch (PlcConnectionException ex) {
+            throw new NotConnectedException(ex);
+        }
+    }
+
+    /**
+     * After using the connection received from getReader or getConnection to release the connection again
+     * @param connectionString for which the connection should be released again
+     */
+    public void returnConnection(String connectionString) {
+        isBlockedMap.put(connectionString, false);
+    }
+
+    /**
+     * close all connections before closing
+     */
+    @PreDestroy
+    public void close() {
+        for (PlcConnection plcConnection : connections.values()) {
+            try {
+                plcConnection.close();
+            } catch (Exception ex) {
+                logger.error("Error disconnecting", ex);
+            }
+        }
+    }
+}
diff --git a/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/PlcConnectionProxy.java b/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/PlcConnectionProxy.java
new file mode 100644
index 000000000..ea9884f06
--- /dev/null
+++ b/plc4j/core/src/main/java/org/apache/plc4x/java/connectionpool/PlcConnectionProxy.java
@@ -0,0 +1,101 @@
+/*
+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.connectionpool;
+
+
+import org.apache.plc4x.java.api.connection.PlcConnection;
+import org.apache.plc4x.java.api.connection.PlcReader;
+import org.apache.plc4x.java.api.connection.PlcSubscriber;
+import org.apache.plc4x.java.api.connection.PlcWriter;
+
+import java.util.Optional;
+
+/**
+ * wrapper for PlcConnections to make access thread safe
+ * Tells ConnectionManager when the connection is not used anymore
+ */
+public class PlcConnectionProxy implements PlcConnection {
+    private final PlcConnectionManager parent;
+    private final String connectionString;
+    private final PlcConnection plcConnection;
+    private boolean closed;
+
+
+    public PlcConnectionProxy(PlcConnectionManager parent, String connectionString, PlcConnection plcConnection) {
+        this.parent = parent;
+        this.connectionString = connectionString;
+        this.plcConnection = plcConnection;
+        closed = false;
+    }
+
+    /**
+     * connect should already be handled in the connection manager
+     * returns without doing anything
+     */
+    @Override
+    public void connect() {
+    }
+
+    @Override
+    public boolean isConnected() {
+        if(closed){
+            return false;
+        }else {
+            return plcConnection.isConnected();
+        }
+    }
+
+    /**
+     * tell PlcConnectionManager that the connection is free again
+     */
+    @Override
+    public void close() {
+        closed = true;
+        parent.returnConnection(connectionString);
+    }
+
+    @Override
+    public Optional<PlcReader> getReader() {
+        if(closed){
+            return Optional.empty();
+        }else {
+            return plcConnection.getReader();
+        }
+    }
+
+    @Override
+    public Optional<PlcWriter> getWriter() {
+        if(closed) {
+            return Optional.empty();
+        }else{
+            return plcConnection.getWriter();
+        }
+    }
+
+    @Override
+    public Optional<PlcSubscriber> getSubscriber() {
+        if(closed){
+            return Optional.empty();
+        }else {
+            return plcConnection.getSubscriber();
+        }
+    }
+
+
+}
diff --git a/plc4j/core/src/main/java/org/apache/plc4x/java/exceptions/NoConnectionAvailableException.java b/plc4j/core/src/main/java/org/apache/plc4x/java/exceptions/NoConnectionAvailableException.java
new file mode 100644
index 000000000..9ae94b5fa
--- /dev/null
+++ b/plc4j/core/src/main/java/org/apache/plc4x/java/exceptions/NoConnectionAvailableException.java
@@ -0,0 +1,30 @@
+/*
+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.exceptions;
+
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+
+/**
+ * Exception that should be thrown if the connection is used by a different thread and not realeased in time
+ */
+public class NoConnectionAvailableException extends PlcConnectionException {
+    public NoConnectionAvailableException(String msg) {
+        super(msg);
+    }
+}
diff --git a/plc4j/core/src/main/java/org/apache/plc4x/java/exceptions/NotConnectedException.java b/plc4j/core/src/main/java/org/apache/plc4x/java/exceptions/NotConnectedException.java
new file mode 100644
index 000000000..b1673d82b
--- /dev/null
+++ b/plc4j/core/src/main/java/org/apache/plc4x/java/exceptions/NotConnectedException.java
@@ -0,0 +1,34 @@
+/*
+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.exceptions;
+
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+
+/**
+ * Exception that should be thrown when the connection to a PLC cannot be created
+ */
+public class NotConnectedException extends PlcConnectionException {
+    public NotConnectedException(String msg) {
+        super(msg);
+    }
+
+    public NotConnectedException(Throwable throwable) {
+        super(throwable);
+    }
+}
diff --git a/plc4j/core/src/test/java/org/apache/plc4x/java/connectionpool/PlcConnectionManagerTest.java b/plc4j/core/src/test/java/org/apache/plc4x/java/connectionpool/PlcConnectionManagerTest.java
new file mode 100644
index 000000000..b5f369d4c
--- /dev/null
+++ b/plc4j/core/src/test/java/org/apache/plc4x/java/connectionpool/PlcConnectionManagerTest.java
@@ -0,0 +1,99 @@
+/*
+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.connectionpool;
+
+import org.apache.plc4x.java.api.connection.PlcConnection;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.exceptions.NoConnectionAvailableException;
+import org.apache.plc4x.java.exceptions.NotConnectedException;
+import org.apache.plc4x.test.FastTests;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.Mockito;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class PlcConnectionManagerTest {
+
+    private PlcConnection plcConnection = Mockito.mock(PlcConnection.class);
+    private PlcConnectionManager plcConnectionManager;
+    private static final String TEST_STRING = "s7:127.0.0.100";
+
+
+    @Before
+    public void setUp() {
+        Map<String, PlcConnection> plcConnectionProxyMap = new HashMap<>();
+        Map<String, Boolean> booleanMap = new HashMap<>();
+        plcConnectionProxyMap.put(TEST_STRING, plcConnection);
+        booleanMap.put(TEST_STRING, false);
+        plcConnectionManager = new PlcConnectionManager(plcConnectionProxyMap, booleanMap);
+    }
+
+    @After
+    public void shutDown() {
+        plcConnectionManager.close();
+    }
+
+    @Test
+    @Category(FastTests.class)
+    public void getConnection() throws Exception {
+        plcConnectionManager.getConnection(TEST_STRING);
+        Mockito.verify(plcConnection, Mockito.times(1)).isConnected();
+    }
+
+    @Test(expected = NoConnectionAvailableException.class)
+    @Category(FastTests.class)
+    public void returnConnectionThrows() throws Exception {
+        Mockito.when(plcConnection.isConnected()).thenReturn(true);
+        plcConnectionManager.getConnection(TEST_STRING);
+        //second attempt should throw exception because connection was not returned yet
+        plcConnectionManager.getConnection(TEST_STRING);
+    }
+
+
+    @Test(expected = NotConnectedException.class)
+    @Category(FastTests.class)
+    public void returnConnectionCannotConnect() throws Exception {
+        Mockito.when(plcConnection.isConnected()).thenReturn(false);
+        PlcConnection plcConnectionProxy = plcConnectionManager.getConnection(TEST_STRING); // should
+        plcConnectionProxy.close();
+        Mockito.doThrow(new PlcConnectionException("")).when(plcConnection).connect();
+        plcConnectionManager.getConnection(TEST_STRING);
+
+    }
+
+    @Test
+    @Category(FastTests.class)
+    public void returnConnection() throws Exception {
+        Mockito.when(plcConnection.isConnected()).thenReturn(true);
+        plcConnectionManager.getConnection(TEST_STRING);
+        plcConnectionManager.returnConnection(TEST_STRING);
+        plcConnectionManager.getConnection(TEST_STRING);
+    }
+
+    @Test
+    @Category(FastTests.class)
+    public void closeConnections() {
+        plcConnectionManager.close();
+    }
+}
\ No newline at end of file
diff --git a/plc4j/core/src/test/java/org/apache/plc4x/java/connectionpool/PlcConnectionProxyTest.java b/plc4j/core/src/test/java/org/apache/plc4x/java/connectionpool/PlcConnectionProxyTest.java
new file mode 100644
index 000000000..b69668dd1
--- /dev/null
+++ b/plc4j/core/src/test/java/org/apache/plc4x/java/connectionpool/PlcConnectionProxyTest.java
@@ -0,0 +1,74 @@
+/*
+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.connectionpool;
+
+import org.apache.plc4x.java.api.connection.PlcConnection;
+import org.junit.After;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+
+public class PlcConnectionProxyTest {
+
+    private final String TEST_STRING = "s7:127.0.0.100";
+    private PlcConnectionManager connectionManager = Mockito.mock(PlcConnectionManager.class);
+    private PlcConnection plcConnection = Mockito.mock(PlcConnection.class);
+    private PlcConnectionProxy plcConnectionProxy = new PlcConnectionProxy(connectionManager, TEST_STRING, plcConnection);
+
+    @After
+    public void shutDown() throws Exception {
+        plcConnection.close();
+    }
+
+    @Test
+    public void connect() throws Exception {
+        plcConnectionProxy.connect();
+        Mockito.verify(plcConnection, Mockito.times(0)).connect();
+    }
+
+    @Test
+    public void isConnected() {
+        plcConnectionProxy.isConnected();
+        Mockito.verify(plcConnection, Mockito.times(1)).isConnected();
+    }
+
+    @Test
+    public void close() {
+        plcConnectionProxy.close();
+        Mockito.verify(connectionManager, Mockito.times(1)).returnConnection(TEST_STRING);
+    }
+
+    @Test
+    public void getReader() {
+        plcConnectionProxy.getReader();
+        Mockito.verify(plcConnection, Mockito.times(1)).getReader();
+    }
+
+    @Test
+    public void getWriter() {
+        plcConnectionProxy.getWriter();
+        Mockito.verify(plcConnection, Mockito.times(1)).getWriter();
+    }
+
+    @Test
+    public void getSubscriber() {
+        plcConnectionProxy.getSubscriber();
+        Mockito.verify(plcConnection, Mockito.times(1)).getSubscriber();
+    }
+}
\ No newline at end of file


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services