alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (LocalInstanceCommand.java)

This example Glassfish source code file (LocalInstanceCommand.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

bufferedoutputstream, commandexception, commandexception, file, file, fileinputstream, instancedirs, io, ioexception, ioexception, net, network, override, param, properties, string, string, util

The Glassfish LocalInstanceCommand.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2011 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.cli.cluster;

import com.sun.enterprise.util.StringUtils;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.enterprise.util.io.InstanceDirs;
import java.io.*;
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

import org.glassfish.api.Param;
import org.glassfish.api.admin.*;

import com.sun.enterprise.admin.cli.*;
import com.sun.enterprise.util.SystemPropertyConstants;
import com.sun.enterprise.util.net.NetUtils;
import com.sun.enterprise.universal.io.SmartFile;
import com.sun.enterprise.util.io.ServerDirs;

/**
 * A base class for local commands that manage a local server instance.
 * This base class is used by a LOT of other classes.  There is a big comment before
 * each section of the file -- sorted by visibility.
 * If you specifically want a method to be overridden -- make it protected but
 * not final.
 * final protected means -- "call me but don't override me".  This convention is
 * to make things less confusing.
 * If you add a method or change whether it is final -- move it to the right section.
 *
 * Default instance file structure.
 * ||---- <GlassFish Install Root>
 *          ||---- nodes (nodeDirRoot, --nodedir)
 *                  ||---- <node-1> (nodeDirChild, --node)
 *                          || ---- agent
 *                                  || ---- config
 *                                          | ---- das.properties
 *                          || ---- <instance-1> (instanceDir)
 *                                  ||---- config
 *                                  ||---- applications
 *                                  ||---- java-web-start
 *                                  ||---- generated
 *                                  ||---- lib
 *                                  ||---- docroot
 *                          || ---- <instance-2> (instanceDir)
 *                  ||---- <node-2> (nodeDirChild)
 *
 * @author Byron Nevins
 */
// -----------------------------------------------------------------------
// ----------------   public methods here   --------------- --------------
// -----------------------------------------------------------------------
public abstract class LocalInstanceCommand extends LocalServerCommand {
    @Param(name = "nodedir", optional = true, alias = "agentdir")
    protected String nodeDir;           // nodeDirRoot
    @Param(name = "node", optional = true, alias = "nodeagent")
    protected String node;
    // subclasses decide whether it's optional, required, or not allowed
    //@Param(name = "instance_name", primary = true, optional = true)
    protected String instanceName;
    protected File nodeDirRoot;         // the parent dir of all node(s)
    protected File nodeDirChild;        // the specific node dir
    protected File instanceDir;         // the specific instance dir
    protected String domainName;
    protected boolean isCreateInstanceFilesystem = false;
    private InstanceDirs instanceDirs;

    // This is especially used for change-master-password command for a node.
    // We iterate through all the instances and so it should relax this requirement,
    // that there is only 1 instance in a node.
    protected boolean checkOneAndOnly = true;

    @Override
    protected void validate()
            throws CommandException, CommandValidationException {
        initInstance();
    }

// -----------------------------------------------------------------------
// -------- protected methods where overriding is allowed here -----------
// -----------------------------------------------------------------------
    /** 
     * Override this method if your class does NOT want to create directories
     * @param f the directory to create
     */
    protected boolean mkdirs(File f) {
        return f.mkdirs();
    }

    /**
     * Override this method if your class does NOT want CommandException thrown
     * if directory does not exist.
     * @param f directory to check
     */
    protected boolean isDirectory(File f) {
        return f.isDirectory();
    }

    /**
     * Override this method if your class does NOT want to set ServerDirs
     */
    protected boolean setServerDirs() {
        return true;
    }

    protected void initInstance() throws CommandException {
        /* node dir - parent directory of all node(s) */
        String nodeDirRootPath = null;
        if (ok(nodeDir))
            nodeDirRootPath = nodeDir;
        else // node dir = <install-root>/nodes
            nodeDirRootPath = getNodeDirRootDefault();

        nodeDirRoot = new File(nodeDirRootPath);
        mkdirs(nodeDirRoot);

        if (ok(nodeDir)) {
            // Ensure later uses of nodeDir get an absolute path
            // See bug 15014
            nodeDir = FileUtils.safeGetCanonicalPath(nodeDirRoot);
        }

        if (!isDirectory(nodeDirRoot)) {
            throw new CommandException(
                    Strings.get("Instance.badNodeDir", nodeDirRoot));
        }

        /* <node_dir>/ */
        if (node != null) {
            nodeDirChild = new File(nodeDirRoot, node);
        }
        else {
            nodeDirChild = getTheOneAndOnlyNode(nodeDirRoot);
        }

        /* <node_dir>// */
        if (instanceName != null) {
            instanceDir = new File(nodeDirChild, instanceName);
            mkdirs(instanceDir);
        }
        else {
            instanceDir = getTheOneAndOnlyInstance(nodeDirChild);
            instanceName = instanceDir.getName();
        }

        if (!isDirectory(instanceDir)) {
            throw new CommandException(
                    Strings.get("Instance.badInstanceDir", instanceDir));
        }
        nodeDirChild = SmartFile.sanitize(nodeDirChild);
        instanceDir = SmartFile.sanitize(instanceDir);

        try {
            if (setServerDirs()) {
                instanceDirs = new InstanceDirs(instanceDir);
                setServerDirs(instanceDirs.getServerDirs());
                //setServerDirs(instanceDirs.getServerDirs(), checkForSpecialFiles());
            }
        }
        catch (IOException e) {
            throw new CommandException(e);
        }
        
        logger.finer("nodeDirChild: " + nodeDirChild);
        logger.finer("instanceDir: " + instanceDir);
    }

    protected final InstanceDirs getInstanceDirs() {
        return instanceDirs;
    }

// -----------------------------------------------------------------------
// -------- protected methods where overriding is NOT allowed here -----------
// -----------------------------------------------------------------------
    /**
     * Set the programOpts based on the das.properties file.
     */
    protected final void setDasDefaults(File propfile) throws CommandException {
        Properties dasprops = getDasProperties(propfile);

        // read properties and set them in programOpts
        // properties are:
        // agent.das.port
        // agent.das.host
        // agent.das.isSecure
        // agent.das.user           XXX - not in v2?
        String p;
        p = dasprops.getProperty("agent.das.host");
        if (p != null) {
            programOpts.setHost(p);
        }
        p = dasprops.getProperty("agent.das.port");
        int port = -1;
        if (p != null) {
            port = Integer.parseInt(p);
        }
        p = dasprops.getProperty("agent.das.protocol");
        if (p != null && p.equals("rmi_jrmp")) {
            programOpts.setPort(updateDasPort(dasprops, port, propfile));
        } else if (p == null || p.equals("http")) {
            programOpts.setPort(port);
        } else {
            throw new CommandException(Strings.get("Instance.badProtocol",
                    propfile.toString(), p));
        }
        p = dasprops.getProperty("agent.das.isSecure");
        if (p != null) {
            programOpts.setSecure(Boolean.parseBoolean(p));
        }
        p = dasprops.getProperty("agent.das.user");
        if (p != null) {
            programOpts.setUser(p);
        }
        // XXX - what about the DAS admin password?
    }

    /**
     * Checks if programOpts values match das.properties file.
     */
    protected final void validateDasOptions(String hostOption, String portOption,
            String isSecureOption, File propfile) throws CommandException {
        if (propfile != null) {
            Properties dasprops = getDasProperties(propfile);
            if (!dasprops.isEmpty()) {
                String errorMsg = "";
                String nodeName = nodeDirChild != null ? nodeDirChild.getName() : "";
                String hostProp = dasprops.getProperty("agent.das.host");
                String portProp = dasprops.getProperty("agent.das.port");
                String secureProp = dasprops.getProperty("agent.das.isSecure");
                if (hostProp != null && !hostProp.equals(hostOption)) {
                    errorMsg = errorMsg + Strings.get("Instance.DasHostInvalid", hostOption, nodeName) + "\n";
                }
                if (portProp != null && !portProp.equals(portOption)) {
                    errorMsg = errorMsg + Strings.get("Instance.DasPortInvalid", portOption, nodeName) + "\n";
                }
                if (secureProp != null && !secureProp.equals(isSecureOption)) {
                    errorMsg = errorMsg + Strings.get("Instance.DasIsSecureInvalid", isSecureOption, nodeName) + "\n";
                }
                if (!errorMsg.isEmpty()) {
                    errorMsg = errorMsg + Strings.get("Instance.DasConfig", nodeName, hostProp, portProp, secureProp);
                    throw new CommandException(errorMsg);
                }
            }
        }
    }

    final protected Properties getDasProperties(File propfile) throws CommandException {
        Properties dasprops = new Properties();
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(propfile);
            dasprops.load(fis);
            fis.close();
            fis = null;
        } catch (IOException ioex) {
            throw new CommandException(
                    Strings.get("Instance.cantReadDasProperties",
                    propfile.getPath()));
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException cex) {
                    // ignore it
                }
            }
        }
        return dasprops;
    }

    final protected void whackFilesystem() throws CommandException {
        ServerDirs dirs = getServerDirs();
        File whackee = dirs.getServerDir();
        File parent = dirs.getServerParentDir();
        File grandParent = dirs.getServerGrandParentDir();

        if (whackee == null || !whackee.isDirectory()) {
            throw new CommandException(Strings.get("DeleteInstance.noWhack",
                    whackee));
        }

        // IT 12680 -- perhaps a new empty dir was created.  Get rid of it and 
        // make this an error.
        File[] files = whackee.listFiles();

        if (files == null || files.length <= 0) {
            // empty dir
            if (files != null)
                FileUtils.whack(whackee);

            throw new CommandException(Strings.get("DeleteInstance.noWhack",
                    whackee));
        }

        // Rename the instance directory to a temporary name to ensure that
        // the directory tree can be deleted on Windows.
        // The FileUtils.renameFile method has a retry built in.
        try {
            File tmpwhackee = File.createTempFile("oldinst", null, parent);
            tmpwhackee.delete();
            FileUtils.renameFile(whackee, tmpwhackee);
            FileUtils.whack(tmpwhackee);
        }
        catch (IOException ioe) {
            throw new CommandException(Strings.get("DeleteInstance.badWhackWithException",
                    whackee, ioe, StringUtils.getStackTrace(ioe)));
        }
        if (whackee.isDirectory()) {
            StringBuilder sb = new StringBuilder();
            sb.append("whackee=").append(whackee.toString());
            sb.append(", files in parent:");
            files = parent.listFiles();
            for (File f : files)
                sb.append(f.toString()).append(", ");
            File f1 = new File(whackee.toString());
            sb.append(", new wackee.exists=").append(f1.exists());
            throw new CommandException(Strings.get("DeleteInstance.badWhack",
                    whackee) + ", " + sb.toString());
        }

        // now see if the parent dir is empty.  If so wipe it out.
        // Don't be too picky with throwin errors here...
        try {
            files = parent.listFiles();

            if (noInstancesRemain(files)) {
                File tmpwhackee = File.createTempFile("oldnode", null, grandParent);
                tmpwhackee.delete();
                FileUtils.renameFile(parent, tmpwhackee);
                FileUtils.whack(tmpwhackee);
            }
        }
        catch (IOException ioe) {
            // we tried!!!
        }
    }

    private boolean noInstancesRemain(File[] files) {
        if (files == null || files.length <= 0)
            return true;

        if (files.length == 1
                && files[0].isDirectory()
                && files[0].getName().equals("agent"))
            return true;

        return false;
    }

    /**
     * Gets the GlassFish installation root (using property com.sun.aas.installRoot),
     * first from asenv.conf.  If that's not available, then from java.lang.System.
     *
     * @return path of GlassFish install root
     * @throws CommandException if the GlassFish install root is not found
     */
    protected String getInstallRootPath() throws CommandException {
        String installRootPath = getSystemProperty(
                SystemPropertyConstants.INSTALL_ROOT_PROPERTY);

        if (!StringUtils.ok(installRootPath))
            installRootPath = System.getProperty(
                    SystemPropertyConstants.INSTALL_ROOT_PROPERTY);

        if (!StringUtils.ok(installRootPath))
            throw new CommandException("noInstallDirPath");
        return installRootPath;
    }

    /**
     * Gets the GlassFish product installation root (using property
     * com.sun.aas.productRoot), first from asenv.conf. If that's not
     * available, then from java.lang.System.
     *
     * This will typically be the parent of the glassfish install root
     *
     * @return path of GlassFish product install root
     * @throws CommandException if the GlassFish install root is not found
     */
    protected String getProductRootPath() throws CommandException {
        String productRootPath = getSystemProperty(
                SystemPropertyConstants.PRODUCT_ROOT_PROPERTY);

        if (!StringUtils.ok(productRootPath))
            productRootPath = System.getProperty(
                    SystemPropertyConstants.PRODUCT_ROOT_PROPERTY);

        if (!StringUtils.ok(productRootPath)) {
            // Product install root is parent of glassfish install root
            File installRoot = new File(getInstallRootPath());
            return installRoot.getParent();
        }
        return productRootPath;
    }

// -----------------------------------------------------------------------
// -------- everything below here is private    --------------------------
// -----------------------------------------------------------------------
    /**
     * Update DAS port from an old V2 das.properties file.
     * If the old port is the standard jrmp port, just use the new
     * standard http port.  Otherwise, prompt for the new port number
     * if possible.  In any event, try to rewrite the das.properties
     * file with the new values.
     */
    private int updateDasPort(Properties dasprops, int port, File propfile) {
        Console cons;
        if (port == 8686) {     // the old JRMP port
            logger.info(
                    Strings.get("Instance.oldDasProperties",
                    propfile.toString(), Integer.toString(port),
                    Integer.toString(programOpts.getPort())));
            port = programOpts.getPort();
        }
        else if ((cons = System.console()) != null) {
            String line = cons.readLine("%s",
                    Strings.get("Instance.oldDasPropertiesPrompt",
                    propfile.toString(), Integer.toString(port),
                    Integer.toString(programOpts.getPort())));
            while (line != null && line.length() > 0) {
                try {
                    port = Integer.parseInt(line);
                    if (port > 0 && port <= 65535)
                        break;
                }
                catch (NumberFormatException nfex) {
                }
                line = cons.readLine(Strings.get("Instance.reenterPort"),
                        Integer.toString(programOpts.getPort()));
            }
        }
        else {
            logger.info(
                    Strings.get("Instance.oldDasPropertiesWrong",
                    propfile.toString(), Integer.toString(port),
                    Integer.toString(programOpts.getPort())));
            port = programOpts.getPort();
        }
        dasprops.setProperty("agent.das.protocol", "http");
        dasprops.setProperty("agent.das.port", Integer.toString(port));
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(propfile));
            dasprops.store(bos,
                    "Domain Administration Server Connection Properties");
            bos.close();
            bos = null;
        }
        catch (IOException ex2) {
            logger.info(
                    Strings.get("Instance.dasPropertiesUpdateFailed"));
        }
        finally {
            if (bos != null) {
                try {
                    bos.close();
                }
                catch (IOException cex) {
                    // ignore it
                }
            }
        }
        // whether we were able to update the file or not, keep going
        logger.finer("New DAS port number: " + port);
        return port;
    }

    private File getTheOneAndOnlyNode(File parent) throws CommandException {
        // look for subdirs in the parent dir -- there must be one and only one
        // or there can be zero in which case we create one-and-only

        File[] files = parent.listFiles(new FileFilter() {
            public boolean accept(File f) {
                return isDirectory(f);
            }
        });

        // ERROR:  more than one node dir child
        if (files != null && files.length > 1) {
            throw new CommandException(
                    Strings.get("tooManyNodes", parent));
        }

        // the usual case -- one node dir child
        if (files != null && files.length == 1)
            return files[0];

        /*
         * If there is no existing node dir child -- create one!
         * If the instance is on the same machine as DAS, use "localhost" as the node dir child
         * Only for _create-instance-filesystem
         */
        if (isCreateInstanceFilesystem) {
            try {
                String dashost = null;
                if (programOpts != null) {
                    dashost = programOpts.getHost();
                }
                String hostname = InetAddress.getLocalHost().getHostName();
                if (hostname.equals(dashost) || NetUtils.isThisHostLocal(dashost)) {
                    hostname = "localhost" + "-" + domainName;
                }
                File f = new File(parent, hostname);

                if (!mkdirs(f) || !isDirectory(f)) // for instance there is a regular file with that name
                {
                    throw new CommandException(Strings.get("cantCreateNodeDirChild", f));
                }

                return f;
            } catch (UnknownHostException ex) {
                throw new CommandException(Strings.get("cantGetHostName", ex));
            }
        } else {
            throw new CommandException(Strings.get("DeleteInstance.noInstance"));
        }
    }

    private File getTheOneAndOnlyInstance(File parent) throws CommandException {
        // look for subdirs in the parent dir -- there must be one and only one

        File[] files = parent.listFiles(new FileFilter() {
            public boolean accept(File f) {
                return isDirectory(f);
            }
        });

        if (files == null || files.length == 0) {
            throw new CommandException(
                    Strings.get("Instance.noInstanceDirs", parent));
        }

        // expect two - the "agent" directory and the instance directory
        if (files.length > 2 && checkOneAndOnly) {
            throw new CommandException(
                    Strings.get("Instance.tooManyInstanceDirs", parent));
        }

        for (File f : files) {
            if (!f.getName().equals("agent"))
                return f;
        }
        throw new CommandException(
                Strings.get("Instance.noInstanceDirs", parent));
    }

    /**
     * Return the default value for nodeDirRoot, first checking if com.sun.aas.agentRoot
     * was specified in asenv.conf and returning this value. If not specified,
     * then the defaut value is the {GlassFish_Install_Root}/nodes.
     * nodeDirRoot is the parent directory of the node(s).
     *
     * @return String default nodeDirRoot - parent directory of node(s)
     * @throws CommandException if the GlassFish install root is not found
     */
    private String getNodeDirRootDefault() throws CommandException {
        String nodeDirDefault = getSystemProperty(
                SystemPropertyConstants.AGENT_ROOT_PROPERTY);

        if (StringUtils.ok(nodeDirDefault))
            return nodeDirDefault;

        String installRootPath = getInstallRootPath();
        return installRootPath + "/" + "nodes";
    }

    @Override
    protected File getMasterPasswordFile() {

        if (nodeDirChild == null)
            return null;

        File mp = new File(new File(nodeDirChild,"agent"), "master-password");
        if (!mp.canRead())
            return null;

        return mp;
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish LocalInstanceCommand.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.