1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.operations.extended;
21  
22  
23  import org.apache.directory.server.core.DefaultDirectoryService;
24  import org.apache.directory.server.core.DirectoryService;
25  import org.apache.directory.server.core.integ.IntegrationUtils;
26  import org.apache.directory.server.core.integ.Level;
27  import org.apache.directory.server.core.integ.annotations.CleanupLevel;
28  import org.apache.directory.server.core.integ.annotations.Factory;
29  import org.apache.directory.server.integ.LdapServerFactory;
30  import org.apache.directory.server.integ.SiRunner;
31  import org.apache.directory.server.ldap.ExtendedOperationHandler;
32  import org.apache.directory.server.ldap.LdapService;
33  import org.apache.directory.server.ldap.handlers.bind.MechanismHandler;
34  import org.apache.directory.server.ldap.handlers.bind.SimpleMechanismHandler;
35  import org.apache.directory.server.ldap.handlers.bind.cramMD5.CramMd5MechanismHandler;
36  import org.apache.directory.server.ldap.handlers.bind.digestMD5.DigestMd5MechanismHandler;
37  import org.apache.directory.server.ldap.handlers.bind.gssapi.GssapiMechanismHandler;
38  import org.apache.directory.server.ldap.handlers.bind.ntlm.NtlmMechanismHandler;
39  import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
40  import org.apache.directory.server.protocol.shared.SocketAcceptor;
41  import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
42  import org.apache.directory.shared.ldap.schema.DeepTrimToLowerNormalizer;
43  import org.apache.directory.shared.ldap.schema.OidNormalizer;
44  import org.apache.directory.shared.ldap.sp.JavaStoredProcUtils;
45  import org.apache.mina.util.AvailablePortFinder;
46  import org.junit.Before;
47  import org.junit.Test;
48  import org.junit.runner.RunWith;
49  
50  import javax.naming.directory.Attributes;
51  import javax.naming.directory.BasicAttributes;
52  import javax.naming.ldap.InitialLdapContext;
53  import javax.naming.ldap.LdapContext;
54  
55  import java.util.HashMap;
56  import java.util.HashSet;
57  import java.util.Hashtable;
58  import java.util.Map;
59  import java.util.Set;
60  
61  import static org.junit.Assert.assertEquals;
62  import static org.junit.Assert.assertNotNull;
63  
64  
65  /**
66   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
67   * @version $Rev:$
68   */
69  @RunWith ( SiRunner.class ) 
70  @CleanupLevel ( Level.CLASS )
71  @Factory ( StoredProcedureIT.Factory.class )
72  public class StoredProcedureIT
73  {
74      private LdapContext ctx;
75      private LdapContext spCtx;
76      private Map<String, OidNormalizer> oids;
77  
78      
79      public static LdapService ldapService;
80  
81      
82      public static class Factory implements LdapServerFactory
83      {
84          public LdapService newInstance() throws Exception
85          {
86              DirectoryService service = new DefaultDirectoryService();
87              IntegrationUtils.doDelete( service.getWorkingDirectory() );
88              service.getChangeLog().setEnabled( true );
89              service.setShutdownHookEnabled( false );
90  
91              // change the working directory to something that is unique
92              // on the system and somewhere either under target directory
93              // or somewhere in a temp area of the machine.
94  
95              LdapService ldapService = new LdapService();
96              ldapService.setDirectoryService( service );
97              ldapService.setSocketAcceptor( new SocketAcceptor( null ) );
98              ldapService.setIpPort( AvailablePortFinder.getNextAvailable( 1024 ) );
99              ldapService.setEnabled( true );
100             ldapService.addExtendedOperationHandler( new StoredProcedureExtendedOperationHandler() );
101 
102             // Setup SASL Mechanisms
103             
104             Map<String, MechanismHandler> mechanismHandlerMap = new HashMap<String,MechanismHandler>();
105             mechanismHandlerMap.put( SupportedSaslMechanisms.PLAIN, new SimpleMechanismHandler() );
106 
107             CramMd5MechanismHandler cramMd5MechanismHandler = new CramMd5MechanismHandler();
108             mechanismHandlerMap.put( SupportedSaslMechanisms.CRAM_MD5, cramMd5MechanismHandler );
109 
110             DigestMd5MechanismHandler digestMd5MechanismHandler = new DigestMd5MechanismHandler();
111             mechanismHandlerMap.put( SupportedSaslMechanisms.DIGEST_MD5, digestMd5MechanismHandler );
112 
113             GssapiMechanismHandler gssapiMechanismHandler = new GssapiMechanismHandler();
114             mechanismHandlerMap.put( SupportedSaslMechanisms.GSSAPI, gssapiMechanismHandler );
115 
116             NtlmMechanismHandler ntlmMechanismHandler = new NtlmMechanismHandler();
117             mechanismHandlerMap.put( SupportedSaslMechanisms.NTLM, ntlmMechanismHandler );
118             mechanismHandlerMap.put( SupportedSaslMechanisms.GSS_SPNEGO, ntlmMechanismHandler );
119 
120             ldapService.setSaslMechanismHandlers( mechanismHandlerMap );
121 
122             Set<ExtendedOperationHandler> handlers = new HashSet<ExtendedOperationHandler>( ldapService.getExtendedOperationHandlers() );
123             handlers.add( new StoredProcedureExtendedOperationHandler() );
124             ldapService.setExtendedOperationHandlers( handlers );
125 
126             return ldapService;
127         }
128     }
129     
130     
131     @Before 
132     public void setUp() throws Exception
133     {
134         Hashtable<String, Object> env = new Hashtable<String, Object>();
135         env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
136         env.put( "java.naming.provider.url", "ldap://localhost:" + ldapService.getIpPort() + "/ou=system" );
137         env.put( "java.naming.security.principal", "uid=admin,ou=system" );
138         env.put( "java.naming.security.credentials", "secret" );
139         env.put( "java.naming.security.authentication", "simple" );
140         ctx = new InitialLdapContext( env, null );
141         
142         Attributes spContainer = new BasicAttributes( "objectClass", "top", true );
143         spContainer.get( "objectClass" ).add( "organizationalUnit" );
144         spContainer.put( "ou", "Stored Procedures" );
145         spCtx = ( LdapContext ) ctx.createSubcontext( "ou=Stored Procedures", spContainer );
146         assertNotNull( spCtx );
147         
148         // Initialize OIDs maps for normalization
149         oids = new HashMap<String, OidNormalizer>();
150 
151         oids.put( "ou", new OidNormalizer( "ou", new DeepTrimToLowerNormalizer() ) );
152         oids.put( "organizationalUnitName", new OidNormalizer( "ou", new DeepTrimToLowerNormalizer() ) );
153         oids.put( "2.5.4.11", new OidNormalizer( "ou", new DeepTrimToLowerNormalizer() ) );
154     }
155 
156     
157     @Test
158     public void testExecuteProcedureWithReturnValue() throws Exception
159     {
160         String procedureName = HelloWorldProcedure.class.getName() + ":sayHello";
161         JavaStoredProcUtils.loadStoredProcedureClass( spCtx, HelloWorldProcedure.class );
162         Object response = JavaStoredProcUtils.callStoredProcedure( ctx, procedureName, new Object[] { } );
163         assertEquals( "Hello World!", response );
164     }
165     
166 
167     @Test
168     public void testExecuteProcedureWithParametersAndReturnValue() throws Exception
169     {
170         String procedureName = HelloWorldProcedure.class.getName() + ":sayHelloTo";
171         JavaStoredProcUtils.loadStoredProcedureClass( spCtx, HelloWorldProcedure.class );
172         Object response = JavaStoredProcUtils.callStoredProcedure( ctx, procedureName, new Object[] { "Ersin" } );
173         assertEquals( "Hello Ersin!", response );
174     }
175     
176     
177     /*
178     @Test public void testSPDeleteSubtree() throws Exception
179     {
180         String ldif =
181             "version: 1\n" +
182             "\n" +
183             "dn: ou=People,ou=system\n" +
184             "ou: People\n" +
185             "objectclass: organizationalUnit\n" +
186             "objectclass: top\n" +
187             "\n" + 
188             "dn: cn=John,ou=People,ou=system\n" +
189             "objectclass: person\n" +
190             "objectclass: top\n" +
191             "sn: John\n" +
192             "cn: John\n" +
193             "\n" +
194             "dn: cn=Jane,ou=People,ou=system\n" +
195             "objectclass: person\n" +
196             "objectclass: top\n" +
197             "sn: Jane\n" +
198             "cn: Jane\n";
199         
200         injectEntries( ldif );
201         
202         JavaStoredProcUtils.loadStoredProcedureClass( spCtx, DITUtilitiesSP.class );
203         
204         LdapDN people = new LdapDN( "ou=People" );
205         people = LdapDN.normalize(  people, oids );
206         
207         String spName = DITUtilitiesSP.class.getName() + ":deleteSubtree";
208         Object[] params = new Object[] { new LdapContextParameter( "ou=system" ),
209                                          people };
210         
211         
212         JavaStoredProcUtils.callStoredProcedure( ctx, spName, params );
213         
214         try
215         {
216             sysRoot.lookup( "cn=Jane,ou=People" );
217             sysRoot.lookup( "cn=John,ou=People" );
218             sysRoot.lookup( "ou=People" );
219             fail( "We should not have come here." );
220         }
221         catch ( NameNotFoundException e )
222         {
223             // Expected
224         }
225     }
226     */
227 }