Package org.glassfish.web.admin.cli

Source Code of org.glassfish.web.admin.cli.CreateHttpListener

/*
* 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 org.glassfish.web.admin.cli;

import java.beans.PropertyVetoException;
import java.text.MessageFormat;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.inject.Named;
import com.sun.enterprise.config.serverbeans.Config;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.config.serverbeans.HttpService;
import com.sun.enterprise.config.serverbeans.VirtualServer;
import com.sun.enterprise.util.SystemPropertyConstants;
import org.glassfish.api.ActionReport;
import org.glassfish.api.ActionReport.ExitCode;
import org.glassfish.api.I18n;
import org.glassfish.api.Param;
import org.glassfish.api.admin.AdminCommand;
import org.glassfish.api.admin.AdminCommandContext;
import org.glassfish.api.admin.CommandRunner;
import org.glassfish.api.admin.ExecuteOn;
import org.glassfish.api.admin.RuntimeType;
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.config.support.CommandTarget;
import org.glassfish.config.support.TargetType;
import org.glassfish.grizzly.config.dom.NetworkConfig;
import org.glassfish.grizzly.config.dom.NetworkListener;
import org.glassfish.grizzly.config.dom.NetworkListeners;
import org.glassfish.grizzly.config.dom.ThreadPool;
import org.glassfish.grizzly.config.dom.Transport;
import org.glassfish.internal.api.Target;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.api.PerLookup;
import org.glassfish.logging.annotation.LogMessageInfo;
import org.glassfish.web.admin.monitor.HttpServiceStatsProviderBootstrap;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.config.ConfigSupport;
import org.jvnet.hk2.config.SingleConfigCode;
import org.jvnet.hk2.config.TransactionFailure;
import org.jvnet.hk2.config.Transactions;

/**
* Create Http Listener Command
*/
@Service(name = "create-http-listener")
@PerLookup
@I18n("create.http.listener")
@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE}) 
@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER,CommandTarget.CONFIG})
public class CreateHttpListener implements AdminCommand {

    @Param(name = "listeneraddress")
    String listenerAddress;
    @Param(name = "listenerport")
    String listenerPort;
    @Param(name = "defaultvs", optional = true)
    String defaultVS;
    @Param(name = "default-virtual-server", optional = true)
    String defaultVirtualServer;
    @Param(name = "servername", optional = true)
    String serverName;
    @Param(name = "xpowered", optional = true, defaultValue = "true")
    Boolean xPoweredBy;
    @Param(name = "acceptorthreads", optional = true)
    String acceptorThreads;
    @Param(name = "redirectport", optional = true)
    String redirectPort;
    @Param(name = "securityenabled", optional = true, defaultValue = "false")
    Boolean securityEnabled;
    @Param(optional = true, defaultValue = "true")
    Boolean enabled;
    @Param(optional = true, defaultValue = "false")
    Boolean secure; //FIXME
    @Param(name = "listener_id", primary = true)
    String listenerId;
    @Param(name = "target", optional = true, defaultValue = SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
    String target;
    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
    Config config;
    @Inject
    ServiceLocator services;
    @Inject
    CommandRunner runner;
    @Inject
    Domain domain;
    private static final String DEFAULT_TRANSPORT = "tcp";
    private NetworkConfig networkConfig = null;

    private static final Logger logger = HttpServiceStatsProviderBootstrap.logger;

    private static final ResourceBundle rb = logger.getResourceBundle();

    @LogMessageInfo(
            message = "The acceptor threads must be at least 1",
            level = "INFO")
    private static final String ACCEPTOR_THREADS_TOO_LOW = "AS-WEB-ADMIN-00003";

    @LogMessageInfo(
            message = "Listener {0} could not be created, actual reason: {1}",
            level = "INFO")
    private static final String CREATE_HTTP_LISTENER_FAIL = "AS-WEB-ADMIN-00004";

    @LogMessageInfo(
            message = "A default virtual server is required.  Please use --default-virtual-server to specify this value.",
            level = "INFO")
    private static final String CREATE_HTTP_LISTENER_VS_BLANK = "AS-WEB-ADMIN-00005";

    @LogMessageInfo(
            message = "--defaultVS and --default-virtual-server conflict.  Please use only --default-virtual-server to specify this value.",
            level = "INFO")
    private static final String CREATE_HTTP_LISTENER_VS_BOTH_PARAMS = "AS-WEB-ADMIN-00006";

    @LogMessageInfo(
            message = "Attribute value (default-virtual-server = {0}) is not found in list of virtual servers defined in config.",
            level = "INFO")
    private static final String CREATE_HTTP_LISTENER_VS_NOTEXISTS = "AS-WEB-ADMIN-00007";

    @LogMessageInfo(
            message = "Http Listener named {0} already exists.",
            level = "INFO")
    private static final String CREATE_HTTP_LISTENER_DUPLICATE = "AS-WEB-ADMIN-00008";

    @LogMessageInfo(
            message = "Port [{0}] is already taken for address [{1}], please choose another port.",
            level = "INFO")
    protected static final String PORT_IN_USE = "AS-WEB-ADMIN-00009";

    /**
     * Executes the command with the command parameters passed as Properties where the keys are the paramter names and
     * the values the parameter values
     *
     * @param context information
     */
    public void execute(AdminCommandContext context) {
        final ActionReport report = context.getActionReport();
        if(!validateInputs(report)) {
            return;
        }
        Target targetUtil = services.getService(Target.class);
        Config newConfig = targetUtil.getConfig(target);
        if (newConfig!=null) {
            config = newConfig;
        }
        networkConfig = config.getNetworkConfig();
        HttpService httpService = config.getHttpService();
        if (!(verifyUniqueName(report, networkConfig) && verifyUniquePort(report, networkConfig)
            && verifyDefaultVirtualServer(report))) {
            return;
        }
        VirtualServer vs = httpService.getVirtualServerByName(defaultVirtualServer);
        boolean listener = false;
        boolean protocol = false;
        boolean transport = false;
        try {
            transport = createOrGetTransport(null);
            protocol = createProtocol(context);
            createHttp(context);
            final ThreadPool threadPool = getThreadPool(networkConfig);
            listener = createNetworkListener(networkConfig, transport, threadPool);
            updateVirtualServer(vs);
        } catch (TransactionFailure e) {
            try {
                if (listener) {
                    deleteListener(context);
                }
                if (protocol) {
                    deleteProtocol(context);
                }
                if (transport) {
                    deleteTransport(context);
                }
            } catch (Exception e1) {
                if (logger.isLoggable(Level.INFO)) {
                    logger.log(Level.INFO, e.getMessage(), e);
                }
                throw new RuntimeException(e.getMessage());
            }
            if (logger.isLoggable(Level.INFO)) {
                logger.log(Level.INFO, e.getMessage(), e);
            }
            report.setMessage(MessageFormat.format(rb.getString(CREATE_HTTP_LISTENER_FAIL), listenerId, e.getMessage()));
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            report.setFailureCause(e);
            return;
        }
        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
    }

    private void updateVirtualServer(VirtualServer vs) throws TransactionFailure {
        //now change the associated virtual server
        ConfigSupport.apply(new SingleConfigCode<VirtualServer>() {
            public Object run(VirtualServer avs) throws PropertyVetoException {
                String DELIM = ",";
                String lss = avs.getNetworkListeners();
                boolean listenerShouldBeAdded = true;
                if (lss == null || lss.length() == 0) {
                    lss = listenerId; //the only listener in the list
                } else if (!lss.contains(listenerId)) { //listener does not already exist
                    if (!lss.endsWith(DELIM)) {
                        lss += DELIM;
                    }
                    lss += listenerId;
                } else { //listener already exists in the list, do nothing
                    listenerShouldBeAdded = false;
                }
                if (listenerShouldBeAdded) {
                    avs.setNetworkListeners(lss);
                }
                return avs;
            }
        }, vs);
    }

    private boolean createNetworkListener(NetworkConfig networkConfig, final boolean newTransport,
        final ThreadPool threadPool) throws TransactionFailure {
        ConfigSupport.apply(new SingleConfigCode<NetworkListeners>() {
            public Object run(NetworkListeners listenersParam)
                throws TransactionFailure {
                final NetworkListener newListener = listenersParam.createChild(NetworkListener.class);
                newListener.setName(listenerId);
                newListener.setAddress(listenerAddress);
                newListener.setPort(listenerPort);
                newListener.setTransport(newTransport ? listenerId : DEFAULT_TRANSPORT);
                newListener.setProtocol(listenerId);
                newListener.setThreadPool(threadPool.getName());
                newListener.setEnabled(enabled.toString());
                listenersParam.getNetworkListener().add(newListener);
                return newListener;
            }
        }, networkConfig.getNetworkListeners());
        services.<Transactions>getService(Transactions.class).waitForDrain();
        return true;
    }

    private boolean verifyDefaultVirtualServer(ActionReport report) {
        if (defaultVS == null && defaultVirtualServer == null) {
            report.setMessage(rb.getString(CREATE_HTTP_LISTENER_VS_BLANK));
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            return false;
        }
        if (defaultVS != null && defaultVirtualServer != null && !defaultVS.equals(defaultVirtualServer)) {
            report.setMessage(rb.getString(CREATE_HTTP_LISTENER_VS_BOTH_PARAMS));
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            return false;
        } else if (defaultVirtualServer == null && defaultVS != null) {
            defaultVirtualServer = defaultVS;
        }
        //no need to check the other things (e.g. id) for uniqueness
        // ensure that the specified default virtual server exists
        if (!defaultVirtualServerExists()) {
            report.setMessage(MessageFormat.format(rb.getString(CREATE_HTTP_LISTENER_VS_NOTEXISTS), defaultVirtualServer));
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            return false;
        }
        return true;
    }

    private boolean verifyUniquePort(ActionReport report, NetworkConfig networkConfig) {
        //check port uniqueness, only for same address
        for (NetworkListener listener : networkConfig.getNetworkListeners()
            .getNetworkListener()) {
            if (listener.getPort().trim().equals(listenerPort) &&
                listener.getAddress().trim().equals(listenerAddress)) {
                String def = "Port is already taken by another listener, choose another port.";
                String msg = MessageFormat.format(rb.getString(PORT_IN_USE), listenerPort, listenerAddress);
                report.setMessage(msg);
                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
                return false;
            }
        }
        return true;
    }

    private boolean validateInputs(final ActionReport report) {
        if(acceptorThreads != null && Integer.parseInt(acceptorThreads) < 1) {
            report.setMessage(MessageFormat.format(rb.getString(ACCEPTOR_THREADS_TOO_LOW), listenerId));
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            return false;
        }
        return true;
    }
    private boolean verifyUniqueName(ActionReport report, NetworkConfig networkConfig) {
        // ensure we don't already have one of this name
        for (NetworkListener listener : networkConfig.getNetworkListeners().getNetworkListener()) {
            if (listener.getName().equals(listenerId)) {
                report.setMessage(MessageFormat.format(rb.getString(CREATE_HTTP_LISTENER_DUPLICATE), listenerId));
                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
                return false;
            }
        }
        return true;
    }

    private ThreadPool getThreadPool(NetworkConfig config) {
        final List<ThreadPool> pools = config.getParent(Config.class).getThreadPools().getThreadPool();
        ThreadPool target = null;
        for (ThreadPool pool : pools) {
            if ("http-thread-pool".equals(pool.getName())) {
                target = pool;
            }
        }
        if (target == null && !pools.isEmpty()) {
            target = pools.get(0);
        }
        return target;
    }

    private boolean createOrGetTransport(final AdminCommandContext context) throws TransactionFailure {
        boolean newTransport = false;
        for (Transport t : networkConfig.getTransports().getTransport()) {
            if (!t.getName().equals(DEFAULT_TRANSPORT)) {
                 newTransport = true;
            }
        }
        if (newTransport) {
            final CreateTransport command = (CreateTransport) runner
                .getCommand("create-transport", context.getActionReport(), context.getLogger());
            command.transportName = listenerId;
            command.acceptorThreads = acceptorThreads;
            command.target = target;
            command.execute(context);
            checkProgress(context);
            newTransport = true;
        }
        return newTransport;
    }

    private boolean createProtocol(final AdminCommandContext context) throws TransactionFailure {
        final CreateProtocol command = (CreateProtocol) runner
            .getCommand("create-protocol", context.getActionReport(), context.getLogger());
        command.protocolName = listenerId;
        command.securityEnabled = securityEnabled;
        command.target = target;
        command.execute(context);
        checkProgress(context);
        return true;
    }

    private boolean createHttp(final AdminCommandContext context) throws TransactionFailure {
        final CreateHttp command = (CreateHttp) runner
            .getCommand("create-http", context.getActionReport(), context.getLogger());
        command.protocolName = listenerId;
        command.defaultVirtualServer = defaultVirtualServer;
        command.xPoweredBy = xPoweredBy;
        command.serverName = serverName;
        command.target = target;
        command.execute(context);
        checkProgress(context);
        return true;
    }

    private void checkProgress(final AdminCommandContext context) throws TransactionFailure {
        if(context.getActionReport().getActionExitCode() != ExitCode.SUCCESS) {
            throw new TransactionFailure(context.getActionReport().getMessage());
        }
    }

    private boolean deleteProtocol(final AdminCommandContext context) {
        final DeleteProtocol command = (DeleteProtocol) runner
            .getCommand("delete-protocol", context.getActionReport(), context.getLogger());
        command.protocolName = listenerId;
        command.target = target;
        command.execute(context);
        return true;
    }

    private boolean deleteTransport(final AdminCommandContext context) {
        final DeleteTransport command = (DeleteTransport) runner
            .getCommand("delete-transport", context.getActionReport(), context.getLogger());
        command.transportName = listenerId;
        command.target = target;
        command.execute(context);
        return true;
    }

    private boolean deleteListener(final AdminCommandContext context) {
        final DeleteNetworkListener command = (DeleteNetworkListener) runner
            .getCommand("delete-network-listener", context.getActionReport(), context.getLogger());
        command.networkListenerName = listenerId;
        command.target = target;
        command.execute(context);
        return true;
    }

    private boolean defaultVirtualServerExists() {
        return (defaultVirtualServer != null) && (
                config.getHttpService().getVirtualServerByName(defaultVirtualServer) != null);
    }
}
TOP

Related Classes of org.glassfish.web.admin.cli.CreateHttpListener

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.