Package com.sun.enterprise.admin.servermgmt.cli

Source Code of com.sun.enterprise.admin.servermgmt.cli.CreateDomainCommand

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.admin.servermgmt.cli;

import com.sun.appserv.management.client.prefs.LoginInfo;
import com.sun.appserv.management.client.prefs.LoginInfoStore;
import com.sun.appserv.management.client.prefs.LoginInfoStoreFactory;
import com.sun.enterprise.admin.cli.CLICommand;
import com.sun.enterprise.admin.cli.CLIConstants;
import com.sun.enterprise.admin.servermgmt.*;
import com.sun.enterprise.admin.servermgmt.domain.DomainBuilder;
import com.sun.enterprise.admin.servermgmt.pe.PEDomainsManager;
import com.sun.enterprise.admin.util.CommandModelData.ParamModelData;
import com.sun.enterprise.config.serverbeans.Config;
import static com.sun.enterprise.config.util.PortConstants.*;
import com.sun.enterprise.module.bootstrap.StartupContext;
import com.sun.enterprise.universal.i18n.LocalStringsImpl;
import com.sun.enterprise.util.SystemPropertyConstants;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.enterprise.util.net.NetUtils;
import com.sun.logging.LogDomains;

import java.beans.PropertyVetoException;
import java.io.Console;
import java.io.File;
import java.util.*;
import java.util.logging.Level;
import org.glassfish.api.Param;
import org.glassfish.api.admin.CommandException;
import org.glassfish.api.admin.CommandModel.ParamModel;
import org.glassfish.api.admin.CommandValidationException;
import org.glassfish.api.admin.config.Container;
import org.glassfish.api.admin.config.DomainContext;
import org.glassfish.api.admin.config.DomainInitializer;
import org.glassfish.embeddable.BootstrapProperties;
import org.glassfish.embeddable.GlassFish;
import org.glassfish.embeddable.GlassFishException;
import org.glassfish.embeddable.GlassFishProperties;
import org.glassfish.embeddable.GlassFishRuntime;
import org.glassfish.security.common.FileRealmHelper;

import org.jvnet.hk2.annotations.Service;
import org.glassfish.hk2.api.PerLookup;
import org.glassfish.hk2.api.ServiceLocator;
import org.jvnet.hk2.config.ConfigBeanProxy;
import org.jvnet.hk2.config.ConfigCode;
import org.jvnet.hk2.config.ConfigSupport;
import org.jvnet.hk2.config.TransactionFailure;

/**
* This is a local command that creates a domain.
*/
@Service(name = "create-domain")
@PerLookup
public final class CreateDomainCommand extends CLICommand {
    // constants for create-domain options
    private static final String ADMIN_PORT = "adminport";
    private static final String ADMIN_PASSWORD = "password";
    private static final String DEFAULT_MASTER_PASSWORD =
            RepositoryManager.DEFAULT_MASTER_PASSWORD;
    private static final String SAVE_MASTER_PASSWORD = "savemasterpassword";
    private static final String INSTANCE_PORT = "instanceport";
    private static final String DOMAIN_PROPERTIES = "domainproperties";
    private static final String PORTBASE_OPTION = "portbase";
    private String adminUser = null;
    @Param(name = ADMIN_PORT, optional = true)
    private String adminPort;
    @Param(name = PORTBASE_OPTION, optional = true)
    private String portBase;
    @Param(obsolete = true, name = "profile", optional = true)
    private String profile;
    @Param(name = "template", optional = true)
    private String template;
    @Param(name = "domaindir", optional = true)
    private String domainDir;
    @Param(name = INSTANCE_PORT, optional = true)
    private String instancePort;
    @Param(name = SAVE_MASTER_PASSWORD, optional = true, defaultValue = "false")
    private boolean saveMasterPassword = false;
    @Param(name = "usemasterpassword", optional = true, defaultValue = "false")
    private boolean useMasterPassword = false;
    @Param(name = DOMAIN_PROPERTIES, optional = true, separator = ':')
    private Properties domainProperties;
    @Param(name = "keytooloptions", optional = true)
    private String keytoolOptions;
    @Param(name = "savelogin", optional = true, defaultValue = "false")
    private boolean saveLoginOpt = false;
    @Param(name = "nopassword", optional = true, defaultValue = "false")
    private boolean noPassword = false;
    @Param(name = ADMIN_PASSWORD, optional = true, password = true)
    private String adminPassword = null;
    @Param(name = "masterpassword", optional = true, password = true, defaultValue = DEFAULT_MASTER_PASSWORD)
    private String masterPassword = null;
    @Param(name = "checkports", optional = true, defaultValue = "true")
    private boolean checkPorts = true;
    @Param(name = "domain_name", primary = true)
    private String domainName;
    private static final LocalStringsImpl strings =
            new LocalStringsImpl(CreateDomainCommand.class);

    public CreateDomainCommand() {
    }

    /**
     * Add --adminport and --instanceport options with proper default values.
     * (Can't set default values above because it conflicts with --portbase
     * option processing.)
     */
    protected Collection<ParamModel> usageOptions() {
        Collection<ParamModel> opts = commandModel.getParameters();
        Set<ParamModel> uopts = new LinkedHashSet<ParamModel>();
        ParamModel aPort = new ParamModelData(ADMIN_PORT, String.class, true,
                Integer.toString(CLIConstants.DEFAULT_ADMIN_PORT));
        ParamModel iPort = new ParamModelData(INSTANCE_PORT, String.class, true,
                Integer.toString(DEFAULT_INSTANCE_PORT));
        for (ParamModel pm : opts) {
            if (pm.getName().equals(ADMIN_PORT))
                uopts.add(aPort);
            else if (pm.getName().equals(INSTANCE_PORT))
                uopts.add(iPort);
            else
                uopts.add(pm);
        }
        return uopts;
    }

    /**
     */
    @Override
    protected void validate()
            throws CommandException, CommandValidationException {
        if (domainDir == null) {
            domainDir = getSystemProperty(
                    SystemPropertyConstants.DOMAINS_ROOT_PROPERTY);
        }
        if (domainDir == null) {
            throw new CommandValidationException(
                    strings.get("InvalidDomainPath", domainDir));
        }

        /*
         * The only required value is the domain_name operand, which might have
         * been prompted for before we get here.
         *
         * If --user wasn't specified as a program option, we treat it as a
         * required option and prompt for it if possible, unless --nopassword
         * was specified in which case we default the user name.
         *
         * The next prompted-for value will be the admin password, if required.
         */
        if (programOpts.getUser() == null && !noPassword) {
            // prompt for it (if interactive)
            Console cons = System.console();
            if (cons != null && programOpts.isInteractive()) {
                cons.printf("%s", strings.get("AdminUserRequiredPrompt",
                        SystemPropertyConstants.DEFAULT_ADMIN_USER));
                String val = cons.readLine();
                if (ok(val)) {
                    programOpts.setUser(val);
                    if (adminPassword == null) {
                        adminPassword = getAdminPassword();
                    }
                }
            }
            else {
                //logger.info(strings.get("AdminUserRequired"));
                throw new CommandValidationException(
                        strings.get("AdminUserRequired"));
            }
        }
        if (programOpts.getUser() != null) {
            try {
                FileRealmHelper.validateUserName(programOpts.getUser());
            }
            catch (IllegalArgumentException ise) {
                throw new CommandValidationException(
                        strings.get("InvalidUserName", programOpts.getUser()));
            }
        }
    }

    public void verifyPortBase() throws CommandValidationException {
        if (usePortBase()) {
            final int portbase = convertPortStr(portBase);
            setOptionsWithPortBase(portbase);
        }
    }

    private void setOptionsWithPortBase(final int portbase)
            throws CommandValidationException {
        // set the option name and value in the options list
        verifyPortBasePortIsValid(ADMIN_PORT,
                portbase + PORTBASE_ADMINPORT_SUFFIX);
        adminPort = String.valueOf(portbase + PORTBASE_ADMINPORT_SUFFIX);

        verifyPortBasePortIsValid(INSTANCE_PORT,
                portbase + PORTBASE_INSTANCE_SUFFIX);
        instancePort = String.valueOf(portbase + PORTBASE_INSTANCE_SUFFIX);

        domainProperties = new Properties();
        verifyPortBasePortIsValid(DomainConfig.K_HTTP_SSL_PORT,
                portbase + PORTBASE_HTTPSSL_SUFFIX);
        domainProperties.put(DomainConfig.K_HTTP_SSL_PORT,
                String.valueOf(portbase + PORTBASE_HTTPSSL_SUFFIX));

        verifyPortBasePortIsValid(DomainConfig.K_IIOP_SSL_PORT,
                portbase + PORTBASE_IIOPSSL_SUFFIX);
        domainProperties.put(DomainConfig.K_IIOP_SSL_PORT,
                String.valueOf(portbase + PORTBASE_IIOPSSL_SUFFIX));

        verifyPortBasePortIsValid(DomainConfig.K_IIOP_MUTUALAUTH_PORT,
                portbase + PORTBASE_IIOPMUTUALAUTH_SUFFIX);
        domainProperties.put(DomainConfig.K_IIOP_MUTUALAUTH_PORT,
                String.valueOf(portbase + PORTBASE_IIOPMUTUALAUTH_SUFFIX));

        verifyPortBasePortIsValid(DomainConfig.K_JMS_PORT,
                portbase + PORTBASE_JMS_SUFFIX);
        domainProperties.put(DomainConfig.K_JMS_PORT,
                String.valueOf(portbase + PORTBASE_JMS_SUFFIX));

        verifyPortBasePortIsValid(DomainConfig.K_ORB_LISTENER_PORT,
                portbase + PORTBASE_IIOP_SUFFIX);
        domainProperties.put(DomainConfig.K_ORB_LISTENER_PORT,
                String.valueOf(portbase + PORTBASE_IIOP_SUFFIX));

        verifyPortBasePortIsValid(DomainConfig.K_JMX_PORT,
                portbase + PORTBASE_JMX_SUFFIX);
        domainProperties.put(DomainConfig.K_JMX_PORT,
                String.valueOf(portbase + PORTBASE_JMX_SUFFIX));

        verifyPortBasePortIsValid(DomainConfig.K_OSGI_SHELL_TELNET_PORT,
                portbase + PORTBASE_OSGI_SUFFIX);
        domainProperties.put(DomainConfig.K_OSGI_SHELL_TELNET_PORT,
                String.valueOf(portbase + PORTBASE_OSGI_SUFFIX));

        verifyPortBasePortIsValid(DomainConfig.K_JAVA_DEBUGGER_PORT,
                portbase + PORTBASE_DEBUG_SUFFIX);
        domainProperties.put(DomainConfig.K_JAVA_DEBUGGER_PORT,
                String.valueOf(portbase + PORTBASE_DEBUG_SUFFIX));

    }

    /**
     */
    @Override
    protected int executeCommand()
            throws CommandException, CommandValidationException {

        // domain validation upfront (i.e. before we prompt)
        try {
            DomainsManager manager = new PEDomainsManager();
            DomainConfig config =
                    new DomainConfig(domainName, domainDir);
            manager.validateDomain(config, false);
            verifyPortBase();
        }
        catch (DomainException e) {
            logger.fine(e.getLocalizedMessage());
            throw new CommandException(
                    strings.get("CouldNotCreateDomain", domainName), e);
        }

        /*
         * The admin user is specified with the --user program option. If not
         * specified (because the user hit Enter at the prompt), we use the
         * default, which allows unauthenticated login.
         */
        adminUser = programOpts.getUser();
        if (!ok(adminUser)) {
            adminUser = SystemPropertyConstants.DEFAULT_ADMIN_USER;
            adminPassword = SystemPropertyConstants.DEFAULT_ADMIN_PASSWORD;
        }
        else if (noPassword) {
            adminPassword = SystemPropertyConstants.DEFAULT_ADMIN_PASSWORD;
        }
        else {
            adminPassword = getAdminPassword();
            boolean haveAdminPwd = true;
        }

        if (saveMasterPassword)
            useMasterPassword = true;

        if (masterPassword == null)
            masterPassword = DEFAULT_MASTER_PASSWORD;

        try {
            // verify admin port is valid if specified on command line
            if (adminPort != null) {
                verifyPortIsValid(adminPort);
            }
            // instance option is entered then verify instance port is valid
            if (instancePort != null) {
                verifyPortIsValid(instancePort);
            }

            // saving the login information happens inside this method
            createTheDomain(domainDir, domainProperties);
        }
        catch (CommandException ce) {
            logger.info(ce.getLocalizedMessage());
            throw new CommandException(
                    strings.get("CouldNotCreateDomain", domainName), ce);
        }
        catch (Exception e) {
            logger.fine(e.getLocalizedMessage());
            throw new CommandException(
                    strings.get("CouldNotCreateDomain", domainName), e);
        }
        return 0;
    }

    /**
     * Get the admin password as a required option.
     */
    private String getAdminPassword() throws CommandValidationException {
        // create a required ParamModel for the password
        ParamModelData po = new ParamModelData(ADMIN_PASSWORD, String.class, false, null);
        po.prompt = strings.get("AdminPassword");
        po.promptAgain = strings.get("AdminPasswordAgain");
        po.param._password = true;
        return getPassword(po, SystemPropertyConstants.DEFAULT_ADMIN_PASSWORD, true);
    }

    /**
     * Verify that the port is valid. Port must be greater than 0 and less than
     * 65535. This method will also check if the port is in use. If checkPorts
     * is false it does not throw an Exception if it is in use.
     *
     * @param portNum - the port number to verify
     * @throws CommandException if Port is not valid
     * @throws CommandValidationException is port number is not a numeric value.
     */
    private void verifyPortIsValid(String portNum)
            throws CommandException, CommandValidationException {

        final int portToVerify = convertPortStr(portNum);

        if (!NetUtils.isPortValid(portToVerify))
            throw new CommandException(strings.get("InvalidPortRange", portNum));

        if (checkPorts == false) {
            // do NOT make any network calls!
            logger.log(Level.FINER, "Port ={0}", portToVerify);
            return;
        }

        NetUtils.PortAvailability avail = NetUtils.checkPort(portToVerify);

        switch (avail) {
            case illegalNumber:
                throw new CommandException(
                        strings.get("InvalidPortRange", portNum));

            case inUse:
                throw new CommandException(
                        strings.get("PortInUseError", domainName, portNum));

            case noPermission:
                throw new CommandException(
                        strings.get("NoPermissionForPortError",
                        portNum, domainName));

            case unknown:
                throw new CommandException(strings.get("UnknownPortMsg", portNum));

            case OK:
                logger.log(Level.FINER, "Port ={0}", portToVerify);
                break;
            default:
                break;
        }
    }

    /**
     * Converts the port string to port int
     *
     * @param port the port number
     * @return the port number as an int
     * @throws CommandValidationException if port string is not numeric
     */
    private int convertPortStr(final String port)
            throws CommandValidationException {
        try {
            return Integer.parseInt(port);
        }
        catch (Exception e) {
            throw new CommandValidationException(
                    strings.get("InvalidPortNumber", port));
        }
    }

    /**
     * Verify that the portbase port is valid Port must be greater than 0 and
     * less than 65535. This method will also check if the port is in used.
     *
     * @param portNum the port number to verify
     * @throws CommandException if Port is not valid
     * @throws CommandValidationException is port number is not a numeric value.
     */
    private void verifyPortBasePortIsValid(String portName, int portNum)
            throws CommandValidationException {
        if (portNum <= 0 || portNum > PORT_MAX_VAL) {
            throw new CommandValidationException(
                    strings.get("InvalidPortBaseRange", portNum, portName));
        }
        if (checkPorts && !NetUtils.isPortFree(portNum)) {
            throw new CommandValidationException(
                    strings.get("PortBasePortInUse", portNum, portName));
        }
        logger.finer("Port =" + portNum);
    }

    /**
     * Create the domain.
     *
     * @param domainPath domain path to insert in domainConfig
     * @param domainProperties properties to insert in domainConfig
     * @throws CommandException if domain cannot be created
     */
    private void createTheDomain(final String domainPath,
            Properties domainProperties)
            throws DomainException, CommandValidationException {

        //
        // fix for bug# 4930684
        // domain name is validated before the ports
        //
        String domainFilePath = (domainPath + File.separator + domainName);
        if (FileUtils.safeGetCanonicalFile(new File(domainFilePath)).exists()) {
            throw new CommandValidationException(strings.get("DomainExists", domainName));
        }
        DomainConfig domainConfig = null;
        if (template == null || template.endsWith(".jar")) {
            domainConfig = new DomainConfig(domainName,
                    domainPath, adminUser, adminPassword,
                    masterPassword, saveMasterPassword,
                    adminPort, instancePort,
                    domainProperties);
            domainConfig.put(DomainConfig.K_VALIDATE_PORTS,
                    Boolean.valueOf(checkPorts));
            domainConfig.put(DomainConfig.KEYTOOLOPTIONS, keytoolOptions);
            domainConfig.put(DomainConfig.K_TEMPLATE_NAME, template);
            domainConfig.put(DomainConfig.K_PORTBASE, portBase);
            initSecureAdminSettings(domainConfig);
            try {
                DomainBuilder domainBuilder = new DomainBuilder(domainConfig);
                domainBuilder.validateTemplate();
                domainBuilder.run();
            } catch (Exception e) {
                throw new DomainException(e.getMessage());
            }
        }
        else {
            throw new DomainException(strings.get("InvalidTemplateValue", template));
        }
        logger.info(strings.get("DomainCreated", domainName));
        Integer adminPort = (Integer)domainConfig.get(DomainConfig.K_ADMIN_PORT);
        logger.info(strings.get("DomainPort", domainName, adminPort));
        if (adminPassword.equals(
                SystemPropertyConstants.DEFAULT_ADMIN_PASSWORD))
            logger.info(strings.get("DomainAllowsUnauth", domainName,
                    adminUser));
        else
            logger.info(
                    strings.get("DomainAdminUser", domainName, adminUser));
        //checkAsadminPrefsFile();
        if (saveLoginOpt) {
            saveLogin(adminPort, adminUser, adminPassword, domainName);
        }
    }

    /**
     * Saves the login information to the login store. Usually this is the file
     * ".asadminpass" in user's home directory.
     */
    private void saveLogin(final int port, final String user,
            final String password, final String dn) {
        try {
            // by definition, the host name will default to "localhost"
            // and entry is overwritten
            final LoginInfoStore store = LoginInfoStoreFactory.getStore(null);
            final LoginInfo login =
                    new LoginInfo("localhost", port, user, password);
            if (store.exists(login.getHost(), login.getPort())) {
                // just let the user know that the user has chosen to overwrite
                // the login information. This is non-interactive, on purpose
                logger.info(strings.get("OverwriteLoginMsgCreateDomain",
                        login.getHost(), "" + login.getPort()));
            }
            store.store(login, true);
            logger.info(strings.get("LoginInfoStoredCreateDomain",
                    user, dn, store.getName()));
        }
        catch (final Throwable e) {
            logger.warning(
                    strings.get("LoginInfoNotStoredCreateDomain", user, dn));
            printExceptionStackTrace(e);
        }
    }

    /**
     * Check if portbase option is specified. Portbase is mutually exclusive to
     * adminport and domainproperties options. If portbase options is specfied
     * and also adminport or domainproperties is specified as well, then throw
     * an exception.
     */
    private boolean usePortBase() throws CommandValidationException {
        if (portBase != null) {
            if (adminPort != null) {
                throw new CommandValidationException(
                        strings.get("MutuallyExclusiveOption",
                        ADMIN_PORT, PORTBASE_OPTION));
            }
            else if (instancePort != null) {
                throw new CommandValidationException(
                        strings.get("MutuallyExclusiveOption",
                        INSTANCE_PORT, PORTBASE_OPTION));
            }
            else if (domainProperties != null) {
                throw new CommandValidationException(
                        strings.get("MutuallyExclusiveOption",
                        DOMAIN_PROPERTIES, PORTBASE_OPTION));
            }
            else {
                return true;
            }
        }
        return false;
    }

    private void initSecureAdminSettings(final DomainConfig config) {
        config.put(DomainConfig.K_ADMIN_CERT_DN, KeystoreManager.getDASCertDN(config));
        config.put(DomainConfig.K_INSTANCE_CERT_DN, KeystoreManager.getInstanceCertDN(config));
        config.put(DomainConfig.K_SECURE_ADMIN_IDENTIFIER, secureAdminIdentifier());
    }

    private String secureAdminIdentifier() {
        final UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }
}
TOP

Related Classes of com.sun.enterprise.admin.servermgmt.cli.CreateDomainCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.