This is an automated email from the ASF dual-hosted git repository. sruehl pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git
The following commit(s) were added to refs/heads/master by this push: new 08dd73e [plc4j-pool] invalidating proxy after returning it to the pool. 08dd73e is described below commit 08dd73ee27e785537fe1710fed8314b18c05f0f0 Author: Sebastian Rühl <sru...@apache.org> AuthorDate: Fri Oct 26 15:42:54 2018 +0200 [plc4j-pool] invalidating proxy after returning it to the pool. --- .../connectionpool/PooledPlcDriverManager.java | 13 +++++++++---- .../connectionpool/PooledPlcDriverManagerTest.java | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/plc4j/utils/connection-pool/src/main/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManager.java b/plc4j/utils/connection-pool/src/main/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManager.java index 6f91165..a266ddb 100644 --- a/plc4j/utils/connection-pool/src/main/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManager.java +++ b/plc4j/utils/connection-pool/src/main/java/org/apache/plc4x/java/utils/connectionpool/PooledPlcDriverManager.java @@ -30,6 +30,7 @@ import java.lang.reflect.Proxy; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -83,15 +84,19 @@ public class PooledPlcDriverManager extends PlcDriverManager { } } PlcConnection plcConnection = pool.borrowObject(); - // TODO 25-10-2018 jf: Return a real wrapper object. This implementation leaks the connection. - // The connection can be reused by the pool but is still referenced and can thus still be used. - return (PlcConnection) Proxy.newProxyInstance(classLoader, new Class[]{PlcConnection.class}, (o, method, objects) -> { + // Used to invalidate a proxy + AtomicBoolean proxyInvalidated = new AtomicBoolean(false); + return (PlcConnection) Proxy.newProxyInstance(classLoader, new Class[]{PlcConnection.class}, (proxy, method, args) -> { + if (proxyInvalidated.get()) { + throw new IllegalStateException("Proxy not valid anymore"); + } if ("close".equals(method.getName())) { LOGGER.debug("close called on {}. Returning to {}", plcConnection, pool); + proxyInvalidated.set(true); pool.returnObject(plcConnection); return null; } else { - return method.invoke(plcConnection, objects); + return method.invoke(plcConnection, args); } }); } catch (Exception e) { 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 6b8b91a..724daf1 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 @@ -199,6 +199,27 @@ class PooledPlcDriverManagerTest implements WithAssertions { ); } + @Test + void connectionInvalidation() throws Exception { + when(plcDriver.connect(anyString())).then(invocationOnMock -> new DummyPlcConnection(invocationOnMock.getArgument(0))); + + PlcConnection connection = SUT.getConnection("dummydummy:single/socket1/socket2?fancyOption=true"); + assertThat(connection.isConnected()).isEqualTo(true); + assertThat(connection.getMetadata().canRead()).isEqualTo(false); + assertThat(connection.getMetadata().canWrite()).isEqualTo(false); + assertThat(connection.getMetadata().canSubscribe()).isEqualTo(false); + + connection.close(); + assertThatThrownBy(connection::connect).isInstanceOf(IllegalStateException.class).hasMessage("Proxy not valid anymore"); + assertThatThrownBy(connection::isConnected).isInstanceOf(IllegalStateException.class).hasMessage("Proxy not valid anymore"); + assertThatThrownBy(connection::close).isInstanceOf(IllegalStateException.class).hasMessage("Proxy not valid anymore"); + assertThatThrownBy(connection::getMetadata).isInstanceOf(IllegalStateException.class).hasMessage("Proxy not valid anymore"); + assertThatThrownBy(connection::readRequestBuilder).isInstanceOf(IllegalStateException.class).hasMessage("Proxy not valid anymore"); + assertThatThrownBy(connection::writeRequestBuilder).isInstanceOf(IllegalStateException.class).hasMessage("Proxy not valid anymore"); + assertThatThrownBy(connection::subscriptionRequestBuilder).isInstanceOf(IllegalStateException.class).hasMessage("Proxy not valid anymore"); + assertThatThrownBy(connection::unsubscriptionRequestBuilder).isInstanceOf(IllegalStateException.class).hasMessage("Proxy not valid anymore"); + } + class DummyPlcConnection implements PlcConnection, PlcConnectionMetadata { private final String url;