Author: ate
Date: Thu Feb 8 08:36:52 2007
New Revision: 504946
URL: http://svn.apache.org/viewvc?view=rev&rev=504946
Log:
JS2-575: A proxy based solution for lost ldap connections.
The LdapContextProxy will automatically try to reconnect and retry a failed
operation when the connection was broken.
Note: this is a different solution as proposed by Eivinn Hustveit (see
JS2-575), but much less intrusive.
Added:
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapContextProxy.java
(with props)
Modified:
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/AbstractLdapDao.java
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapBindingConfig.java
Modified:
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/AbstractLdapDao.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/AbstractLdapDao.java?view=diff&rev=504946&r1=504945&r2=504946
==============================================================================
---
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/AbstractLdapDao.java
(original)
+++
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/AbstractLdapDao.java
Thu Feb 8 08:36:52 2007
@@ -14,9 +14,6 @@
*/
package org.apache.jetspeed.security.spi.impl.ldap;
-import java.util.Properties;
-
-import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
@@ -24,7 +21,6 @@
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
-import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import org.apache.commons.lang.StringUtils;
@@ -89,31 +85,12 @@
*/
protected void bindToServer(String rootDn, String rootPassword) throws
SecurityException
{
- validateDn(rootDn);
- validatePassword(rootPassword);
-
- try
+ if ( ctx == null )
{
- Properties env = new Properties();
- env.put(Context.INITIAL_CONTEXT_FACTORY,
this.ldapBindingConfig.getInitialContextFactory());
- env.put(Context.PROVIDER_URL,
this.ldapBindingConfig.getLdapScheme() + "://" +
this.ldapBindingConfig.getLdapServerName() + ":"
- + this.ldapBindingConfig.getLdapServerPort() + "/" +
this.ldapBindingConfig.getRootContext());
- env.put(Context.SECURITY_PRINCIPAL, rootDn);
- env.put(Context.SECURITY_CREDENTIALS, rootPassword);
- env.put(Context.SECURITY_AUTHENTICATION,
this.ldapBindingConfig.getLdapSecurityLevel());
- if (
!StringUtils.isEmpty(this.ldapBindingConfig.getLdapSecurityProtocol()) )
- {
- env.put(Context.SECURITY_PROTOCOL,
this.ldapBindingConfig.getLdapSecurityProtocol());
- }
- if (
!StringUtils.isEmpty(this.ldapBindingConfig.getLdapSocketFactory()) )
- {
- env.put("java.naming.ldap.factory.socket",
this.ldapBindingConfig.getLdapSocketFactory());
- }
- ctx = new InitialLdapContext(env, null);
- }
- catch (NamingException ne)
- {
- throw new SecurityException(ne);
+ validateDn(rootDn);
+ validatePassword(rootPassword);
+
+ ctx = LdapContextProxy.createProxy(ldapBindingConfig);
}
}
Modified:
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapBindingConfig.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapBindingConfig.java?view=diff&rev=504946&r1=504945&r2=504946
==============================================================================
---
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapBindingConfig.java
(original)
+++
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapBindingConfig.java
Thu Feb 8 08:36:52 2007
@@ -14,6 +14,8 @@
*/
package org.apache.jetspeed.security.spi.impl.ldap;
+import javax.naming.ldap.LdapContext;
+
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.lang.StringUtils;
@@ -31,6 +33,8 @@
{
/** The logger. */
private static final Log logger =
LogFactory.getLog(LdapBindingConfig.class);
+
+ private LdapContext context;
private String initialContextFactory;
private String ldapSocketFactory;
@@ -256,6 +260,16 @@
{
logger.error("Could not configure LdapBindingConfig: " + ce);
}
+ }
+
+ LdapContext getContext()
+ {
+ return context;
+ }
+
+ void setContext(LdapContext context)
+ {
+ this.context = context;
}
/**
Added:
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapContextProxy.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapContextProxy.java?view=auto&rev=504946
==============================================================================
---
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapContextProxy.java
(added)
+++
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapContextProxy.java
Thu Feb 8 08:36:52 2007
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.jetspeed.security.spi.impl.ldap;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Properties;
+
+import javax.naming.CommunicationException;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.ServiceUnavailableException;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Proxy providing recoverable LdapContext connections.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma</a>
+ * @version $Id$
+ */
+public class LdapContextProxy implements InvocationHandler
+{
+ private Properties env;
+ private LdapContext ctx;
+
+ public static LdapContext createProxy(LdapBindingConfig config)
+ {
+ LdapContext proxy = config.getContext();
+
+ if ( proxy == null || !(Proxy.getInvocationHandler(proxy) instanceof
LdapContextProxy))
+ {
+ proxy =
(LdapContext)Proxy.newProxyInstance(LdapContext.class.getClassLoader(),new
Class[]{LdapContext.class}, new LdapContextProxy(config));
+ config.setContext(proxy);
+ }
+ return proxy;
+ }
+
+ private LdapContextProxy(LdapBindingConfig ldapBindingConfig)
+ {
+ env = new Properties();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
ldapBindingConfig.getInitialContextFactory());
+ env.put(Context.PROVIDER_URL, ldapBindingConfig.getLdapScheme() +
"://" + ldapBindingConfig.getLdapServerName() + ":"
+ + ldapBindingConfig.getLdapServerPort() + "/" +
ldapBindingConfig.getRootContext());
+ env.put(Context.SECURITY_PRINCIPAL, ldapBindingConfig.getRootDn());
+ env.put(Context.SECURITY_CREDENTIALS,
ldapBindingConfig.getRootPassword());
+ env.put(Context.SECURITY_AUTHENTICATION,
ldapBindingConfig.getLdapSecurityLevel());
+ if ( !StringUtils.isEmpty(ldapBindingConfig.getLdapSecurityProtocol())
)
+ {
+ env.put(Context.SECURITY_PROTOCOL,
ldapBindingConfig.getLdapSecurityProtocol());
+ }
+ if ( !StringUtils.isEmpty(ldapBindingConfig.getLdapSocketFactory()) )
+ {
+ env.put("java.naming.ldap.factory.socket",
ldapBindingConfig.getLdapSocketFactory());
+ }
+ }
+
+ private LdapContext getCtx() throws NamingException
+ {
+ if ( ctx == null )
+ {
+ ctx = new InitialLdapContext(env, null);
+ }
+ return ctx;
+ }
+
+ private void closeCtx()
+ {
+ if ( ctx != null )
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (Exception e)
+ {
+ }
+ ctx = null;
+ }
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
+ * java.lang.reflect.Method, java.lang.Object[])
+ */
+ public synchronized Object invoke(Object proxy, Method m, Object[] args)
throws Throwable
+ {
+ Object result = null;
+ boolean close = "close".equals(m.getName()) && args.length == 0;
+ if ( close && ctx == null )
+ {
+ // don't need to do anything
+ ;
+ }
+ else
+ {
+ LdapContext ctx = getCtx();
+
+ try
+ {
+ result = m.invoke(ctx,args);
+ if ( close )
+ {
+ closeCtx();
+ }
+ }
+ catch (Throwable t)
+ {
+ closeCtx();
+
+ if ( t instanceof InvocationTargetException)
+ {
+ t = ((InvocationTargetException)t).getTargetException();
+ }
+ if (t instanceof ServiceUnavailableException || t instanceof
CommunicationException)
+ {
+ try
+ {
+ ctx = getCtx();
+ result = m.invoke(ctx,args);
+ }
+ catch (Throwable t2)
+ {
+ closeCtx();
+ if ( t2 instanceof InvocationTargetException)
+ {
+ t2 =
((InvocationTargetException)t2).getTargetException();
+ }
+
+ throw t2;
+ }
+ }
+ throw t;
+ }
+ }
+ return result;
+ }
+}
Propchange:
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapContextProxy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/ldap/LdapContextProxy.java
------------------------------------------------------------------------------
svn:keywords = Id
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]