001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *  http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.directory.shared.client.api;
020
021
022import java.io.IOException;
023import java.util.HashMap;
024import java.util.Map;
025
026import org.apache.directory.api.ldap.codec.api.SchemaBinaryAttributeDetector;
027import org.apache.directory.api.ldap.model.exception.LdapException;
028import org.apache.directory.api.util.Network;
029import org.apache.directory.ldap.client.api.DefaultPoolableLdapConnectionFactory;
030import org.apache.directory.ldap.client.api.LdapConnection;
031import org.apache.directory.ldap.client.api.LdapConnectionConfig;
032import org.apache.directory.ldap.client.api.LdapConnectionPool;
033import org.apache.directory.ldap.client.api.LdapNetworkConnection;
034import org.apache.directory.server.constants.ServerDNConstants;
035import org.apache.directory.server.ldap.LdapServer;
036
037
038/**
039 * The Class LdapApiIntegrationUtils.
040 */
041public final class LdapApiIntegrationUtils
042{
043    /** The Constant DEFAULT_HOST. */
044    private static final String DEFAULT_HOST = "localhost";
045
046    /** The Constant DEFAULT_ADMIN. */
047    private static final String DEFAULT_ADMIN = ServerDNConstants.ADMIN_SYSTEM_DN;
048
049    /** The Constant DEFAULT_PASSWORD. */
050    private static final String DEFAULT_PASSWORD = "secret";
051
052    /** The pools. */
053    private static final Map<Integer, LdapConnectionPool> POOLS = new HashMap<>();
054
055
056    private LdapApiIntegrationUtils()
057    {
058    }
059
060
061    /**
062     * Creates a new {@link LdapNetworkConnection} and authenticates as admin user.
063     * The caller is responsible for closing the connection, use closeConnection().
064     *
065     * @param ldapServer the LDAP server instance, used to obtain the port used
066     * @return the created connection
067     * @throws LdapException the LDAP exception
068     */
069    public static LdapNetworkConnection createAdminConnection( LdapServer ldapServer ) throws LdapException
070    {
071        LdapNetworkConnection conn = new LdapNetworkConnection( Network.LOOPBACK_HOSTNAME, ldapServer.getPort() );
072        conn.bind( DEFAULT_ADMIN, DEFAULT_PASSWORD );
073        
074        return conn;
075    }
076
077
078    /**
079     * Closes the {@link LdapNetworkConnection}.
080     *
081     * @param conn the connection to close
082     * @throws LdapException the LDAP exception
083     * @throws IOException Signals that an I/O exception has occurred.
084     */
085    public static void closeConnection( LdapNetworkConnection conn ) throws LdapException, IOException
086    {
087        if ( conn != null )
088        {
089            conn.unBind();
090            conn.close();
091        }
092    }
093
094
095    /**
096     * Gets the pooled {@link LdapConnectionPool}, authenticated as admin user.
097     * The caller is reponsible for releasing the connection, use releasePooledConnection().
098     *
099     * @param ldapServer the LDAP server instance, used to obtain the port used
100     * @return the pooled admin connection
101     * @throws LdapException the exception
102     */
103    public static LdapConnection getPooledAdminConnection( LdapServer ldapServer ) throws LdapException
104    {
105        LdapConnection ldapConnection = getAdminPool( ldapServer ).getConnection();
106
107        ldapConnection.setBinaryAttributeDetector(
108            new SchemaBinaryAttributeDetector(
109                ldapServer.getDirectoryService().getSchemaManager() ) );
110
111        return ldapConnection;
112    }
113
114
115    /**
116     * Releases a pooled connection back to the pool.
117     *
118     * @param conn the connection to release
119     * @param ldapServer the LDAP server instance, used to obtain the port used
120     * @throws LdapException the exception
121     */
122    public static void releasePooledAdminConnection( LdapConnection conn, LdapServer ldapServer )
123        throws LdapException
124    {
125        getAdminPool( ldapServer ).releaseConnection( conn );
126    }
127
128
129    /**
130     * Gets the admin pool.
131     *
132     * @param ldapServer the ldap server
133     * @return the admin pool
134     */
135    private static LdapConnectionPool getAdminPool( LdapServer ldapServer )
136    {
137        int port = ldapServer.getPort();
138
139        if ( !POOLS.containsKey( port ) )
140        {
141            LdapConnectionConfig config = new LdapConnectionConfig();
142            config.setLdapHost( Network.LOOPBACK_HOSTNAME );
143            config.setLdapPort( port );
144            config.setName( DEFAULT_ADMIN );
145            config.setCredentials( DEFAULT_PASSWORD );
146            DefaultPoolableLdapConnectionFactory factory = new DefaultPoolableLdapConnectionFactory( config );
147            LdapConnectionPool pool = new LdapConnectionPool( factory );
148            pool.setTestOnBorrow( true );
149            POOLS.put( port, pool );
150        }
151
152        return POOLS.get( port );
153    }
154
155
156    /**
157     * Gets an anonymous LdapNetworkConnection
158     * 
159     * @param host The server to connect to
160     * @param port The port to connect with
161     * @return A LdapNetworkConnection instance
162     * @exception LdapException If the connection could not be established.
163     */
164    public static LdapConnection getAnonymousNetworkConnection( String host, int port ) throws LdapException
165    {
166        LdapConnection connection = new LdapNetworkConnection( host, port );
167        connection.bind();
168
169        return connection;
170    }
171
172
173    /**
174     * Gets an anonymous LdapNetworkConnection
175     * 
176     * @param ldapServer The LDAP server we want to connect to
177     * @return A LdapNetworkConnection instance
178     * @exception LdapException If the connection could not be established.
179     */
180    public static LdapConnection getAnonymousNetworkConnection( LdapServer ldapServer ) throws LdapException
181    {
182        LdapConnection connection = new LdapNetworkConnection( Network.LOOPBACK_HOSTNAME, ldapServer.getPort() );
183        connection.bind();
184
185        return connection;
186    }
187}