All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.enterprise.admin.servermgmt.cli.StartDomainCommand Maven / Gradle / Ivy

There is a newer version: 4.1.2.181
Show newest version
/*
 * 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.enterprise.admin.cli.CLIConstants;
import java.io.*;
import java.util.*;
import java.util.logging.*;

import javax.inject.Inject;

import org.jvnet.hk2.annotations.*;
import org.glassfish.api.Param;
import org.glassfish.api.admin.*;
import org.glassfish.hk2.api.PerLookup;

import com.sun.enterprise.admin.cli.Environment;
import com.sun.enterprise.admin.launcher.GFLauncher;
import com.sun.enterprise.admin.launcher.GFLauncherException;
import com.sun.enterprise.admin.launcher.GFLauncherFactory;
import com.sun.enterprise.admin.launcher.GFLauncherInfo;
import com.sun.enterprise.admin.util.CommandModelData.ParamModelData;
import com.sun.enterprise.universal.i18n.LocalStringsImpl;
import com.sun.enterprise.universal.process.ProcessStreamDrainer;
import com.sun.enterprise.universal.xml.MiniXmlParserException;
import org.glassfish.security.common.FileRealmHelper;

/**
 * The start-domain command.
 *
 * @author bnevins
 * @author Bill Shannon
 */
@Service(name = "start-domain")
@PerLookup
public class StartDomainCommand extends LocalDomainCommand implements StartServerCommand {

    private GFLauncherInfo info;
    private GFLauncher launcher;
    @Param(optional = true, shortName = "v", defaultValue = "false")
    private boolean verbose;
    @Param(optional = true, defaultValue = "false")
    private boolean upgrade;
    @Param(optional = true, shortName = "w", defaultValue = "false")
    private boolean watchdog;
    @Param(optional = true, shortName = "d", defaultValue = "false")
    private boolean debug;
    @Param(name = "domain_name", primary = true, optional = true)
    private String domainName0;
    @Param(name = "dry-run", shortName = "n", optional = true,
            defaultValue = "false")
    private boolean dry_run;
    @Param(name = "drop-interrupted-commands", optional = true, defaultValue = "false")
    private boolean drop_interrupted_commands;

    @Inject
    ServerEnvironment senv;
    
    private static final LocalStringsImpl strings =
            new LocalStringsImpl(StartDomainCommand.class);
    // the name of the master password option
    private StartServerHelper helper;
    private String newpwName = Environment.getPrefix() + "NEWPASSWORD";

    @Override
    public List getLauncherArgs() {
        return launcher.getCommandLine();
    }

    @Override
    public RuntimeType getType() {
        return RuntimeType.DAS;
    }

    @Override
    protected void validate()
            throws CommandException, CommandValidationException {
        setDomainName(domainName0);
        super.validate();
    }

    @Override
    protected int executeCommand() throws CommandException {
        try {
            // createLauncher needs to go before the helper is created!!
            createLauncher();
            final String mpv = getMasterPassword();

            helper = new StartServerHelper(
                    logger,
                    programOpts.isTerse(),
                    getServerDirs(),
                    launcher,
                    mpv,
                    debug);

            if (helper.prepareForLaunch() == false)
                return ERROR;

            if (!upgrade && launcher.needsManualUpgrade()) {
                logger.info(strings.get("manualUpgradeNeeded"));
                return ERROR;
            }
            doAutoUpgrade(mpv);

            if (dry_run) {
                logger.fine(Strings.get("dry_run_msg"));
                List cmd = launcher.getCommandLine();
                StringBuilder sb = new StringBuilder();
                for (String s : cmd) {
                    sb.append(s);
                    sb.append('\n');
                }
                logger.info(sb.toString());
                return SUCCESS;
            }

            doAdminPasswordCheck();

            // launch returns very quickly if verbose is not set
            // if verbose is set then it returns after the domain dies
            launcher.launch();

            if (verbose || upgrade || watchdog) { // we can potentially loop forever here...
                while (true) {
                    int returnValue = launcher.getExitValue();

                    switch (returnValue) {
                        case CLIConstants.RESTART_NORMAL:
                            logger.info(strings.get("restart"));
                            break;
                        case CLIConstants.RESTART_DEBUG_ON:
                            logger.info(strings.get("restartChangeDebug", "on"));
                            info.setDebug(true);
                            break;
                        case CLIConstants.RESTART_DEBUG_OFF:
                            logger.info(strings.get("restartChangeDebug", "off"));
                            info.setDebug(false);
                            break;
                        default:
                            return returnValue;
                    }

                    if (env.debug())
                        System.setProperty(CLIConstants.WALL_CLOCK_START_PROP,
                                "" + System.currentTimeMillis());

                    launcher.relaunch();
                }

            }
            else {
                helper.waitForServer();
                helper.report();
                return SUCCESS;
            }
        }
        catch (GFLauncherException gfle) {
            throw new CommandException(gfle.getMessage());
        }
        catch (MiniXmlParserException me) {
            throw new CommandException(me);
        }
    }

    /**
     * Create a launcher for the domain specified by arguments to
     * this command.  The launcher is for a server of the specified type.
     * Sets the launcher and info fields.
     * It has to be public because it is part of an interface
     */
    @Override
    public void createLauncher()
            throws GFLauncherException, MiniXmlParserException {
        launcher = GFLauncherFactory.getInstance(getType());
        info = launcher.getInfo();

        info.setDomainName(getDomainName());
        info.setDomainParentDir(getDomainsDir().getPath());
        info.setVerbose(verbose || upgrade);
        info.setDebug(debug);
        info.setUpgrade(upgrade);
        info.setWatchdog(watchdog);
        info.setDropInterruptedCommands(drop_interrupted_commands);

        info.setRespawnInfo(programOpts.getClassName(),
                programOpts.getClassPath(),
                respawnArgs());

        launcher.setup();
    }

    /**
     * Return the asadmin command line arguments necessary to start
     * this domain admin server.
     */
    private String[] respawnArgs() {
        List args = new ArrayList(15);
        args.addAll(Arrays.asList(programOpts.getProgramArguments()));

        // now the start-domain specific arguments
        args.add(getName());    // the command name
        args.add("--verbose=" + String.valueOf(verbose));
        args.add("--watchdog=" + String.valueOf(watchdog));
        args.add("--debug=" + String.valueOf(debug));
        args.add("--domaindir");
        args.add(getDomainsDir().toString());
        if (ok(getDomainName()))
            args.add(getDomainName());  // the operand

        if (logger.isLoggable(Level.FINER))
            logger.log(Level.FINER, "Respawn args: {0}", args.toString());
        String[] a = new String[args.size()];
        args.toArray(a);
        return a;
    }

    /*
     * This is useful for debugging restart-domain problems.
     * In that case the Server process will run this class and it is fairly
     * involved to attach a debugger (though not bad -- see RestartDomain on
     * the server to see how).  Standard output disappears.  This is a
     * generally useful method.  Feel free to copy & paste!
     */
    private void debug(String s) {
        PrintStream ps = null;
        try {
            ps = new PrintStream(new FileOutputStream("startdomain.txt", true));
            ps.println(new Date().toString() + ":  " + s);
        } catch (FileNotFoundException ex) {
            //
        } finally {
            if (ps != null)
                ps.close();
        }
    }

    /*
     * If this domain needs to be upgraded and --upgrade wasn't
     * specified, first start the domain to do the upgrade and
     * then start the domain again for real.
     */
    private void doAutoUpgrade(String mpv) throws GFLauncherException, MiniXmlParserException, CommandException {
        if (upgrade || !launcher.needsAutoUpgrade())
            return;

        logger.info(strings.get("upgradeNeeded"));
        info.setUpgrade(true);
        launcher.setup();
        launcher.launch();
        Process p = launcher.getProcess();
        int exitCode = -1;
        try {
            exitCode = p.waitFor();
        }
        catch (InterruptedException ex) {
            // should never happen
        }
        if (exitCode != SUCCESS) {
            ProcessStreamDrainer psd =
                    launcher.getProcessStreamDrainer();
            String output = psd.getOutErrString();
            if (ok(output))
                throw new CommandException(
                        strings.get("upgradeFailedOutput",
                        info.getDomainName(), exitCode, output));
            else
                throw new CommandException(strings.get("upgradeFailed",
                        info.getDomainName(), exitCode));
        }
        logger.info(strings.get("upgradeSuccessful"));

        // need a new launcher to start the domain for real
        createLauncher();
        // continue with normal start...
    }

    /*
     * Check to make sure that at least one admin user is able to login.
     * If none is found, then prompt for an admin password.
     *
     * NOTE: this depends on launcher.setup having already been called.
     */
    private void doAdminPasswordCheck() throws CommandException {
        String arfile = launcher.getAdminRealmKeyFile();
        if (arfile != null) {
            try {
                FileRealmHelper ar = new FileRealmHelper(arfile);
                if (!ar.hasAuthenticatableUser()) {
                    // Prompt for the password for the first user and set it
                    Set names = ar.getUserNames();
                    if (names == null || names.isEmpty()) {
                        throw new CommandException("no admin users");
                    }
                    String auser = names.iterator().next();
                    ParamModelData npwo = new ParamModelData(newpwName, String.class, false, null);
                    npwo.prompt = strings.get("new.adminpw", auser);
                    npwo.promptAgain = strings.get("new.adminpw.again", auser);
                    npwo.param._password = true;
                    logger.info(strings.get("new.adminpw.prompt"));
                    String npw = super.getPassword(npwo, null, true);
                    if (npw == null) {
                        throw new CommandException(strings.get("no.console"));
                    }
                    ar.updateUser(auser, auser, npw.toCharArray(), null);
                    ar.persist();
                }
            } catch (IOException ioe) {
                throw new CommandException(ioe);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy