You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/01/13 09:20:57 UTC

svn commit: r368632 - in /directory/trunks: apacheds-core-unit/src/test/java/org/apache/ldap/server/jndi/ apacheds/src/main/java/org/apache/ldap/server/configuration/ apacheds/src/main/java/org/apache/ldap/server/referral/

Author: akarasulu
Date: Fri Jan 13 00:20:50 2006
New Revision: 368632

URL: http://svn.apache.org/viewcvs?rev=368632&view=rev
Log:
got referrals working for the add operation

Added:
    directory/trunks/apacheds-core-unit/src/test/java/org/apache/ldap/server/jndi/ReferralTest.java   (with props)
Modified:
    directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java
    directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java

Added: directory/trunks/apacheds-core-unit/src/test/java/org/apache/ldap/server/jndi/ReferralTest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds-core-unit/src/test/java/org/apache/ldap/server/jndi/ReferralTest.java?rev=368632&view=auto
==============================================================================
--- directory/trunks/apacheds-core-unit/src/test/java/org/apache/ldap/server/jndi/ReferralTest.java (added)
+++ directory/trunks/apacheds-core-unit/src/test/java/org/apache/ldap/server/jndi/ReferralTest.java Fri Jan 13 00:20:50 2006
@@ -0,0 +1,255 @@
+/*
+ *   Copyright 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.ldap.server.jndi;
+
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.ReferralException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.ldap.server.unit.AbstractAdminTestCase;
+
+
+/**
+ * Tests the referral handling functionality within the server's core.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ReferralTest extends AbstractAdminTestCase
+{
+    private static final boolean SUNJNDI = false;
+    private boolean sunjndi = System.getProperty( "sunjndi" ) != null || SUNJNDI;
+    
+    
+    public void setUp() throws Exception
+    {
+        if ( ! sunjndi )
+        {
+            super.setUp();
+        }
+    }
+    
+    
+    public void tearDown() throws Exception
+    {
+        if ( ! sunjndi )
+        {
+            super.tearDown();
+        }
+    }
+
+    /*
+     * NOTE: We may encounter conflicting circumstances where the ManageDsaIT control
+     * is included in the request controls yet the Context.REFERRAL is set to 
+     * something other than ignore: throw or follow.  We have to figure out what to
+     * do in these cases.
+     * 
+     * Simply throw an illegal state exception when this happens?
+     * 
+     * NOTE: Need to figure out the behavoir of referral handling during search
+     * when aliases are being dereferenced.
+     */
+
+    /**
+     * Get's the root "ou=system" in either the embedded instance or an
+     * external instance.  We do this to mold test cases to make sure the 
+     * ApacheDS JNDI LDAP provider behaves just like the SUN JNDI LDAP
+     * provider does.
+     */
+    private LdapContext getSystemRoot() throws NamingException
+    {
+        if ( ! sunjndi )
+        {
+            return sysRoot;
+        }
+        
+        Hashtable env = new Hashtable();
+        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
+        env.put( "java.naming.provider.url", "ldap://hertz.karasulu.homeip.net:10390/ou=system" );
+        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
+        env.put( "java.naming.security.credentials", "longsecret" );
+        env.put( "java.naming.security.authentication", "simple" );
+        return new InitialLdapContext( env, null );
+    }
+    
+    
+    /**
+     * Checks for correct core behavoir when Context.REFERRAL is set to <b>throw</b>
+     * for an add operation with the parent context being a referral.
+     * 
+     * @throws Exception if something goes wrong.
+     */
+    public void testAddWithReferralParent() throws Exception
+    {
+        String ref0 = "ldap://fermi:10389/ou=users,ou=system";
+        String ref1 = "ldap://hertz:10389/ou=users,dc=example,dc=com";
+        String ref2 = "ldap://maxwell:10389/ou=users,ou=system";
+        LdapContext root = getSystemRoot();
+        LdapContext refctx = null;
+
+        // -------------------------------------------------------------------
+        // Adds a referral entry regardless of referral handling settings
+        // -------------------------------------------------------------------
+        
+        // Add a referral entry ( should be fine with or without the control )
+        Attributes referral = new BasicAttributes( "objectClass", "top", true );
+        referral.get( "objectClass" ).add( "referral" );
+        referral.get( "objectClass" ).add( "extensibleObject" );
+        referral.put( "ref", ref0 );
+        referral.get( "ref" ).add( ref1 );
+        referral.get( "ref" ).add( ref2 );
+        referral.put( "ou", "users" );
+
+        // Just in case if server is a remote server destroy remaing referral
+        root.addToEnvironment( Context.REFERRAL, "ignore" );
+        try { root.destroySubcontext( "uid=akarasulu,ou=users" ); } catch( NameNotFoundException e ) { e.printStackTrace(); }
+        try { root.destroySubcontext( "ou=users" ); } catch( NameNotFoundException e ) { e.printStackTrace(); }
+        try
+        {
+            refctx = ( LdapContext ) root.createSubcontext( "ou=users", referral );
+        }
+        catch( NameAlreadyBoundException e )
+        {
+            refctx = ( LdapContext ) root.lookup( "ou=users" );
+        }
+        referral = refctx.getAttributes( "" );
+        assertTrue( referral.get( "ou" ).contains( "users" ) );
+        assertTrue( referral.get( "objectClass" ).contains( "referral" ) );
+
+        // -------------------------------------------------------------------
+        // Attempt to add a normal entry below the referral parent. We should
+        // encounter referral errors with referral setting set to throw.
+        // -------------------------------------------------------------------
+        
+        // attempt to add another entry below the referral entry but now throw and exception
+        refctx.addToEnvironment( Context.REFERRAL, "throw" );
+        Attributes userEntry = new BasicAttributes( "objectClass", "top", true );
+        userEntry.get( "objectClass" ).add( "person" );
+        userEntry.put( "sn", "karasulu" );
+        userEntry.put( "cn", "alex karasulu" );
+
+        //try { refctx.destroySubcontext( "cn=Alex Karasulu" ); } catch( NameNotFoundException e ) {}
+        try 
+        {
+            refctx.createSubcontext( "cn=alex karasulu", userEntry );
+            fail( "Should fail here throwing a ReferralException" );
+        }
+        catch( ReferralException e )
+        {
+            assertEquals( "ldap://fermi:10389", e.getReferralInfo() );
+            assertTrue( e.skipReferral() );
+            assertEquals( "ldap://hertz:10389/cn=alex karasulu,ou=users,dc=example,dc=com", e.getReferralInfo() );
+            assertTrue( e.skipReferral() );
+            assertEquals( "ldap://maxwell:10389", e.getReferralInfo() );
+            assertFalse( e.skipReferral() );
+        }
+        refctx.close();
+        
+        if ( sunjndi )
+        {
+            root.close();
+        }
+    }
+    
+    
+    /**
+     * Checks for correct core behavoir when Context.REFERRAL is set to <b>throw</b>
+     * for an add operation with an ancestor context being a referral.
+     * 
+     * @throws Exception if something goes wrong.
+     */
+    public void testAddWithReferralAncestor() throws Exception
+    {
+        String ref0 = "ldap://fermi:10389/ou=users,ou=system";
+        String ref1 = "ldap://hertz:10389/ou=users,dc=example,dc=com";
+        String ref2 = "ldap://maxwell:10389/ou=users,ou=system";
+        LdapContext root = getSystemRoot();
+        LdapContext refctx = null;
+
+        // -------------------------------------------------------------------
+        // Adds a referral entry regardless of referral handling settings
+        // -------------------------------------------------------------------
+        
+        // Add a referral entry ( should be fine with or without the control )
+        Attributes referral = new BasicAttributes( "objectClass", "top", true );
+        referral.get( "objectClass" ).add( "referral" );
+        referral.get( "objectClass" ).add( "extensibleObject" );
+        referral.put( "ref", ref0 );
+        referral.get( "ref" ).add( ref1 );
+        referral.get( "ref" ).add( ref2 );
+        referral.put( "ou", "users" );
+
+        // Just in case if server is a remote server destroy remaing referral
+        root.addToEnvironment( Context.REFERRAL, "ignore" );
+        try { root.destroySubcontext( "uid=akarasulu,ou=users" ); } catch( NameNotFoundException e ) { e.printStackTrace(); }
+        try { root.destroySubcontext( "ou=users" ); } catch( NameNotFoundException e ) { e.printStackTrace(); }
+        try
+        {
+            refctx = ( LdapContext ) root.createSubcontext( "ou=users", referral );
+        }
+        catch( NameAlreadyBoundException e )
+        {
+            refctx = ( LdapContext ) root.lookup( "ou=users" );
+        }
+        referral = refctx.getAttributes( "" );
+        assertTrue( referral.get( "ou" ).contains( "users" ) );
+        assertTrue( referral.get( "objectClass" ).contains( "referral" ) );
+
+        // -------------------------------------------------------------------
+        // Attempt to add a normal entry below the referral ancestor. We should
+        // encounter referral errors with referral setting set to throw.
+        // -------------------------------------------------------------------
+        
+        // attempt to add another entry below the referral entry but now throw and exception
+        refctx.addToEnvironment( Context.REFERRAL, "throw" );
+        Attributes userEntry = new BasicAttributes( "objectClass", "top", true );
+        userEntry.get( "objectClass" ).add( "person" );
+        userEntry.put( "sn", "karasulu" );
+        userEntry.put( "cn", "alex karasulu" );
+
+        try 
+        {
+            refctx.createSubcontext( "cn=alex karasulu,ou=apache", userEntry );
+            fail( "Should fail here throwing a ReferralException" );
+        }
+        catch( ReferralException e )
+        {
+            assertEquals( "ldap://fermi:10389", e.getReferralInfo() );
+            assertTrue( e.skipReferral() );
+            assertEquals( "ldap://hertz:10389/cn=alex karasulu,ou=apache,ou=users,dc=example,dc=com", 
+                e.getReferralInfo() );
+            assertTrue( e.skipReferral() );
+            assertEquals( "ldap://maxwell:10389", e.getReferralInfo() );
+            assertFalse( e.skipReferral() );
+        }
+        refctx.close();
+        
+        if ( sunjndi )
+        {
+            root.close();
+        }
+    }
+}

Propchange: directory/trunks/apacheds-core-unit/src/test/java/org/apache/ldap/server/jndi/ReferralTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java?rev=368632&r1=368631&r2=368632&view=diff
==============================================================================
--- directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java (original)
+++ directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java Fri Jan 13 00:20:50 2006
@@ -153,6 +153,11 @@
         list.add( interceptorCfg );
 
         interceptorCfg = new MutableInterceptorConfiguration();
+        interceptorCfg.setName( "referralService" );
+        interceptorCfg.setInterceptor( new ReferralService() );
+        list.add( interceptorCfg );
+
+        interceptorCfg = new MutableInterceptorConfiguration();
         interceptorCfg.setName( "exceptionService" );
         interceptorCfg.setInterceptor( new ExceptionService() );
         list.add( interceptorCfg );
@@ -160,11 +165,6 @@
         interceptorCfg = new MutableInterceptorConfiguration();
         interceptorCfg.setName( "schemaService" );
         interceptorCfg.setInterceptor( new SchemaService() );
-        list.add( interceptorCfg );
-
-        interceptorCfg = new MutableInterceptorConfiguration();
-        interceptorCfg.setName( "referralService" );
-        interceptorCfg.setInterceptor( new ReferralService() );
         list.add( interceptorCfg );
         
         interceptorCfg = new MutableInterceptorConfiguration();

Modified: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java?rev=368632&r1=368631&r2=368632&view=diff
==============================================================================
--- directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java (original)
+++ directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java Fri Jan 13 00:20:50 2006
@@ -223,7 +223,16 @@
                 if ( urlDn.equals( farthest ) )
                 {
                     // according to the protocol there is no need for the dn since it is the same as this request
-                    list.add( ldapUrl.getScheme() + "://" + ldapUrl.getHost() );
+                    StringBuffer buf = new StringBuffer();
+                    buf.append( ldapUrl.getScheme() );
+                    buf.append( ldapUrl.getHost() );
+                    if ( ldapUrl.getPort() > 0 )
+                    {
+                        buf.append( ":" );
+                        buf.append( ldapUrl.getPort() );
+                    }
+                    
+                    list.add( buf.toString() );
                     continue;
                 }
                 
@@ -241,9 +250,22 @@
                 }
 
                 urlDn.addAll( extra );
-                list.add( ldapUrl.getScheme() + "://" + ldapUrl.getHost() + "/" + urlDn );
+                
+                
+                
+                StringBuffer buf = new StringBuffer();
+                buf.append( ldapUrl.getScheme() );
+                buf.append( ldapUrl.getHost() );
+                if ( ldapUrl.getPort() > 0 )
+                {
+                    buf.append( ":" );
+                    buf.append( ldapUrl.getPort() );
+                }
+                buf.append( "/" );
+                buf.append( urlDn );
+                list.add( buf.toString() );
             }
-            LdapReferralException lre = new LdapReferralException( getRefs( referral ) );
+            LdapReferralException lre = new LdapReferralException( list );
             throw lre;
         }
         else if ( refval.equals( FOLLOW ) )
@@ -255,18 +277,6 @@
             throw new LdapNamingException( "Undefined value for " + Context.REFERRAL  + " key: " 
                 + refval, ResultCodeEnum.OTHER );
         }
-    }
-
-    
-    static List getRefs( Attributes referral ) throws NamingException
-    {
-        Attribute ref = referral.get( REF_ATTR );
-        List list = new ArrayList( ref.size() );
-        for ( int ii = 0; ii < ref.size(); ii++ )
-        {
-            list.add( ref.get( ii ) );
-        }
-        return list;
     }