From 7057e430ce059963724928296ff166e68b4e2ebb Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 09 Apr 2013 09:58:22 +0000
Subject: [PATCH] Partial fix for OPENDJ-856: Make Rest2LDAP close the cached authenticated connection
---
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnectionWrapper.java | 53 +++++++----------
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java | 3
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java | 26 ++++++++
opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionsTestCase.java | 60 ++++++++++++++++++++
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java | 3
5 files changed, 109 insertions(+), 36 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnectionWrapper.java
similarity index 93%
rename from opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java
rename to opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnectionWrapper.java
index e865863..5de8c93 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnectionWrapper.java
@@ -25,21 +25,10 @@
* Portions copyright 2011-2013 ForgeRock AS
*/
-package com.forgerock.opendj.util;
+package org.forgerock.opendj.ldap;
import java.util.Collection;
-import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.Connection;
-import org.forgerock.opendj.ldap.ConnectionEventListener;
-import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.Entry;
-import org.forgerock.opendj.ldap.ErrorResultException;
-import org.forgerock.opendj.ldap.FutureResult;
-import org.forgerock.opendj.ldap.IntermediateResponseHandler;
-import org.forgerock.opendj.ldap.ResultHandler;
-import org.forgerock.opendj.ldap.SearchResultHandler;
-import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.requests.AbandonRequest;
import org.forgerock.opendj.ldap.requests.AddRequest;
import org.forgerock.opendj.ldap.requests.BindRequest;
@@ -60,24 +49,26 @@
import org.forgerock.opendj.ldif.ChangeRecord;
import org.forgerock.opendj.ldif.ConnectionEntryReader;
+import com.forgerock.opendj.util.Validator;
+
/**
- * A base class from which connection decorators may be easily implemented. The
- * default implementation of each method is to delegate to the decorated
- * connection.
+ * An abstract base class from which connection wrappers may be easily
+ * implemented. The default implementation of each method is to delegate to the
+ * wrapped connection.
*/
-public abstract class ConnectionDecorator implements Connection {
+public abstract class AbstractConnectionWrapper implements Connection {
/**
- * The decorated connection.
+ * The wrapped connection.
*/
protected final Connection connection;
/**
- * Creates a new connection decorator.
+ * Creates a new connection wrapper.
*
* @param connection
- * The connection to be decorated.
+ * The connection to be wrapped.
*/
- protected ConnectionDecorator(final Connection connection) {
+ protected AbstractConnectionWrapper(final Connection connection) {
Validator.ensureNotNull(connection);
this.connection = connection;
}
@@ -140,7 +131,17 @@
* The default implementation is to delegate.
*/
@Override
- public Result applyChange(ChangeRecord request) throws ErrorResultException {
+ public void addConnectionEventListener(final ConnectionEventListener listener) {
+ connection.addConnectionEventListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ @Override
+ public Result applyChange(final ChangeRecord request) throws ErrorResultException {
return connection.applyChange(request);
}
@@ -162,16 +163,6 @@
* The default implementation is to delegate.
*/
@Override
- public void addConnectionEventListener(final ConnectionEventListener listener) {
- connection.addConnectionEventListener(listener);
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * The default implementation is to delegate.
- */
- @Override
public BindResult bind(final BindRequest request) throws ErrorResultException {
return connection.bind(request);
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java
index e90c986..f4962ab 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java
@@ -30,7 +30,6 @@
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.responses.BindResult;
-import com.forgerock.opendj.util.ConnectionDecorator;
import com.forgerock.opendj.util.FutureResultTransformer;
import com.forgerock.opendj.util.RecursiveFutureResult;
@@ -52,7 +51,7 @@
* An authenticated connection supports all operations except Bind
* operations.
*/
- public static final class AuthenticatedConnection extends ConnectionDecorator {
+ public static final class AuthenticatedConnection extends AbstractConnectionWrapper {
private AuthenticatedConnection(final Connection connection) {
super(connection);
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
index 6d5a0e5..deea05a 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2009-2010 Sun Microsystems, Inc.
- * Portions copyright 2011-2012 ForgeRock AS
+ * Portions copyright 2011-2013 ForgeRock AS
*/
package org.forgerock.opendj.ldap;
@@ -472,6 +472,30 @@
return new RequestHandlerFactoryAdapter<C>(factory);
}
+ /**
+ * Returns an uncloseable view of the provided connection. Attempts to call
+ * {@link Connection#close()} or
+ * {@link Connection#close(org.forgerock.opendj.ldap.requests.UnbindRequest, String)}
+ * will be ignored.
+ *
+ * @param connection
+ * The connection whose {@code close} methods are to be disabled.
+ * @return An uncloseable view of the provided connection.
+ */
+ public static Connection uncloseable(Connection connection) {
+ return new AbstractConnectionWrapper(connection) {
+ @Override
+ public void close() {
+ // Do nothing.
+ }
+
+ public void close(org.forgerock.opendj.ldap.requests.UnbindRequest request,
+ String reason) {
+ // Do nothing.
+ };
+ };
+ }
+
// Prevent instantiation.
private Connections() {
// Do nothing.
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
index 10e018f..9f73c51 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
@@ -63,7 +63,6 @@
import org.forgerock.opendj.ldif.ConnectionEntryReader;
import com.forgerock.opendj.util.AsynchronousFutureResult;
-import com.forgerock.opendj.util.ConnectionDecorator;
import com.forgerock.opendj.util.FutureResultTransformer;
import com.forgerock.opendj.util.StaticUtils;
import com.forgerock.opendj.util.Validator;
@@ -76,7 +75,7 @@
/**
* A connection that sends heart beats and supports all operations.
*/
- private final class ConnectionImpl extends ConnectionDecorator implements
+ private final class ConnectionImpl extends AbstractConnectionWrapper implements
ConnectionEventListener, SearchResultHandler {
/**
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionsTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionsTestCase.java
new file mode 100644
index 0000000..ff164c2
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionsTestCase.java
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS
+ */
+package org.forgerock.opendj.ldap;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class ConnectionsTestCase extends SdkTestCase {
+
+ @Test
+ public void testUncloseableConnectionClose() throws Exception {
+ final Connection connection = mock(Connection.class);
+ final Connection uncloseable = Connections.uncloseable(connection);
+ uncloseable.close();
+ verifyZeroInteractions(connection);
+ }
+
+ @Test
+ public void testUncloseableConnectionNotClose() throws Exception {
+ final Connection connection = mock(Connection.class);
+ final Connection uncloseable = Connections.uncloseable(connection);
+ uncloseable.applyChange(null);
+ verify(connection).applyChange(null);
+ }
+
+ @Test
+ public void testUncloseableConnectionUnbind() throws Exception {
+ final Connection connection = mock(Connection.class);
+ final Connection uncloseable = Connections.uncloseable(connection);
+ uncloseable.close(null, null);
+ verifyZeroInteractions(connection);
+ }
+}
--
Gitblit v1.10.0