001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2007-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.forgerock.opendj.config.dsconfig;
018
019import static com.forgerock.opendj.dsconfig.DsconfigMessages.*;
020import static org.forgerock.util.Utils.closeSilently;
021
022import javax.net.ssl.SSLException;
023
024import org.forgerock.opendj.config.LDAPProfile;
025import org.forgerock.opendj.config.client.ManagementContext;
026import org.forgerock.opendj.config.client.ldap.LDAPManagementContext;
027import org.forgerock.opendj.config.server.ConfigException;
028import org.forgerock.opendj.ldap.Connection;
029import org.forgerock.opendj.ldap.ConnectionFactory;
030import org.forgerock.opendj.ldap.LdapException;
031
032import com.forgerock.opendj.cli.ArgumentException;
033import com.forgerock.opendj.cli.ClientException;
034import com.forgerock.opendj.cli.CommandBuilder;
035import com.forgerock.opendj.cli.ConnectionFactoryProvider;
036import com.forgerock.opendj.cli.ConsoleApplication;
037import com.forgerock.opendj.cli.ReturnCode;
038
039/**
040 * An LDAP management context factory for the DSConfig tool.
041 */
042public final class LDAPManagementContextFactory {
043
044    /** The management context. */
045    private ManagementContext context;
046
047    /** The connection parameters command builder. */
048    private CommandBuilder contextCommandBuilder;
049
050    /** The connection factory provider. */
051    private final ConnectionFactoryProvider provider;
052
053    /** The connection factory. */
054    private final ConnectionFactory factory;
055
056    /**
057     * Creates a new LDAP management context factory based on an authenticated connection factory.
058     *
059     * @param cfp
060     *            The connection factory provider which should be used in this context.
061     * @throws ArgumentException
062     *             If an exception occurs when creating the authenticated connection factory linked to this context.
063     */
064    public LDAPManagementContextFactory(ConnectionFactoryProvider cfp) throws ArgumentException {
065        this.provider = cfp;
066        factory = cfp.getAuthenticatedConnectionFactory();
067    }
068
069    /**
070     * Closes this management context.
071     */
072    public void close() {
073        closeSilently(context);
074    }
075
076    /**
077     * Returns the command builder that provides the equivalent arguments in interactive mode to get the management
078     * context.
079     *
080     * @return the command builder that provides the equivalent arguments in interactive mode to get the management
081     *         context.
082     */
083    public CommandBuilder getContextCommandBuilder() {
084        return contextCommandBuilder;
085    }
086
087    /**
088     * Gets the management context which sub-commands should use in order to manage the directory server.
089     *
090     * @param app
091     *            The console application instance.
092     * @return Returns the management context which sub-commands should use in order to manage the directory server.
093     * @throws ArgumentException
094     *             If a management context related argument could not be parsed successfully.
095     * @throws ClientException
096     *             If the management context could not be created.
097     */
098    public ManagementContext getManagementContext(ConsoleApplication app) throws ArgumentException, ClientException {
099        // Lazily create the LDAP management context.
100        if (context == null) {
101            Connection connection;
102            final String hostName = provider.getHostname();
103            final int port = provider.getPort();
104            try {
105                connection = factory.getConnection();
106                BuildVersion.checkVersionMismatch(connection);
107            } catch (LdapException e) {
108                if (e.getCause() instanceof SSLException) {
109                    throw new ClientException(ReturnCode.CLIENT_SIDE_CONNECT_ERROR,
110                            ERR_FAILED_TO_CONNECT_NOT_TRUSTED.get(hostName, String.valueOf(port)));
111                } else {
112                    throw new ClientException(ReturnCode.CLIENT_SIDE_CONNECT_ERROR,
113                            ERR_DSCFG_ERROR_LDAP_FAILED_TO_CONNECT.get(hostName, String.valueOf(port)));
114                }
115            } catch (ConfigException e) {
116                throw new ClientException(ReturnCode.ERROR_USER_DATA, e.getMessageObject());
117            } catch (Exception ex) {
118                throw new ClientException(ReturnCode.CLIENT_SIDE_CONNECT_ERROR,
119                        ERR_DSCFG_ERROR_LDAP_FAILED_TO_CONNECT.get(hostName, port));
120            } finally {
121                closeSilently(factory);
122            }
123
124            context = LDAPManagementContext.newManagementContext(connection, LDAPProfile.getInstance());
125        }
126        return context;
127    }
128}