Package com.sun.enterprise.security.admin.cli

Source Code of com.sun.enterprise.security.admin.cli.SecureAdminCommand$ConfigLevelContext

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

import com.sun.enterprise.config.serverbeans.Config;
import com.sun.enterprise.config.serverbeans.Configs;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.config.serverbeans.MessageSecurityConfig;
import com.sun.enterprise.config.serverbeans.ProviderConfig;
import com.sun.enterprise.config.serverbeans.SecureAdmin;
import com.sun.enterprise.config.serverbeans.SecureAdminHelper.SecureAdminCommandException;
import com.sun.enterprise.config.serverbeans.SecurityService;
import com.sun.grizzly.config.dom.FileCache;
import com.sun.grizzly.config.dom.Http;
import com.sun.grizzly.config.dom.HttpRedirect;
import com.sun.grizzly.config.dom.NetworkConfig;
import com.sun.grizzly.config.dom.NetworkListener;
import com.sun.grizzly.config.dom.PortUnification;
import com.sun.grizzly.config.dom.Protocol;
import com.sun.grizzly.config.dom.ProtocolFinder;
import com.sun.grizzly.config.dom.Protocols;
import com.sun.grizzly.config.dom.Ssl;
import com.sun.logging.LogDomains;
import java.beans.PropertyVetoException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.glassfish.api.ActionReport;
import org.glassfish.api.admin.AdminCommand;
import org.glassfish.api.admin.AdminCommandContext;
import org.jvnet.hk2.annotations.Inject;
import org.jvnet.hk2.config.ConfigSupport;
import org.jvnet.hk2.config.SingleConfigCode;
import org.jvnet.hk2.config.Transaction;
import org.jvnet.hk2.config.TransactionFailure;
import org.jvnet.hk2.config.types.Property;

/**
* Provides common behavior for the enable and disable secure admin commands.
* <p>
* This class, and the concrete subclasses EnableSecureAdminCommand and
* DisableSecureAdminComment, define what must be done in terms of steps.
* Each step has enable work and disable work.  This class builds
* arrays of steps, one array which operates at the domain level and one which
* operates at the config level.  The enable work of these steps is run in order through
* the array to fully
* enable secure admin, and the disable work of these steps are run in REVERSE
* order to fully disable secure admin.
* <p>
* I have defined the steps and their enable and disable work here, together
* in some inner classes, rather than separately in the EnableSecureAdminCommand
* and DisableSecureAdminCommand classes to try to keep common details together.
* The concrete subclasses can override a few methods, in particular overriding
* methods which return an Iterator over the steps to be performed.  This way we
* have a single array of all the steps, with each class returning a forward-running
* or reverse-running iterator over those steps.
*
* @author Tim Quinn
*/
public abstract class SecureAdminCommand implements AdminCommand {

    final static String SEC_ADMIN_LISTENER_PROTOCOL_NAME = "sec-admin-listener";
    private final static String REDIRECT_PROTOCOL_NAME = "admin-http-redirect";
    public final static String ADMIN_LISTENER_NAME = "admin-listener";
    static final String DAS_CONFIG_NAME = "server-config";
    final static String PORT_UNIF_PROTOCOL_NAME = "pu-protocol";
       

    static final Logger logger = LogDomains.getLogger(SecureAdminCommand.class,
                                        LogDomains.ADMIN_LOGGER);


    @Inject
    protected Domain domain;

    /**
     * Applies changes other than whether secure admin is enabled or disabled
     * to the secure-admin element.
     * <p>
     * This method is primarily for the enable processing to apply the
     * admin and/or instance alias values, if specified on the enable-secure-admin
     * command, to the secure-admin element.
     *
     * @param secureAdmin_w
     * @return
     */
    boolean updateSecureAdminSettings(
            final SecureAdmin secureAdmin_w) throws TransactionFailure {
        /*
         * Default implementation - currently used by DisableSecureAdminCommand
         * and overridden by EnableSecureAdminCommand.
         */
        return true;
    }

    interface Context {
    }

    /**
     * Work to be performed - either for enable or disable - in a step.
     * @param <T>
     */
    interface Work<T extends Context> {
        boolean run(final T context) throws TransactionFailure;
    }

    /**
     * A step to be performed during enabling or disabling secure admin.
     *
     * @param <T> either TopLevelContext or ConfigLevelContext, depending on
     * whether the step applies per-domain or per-config.
     */
    interface Step<T extends Context> {
        Work<T> enableWork();
        Work<T> disableWork();
    }

//    interface TopLevelStep {
//        TopLevelWork enableWork();
//        TopLevelWork disableWork();
//    }

//    /**
//     * The contract for performing the work associate with a single step of
//     * enabling or disabling secure admin.
//     */
//    interface SecureAdminWork<T> {
//        boolean run(
//                Transaction t,
//                AdminCommandContext context,
//                T writeableConfigBean) throws TransactionFailure;
//    }
//
//    /**
//     * Enabling or disabling secure admin each involves multiple steps.
//     * Each step has some logic run during enable and some logic run during disable
//     * @param <T>
//     */
//    interface SecureAdminStep<T> {
//        SecureAdminWork<T> enableWork();
//        SecureAdminWork<T> disableWork();
//    }

    static class AbstractContext implements Context {
    }

    /**
     * Keeps track of whether we've found writable versions of various
     * ConfigBeans.
     */
    static class TopLevelContext extends AbstractContext {

        private final Transaction t;
        private final Domain d;
        private Domain d_w = null;

        private SecureAdmin secureAdmin_w = null;

        TopLevelContext(
                final Transaction t,
                final Domain d) {
            this.t = t;
            this.d = d;
        }

        Domain writableDomain() throws TransactionFailure {
            if (d_w == null) {
                d_w = t.enroll(d);
            }
            return d_w;
        }

        /*
         * Gets the SecureAdmin object in writeable form, from the specified
         * domain if the SecureAdmin object already exists or by creating a new
         * one attached to the domain if one does not already exist.
         */
        SecureAdmin writableSecureAdmin() throws TransactionFailure {
            if (secureAdmin_w == null) {

                /*
                 * Create the secure admin node if it is not already there.
                 */
                SecureAdmin secureAdmin = d.getSecureAdmin();
                if (secureAdmin == null) {
                    secureAdmin_w = writableDomain().createChild(SecureAdmin.class);
                    writableDomain().setSecureAdmin(secureAdmin_w);
                } else {
                    /*
                     * It already existed, so join it to the transaction.
                     */
                    secureAdmin_w = t.enroll(secureAdmin);
                }
            }
            return secureAdmin_w;
        }
    }

    /**
     * Tracks writable config beans for each configuration.
     */
    static class ConfigLevelContext extends AbstractContext {

        private final Transaction t;
        private final Config config_w;
        private final TopLevelContext topLevelContext;

        private Protocols protocols_w = null;
        private Map<String,Protocol> namedProtocols_w = new
                HashMap<String,Protocol>();


        ConfigLevelContext(
                final TopLevelContext topLevelContext,
                final Config config_w) {
            this.topLevelContext = topLevelContext;
            this.t = topLevelContext.t;
            this.config_w = config_w;
        }

        private Protocols writableProtocols() throws TransactionFailure {
            if (protocols_w == null) {
                final NetworkConfig nc = config_w.getNetworkConfig();
                if (nc == null) {
                    return null;
                }
                final Protocols p = nc.getProtocols();
                protocols_w = t.enroll(p);
            }
            return protocols_w;
        }

        private Protocol writableProtocol(final String protocolName,
                final boolean isSecure) throws TransactionFailure {
            Protocol p_w = namedProtocols_w.get(protocolName);
            if (p_w == null) {
                /*
                 * Try to find an existing entry for this protocol.
                 */
                final Protocol p_r = findProtocol(protocolName);
                if (p_r == null) {
                    final Protocols ps_w = writableProtocols();
                    if (ps_w == null) {
                        return null;
                    }
                    p_w = ps_w.createChild(Protocol.class);
                    p_w.setName(protocolName);
                    ps_w.getProtocol().add(p_w);
                } else {
                    p_w = t.enroll(p_r);
                }
                namedProtocols_w.put(protocolName, p_w);
            }
            p_w.setSecurityEnabled(Boolean.toString(isSecure));
            return p_w;
        }

        private Protocol findProtocol(final String protocolName) {
            final NetworkConfig nc = config_w.getNetworkConfig();
            if (nc == null) {
                return null;
            }
            final Protocols ps = nc.getProtocols();
            if (ps == null) {
                return null;
            }
            return ps.findProtocol(protocolName);
        }

        private void deleteProtocol(
                    final String protocolName) throws TransactionFailure {
                final Protocols ps_w = writableProtocols();
                if (ps_w == null) {
                    return;
                }
                final Protocol doomedProtocol = ps_w.findProtocol(protocolName);
                if (doomedProtocol != null) {
                    ps_w.getProtocol().remove(doomedProtocol);
                }
            }
    }

    /**
     * Updates the secure-admin element itself.
     * <p>
     * The concrete command implementation classes implement updateSecureAdminSettings
     * differently but they expose the same method signature, so onEnable and
     * onDisable just invoke the same method.
     */
    private Step<TopLevelContext> perDomainStep = new Step<TopLevelContext>() {

        /**
         * Sets enabled=true/false on the secure-admin element.
         */
        private void updateSecureAdminEnabledSetting(
                final SecureAdmin secureAdmin_w,
                final boolean newEnabledValue) {
            secureAdmin_w.setEnabled(Boolean.toString(newEnabledValue));
        }

        /*
         * Both the enable and disable steps for the "secure admin element only"
         * task set the enabled value and then let the concrete command
         * subclass do any additional work.
         */
        class TopLevelWork implements Work<TopLevelContext> {

            private final boolean newEnabledState;

            TopLevelWork(final boolean newEnabledState) {
                this.newEnabledState = newEnabledState;
            }

            @Override
            public boolean run(final TopLevelContext context) throws TransactionFailure {
                final SecureAdmin secureAdmin_w = context.writableSecureAdmin();
                updateSecureAdminEnabledSetting(
                        secureAdmin_w, newEnabledState);
                /*
                 * The subclass might have overridden updateSecureAdminSettings.
                 * Give it a change to run logic specific to enable or disable.
                 */
                return SecureAdminCommand.this.updateSecureAdminSettings(secureAdmin_w);
            }
        }
       
        @Override
        public Work<TopLevelContext> enableWork() {
            return new TopLevelWork(true);
            };

        @Override
        public Work<TopLevelContext> disableWork() {
            return new TopLevelWork(false);
        }
    };

    /**
     * Manages the sec-admin-listener protocol.
     */
    private Step<ConfigLevelContext> secAdminListenerProtocolStep = new Step<ConfigLevelContext>() {

        private static final String ASADMIN_VIRTUAL_SERVER_NAME = "__asadmin";

        private static final String CLIENT_AUTH_VALUE = "want";
        private static final String CLASSNAME_VALUE = "com.sun.enterprise.security.ssl.GlassfishSSLImpl";
        private static final String AUTH_LAYER_NAME = "HttpServlet";
        private static final String PROVIDER_ID_VALUE = "GFConsoleAuthModule";
        private static final String REST_AUTH_URL_PROPERTY_NAME = "restAuthURL";

        private Http writeableHttpWithFileCacheChild(final Transaction t,
                final Protocol secAdminListenerProtocol_w) throws TransactionFailure {
            /*
             * Because of the calling context, the secAdminListenerProtocol is already
             * writeable -- it was just created moments ago and has not yet
             * been committed.
             */
            Http http_w = null;
            Http http = secAdminListenerProtocol_w.getHttp();
            if (http == null) {
                http_w = secAdminListenerProtocol_w.createChild(Http.class);
                secAdminListenerProtocol_w.setHttp(http_w);
            } else {
                http_w = t.enroll(http);
            }
            http_w.setDefaultVirtualServer(ASADMIN_VIRTUAL_SERVER_NAME);
            http_w.setEncodedSlashEnabled("true");
           
            final FileCache cache = http_w.createChild(FileCache.class);
//            cache.setEnabled("false");
            http_w.setFileCache(cache);
                   
            return http_w;
        }

        private Ssl writeableSsl(final Transaction t,
                final Protocol secAdminListenerProtocol_w,
                final String certNickname) throws TransactionFailure {
            Ssl ssl_w = null;
            Ssl ssl = secAdminListenerProtocol_w.getSsl();
            if (ssl == null) {
                ssl_w = secAdminListenerProtocol_w.createChild(Ssl.class);
                secAdminListenerProtocol_w.setSsl(ssl_w);
            } else {
                ssl_w = t.enroll(ssl);
            }
            ssl_w.setClientAuth(CLIENT_AUTH_VALUE);
            ssl_w.setClassname(CLASSNAME_VALUE);
            ssl_w.setCertNickname(certNickname);
            return ssl_w;
        }
       
        private String chooseCertNickname(
                final String configName,
                final String dasAlias,
                final String instanceAlias) throws TransactionFailure {
            return (configName.equals(DAS_CONFIG_NAME) ? dasAlias : instanceAlias);
        }

        private ProviderConfig findProviderConfig(
                final Config config_w) {
            final SecurityService ss = config_w.getSecurityService();
            if (ss == null) {
                return null;
            }
            for (MessageSecurityConfig msc : ss.getMessageSecurityConfig()) {
                if (msc.getAuthLayer().equals(AUTH_LAYER_NAME)) {
                    for (ProviderConfig pc : msc.getProviderConfig()) {
                        if (pc.getProviderId().equals(PROVIDER_ID_VALUE)) {
                            return pc;
                        }
                    }
                }
            }
            return null;
        }

        private void secureRestAuthURL(final Transaction t,
                final Config config_w,
                final boolean newEnabledState) throws TransactionFailure {
            try {
                final ProviderConfig pc = findProviderConfig(config_w);
                if (pc == null) {
                    return;
                }
                final Property p = pc.getProperty(REST_AUTH_URL_PROPERTY_NAME);
                final Property p_w = t.enroll(p);
                final String urlText = p_w.getValue();
                final StringBuilder newURLString = new StringBuilder();
                newURLString.append(newEnabledState ? "https" : "http");
                newURLString.append("://").append(urlText.substring(urlText.indexOf("//") + "//".length()));
                p_w.setValue(newURLString.toString());
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }

        @Override
        public Work<ConfigLevelContext> enableWork() {
            return new Work<ConfigLevelContext>() {

                @Override
                public boolean run(final ConfigLevelContext context) throws TransactionFailure {
                    /*
                     * Get an existing or new writeable sec-admin-listener protocol.
                     */
                    final Protocol secAdminListenerProtocol_w =
                            context.writableProtocol(SEC_ADMIN_LISTENER_PROTOCOL_NAME,
                            true);

                    /*
                     * It seems possible to create configs without network listeners
                     * and children.  In that case it's not a real config so we
                     * will skip it.
                     */
                    if (secAdminListenerProtocol_w == null) {
                        return false;
                    }
                   
                    /*
                     * Get an existing or create a new writeable http child under the new protocol.
                     */
                    final Http http = writeableHttpWithFileCacheChild(context.t, secAdminListenerProtocol_w);

                    /*
                     * Get an existing or create a new writeable ssl child under the new protocol.
                     * Which cert nickname we set depends on whether this is the DAS's config
                     * we're working on or an instance's. 
                     */
                    final Ssl ssl = writeableSsl(context.t, secAdminListenerProtocol_w,
                            chooseCertNickname(
                                context.config_w.getName(),
                                context.topLevelContext.writableSecureAdmin().dasAlias(),
                                context.topLevelContext.writableSecureAdmin().instanceAlias()));

                    secureRestAuthURL(context.t, context.config_w, true);
                    return true;
                }
            };
        }

        @Override
        public Work<ConfigLevelContext> disableWork() {
            return new Work<ConfigLevelContext>() {

                @Override
                public boolean run(ConfigLevelContext context) throws TransactionFailure {


                    context.deleteProtocol(SEC_ADMIN_LISTENER_PROTOCOL_NAME);

                    secureRestAuthURL(context.t, context.config_w, false);
                    return true;
                }
            };
        }
    };

    private enum ProtocolFinderInfo {
        HTTP_FINDER("http-finder", SEC_ADMIN_LISTENER_PROTOCOL_NAME),
        ADMIN_HTTP_REDIRECT_FINDER("admin-http-redirect", REDIRECT_PROTOCOL_NAME);

        private final String name;
        private final String protocolName;
        private final String classname = "com.sun.grizzly.config.HttpProtocolFinder";

        private ProtocolFinderInfo(final String name, final String protocolName) {
            this.name = name;
            this.protocolName = protocolName;
        }

    }

    private Step<ConfigLevelContext> secAdminPortUnifAndRedirectStep = new Step<ConfigLevelContext>() {

        private final static String PORT_UNIF_PROTOCOL_NAME = "pu-protocol";
        private final static String UNSECURE_ADMIN_LISTENER_PROTOCOL_NAME = "admin-listener";

        private final static String HTTP_FINDER_PROTOCOL_FINDER_NAME = "http-finder";
        private final static String ADMIN_HTTP_REDIRECT_FINDER_NAME = "admin-http-redirect";

        private final static String PROTOCOL_FINDER_CLASSNAME = "com.sun.grizzly.confing.HttpProtocolFinder";


        private HttpRedirect writeableHttpRedirect(
                final Transaction t,
                final Protocol adminHttpRedirectProtocol_w) throws TransactionFailure {
            HttpRedirect redirect = adminHttpRedirectProtocol_w.getHttpRedirect();
            HttpRedirect redirect_w;
            if (redirect == null) {
                redirect_w = adminHttpRedirectProtocol_w.createChild(HttpRedirect.class);
                adminHttpRedirectProtocol_w.setHttpRedirect(redirect_w);
            } else {
                redirect_w = t.enroll(redirect);
            }
            redirect_w.setSecure(Boolean.TRUE.toString());
            return redirect_w;
        }

        private PortUnification writeablePortUnification(
                final Transaction t,
                final Protocol protocol_w) throws TransactionFailure {
            PortUnification pu_w;
            PortUnification pu = protocol_w.getPortUnification();
            if (pu == null) {
                pu_w = protocol_w.createChild(PortUnification.class);
                protocol_w.setPortUnification(pu_w);
            } else {
                pu_w = t.enroll(pu);
            }
            return pu_w;
        }

        private ProtocolFinder writeableProtocolFinder(
                final Transaction t,
                final PortUnification pu_w,
                final ProtocolFinderInfo finderInfo) throws TransactionFailure {
            ProtocolFinder pf_w = null;
            for (ProtocolFinder pf : pu_w.getProtocolFinder()) {
                if (pf.getName().equals(finderInfo.name)) {
                    pf_w = t.enroll(pf);
                    break;
                }
            }
            if (pf_w == null) {
                pf_w = pu_w.createChild(ProtocolFinder.class);
                pu_w.getProtocolFinder().add(pf_w);
            }
            pf_w.setName(finderInfo.name);
            pf_w.setClassname(finderInfo.classname);
            pf_w.setProtocol(finderInfo.protocolName);
            return pf_w;
        }

        private NetworkListener writableNetworkListener(
                final Transaction t,
                final Config config_w,
                final String listenerName) throws TransactionFailure {
            NetworkListener nl_w = null;
            final NetworkConfig nc = config_w.getNetworkConfig();
            if (nc == null) {
                return null;
            }
            NetworkListener nl = nc.getNetworkListener(listenerName);
            if (nl == null) {
                return null;
            } else {
                nl_w = t.enroll(nl);
            }
            return nl_w;
        }

       

        private void assignAdminListenerProtocol(
                final Transaction t,
                final Config config_w,
                final String protocolName) throws TransactionFailure {
            final NetworkListener nl_w = writableNetworkListener(t, config_w, ADMIN_LISTENER_NAME);
            if (nl_w != null) {
                nl_w.setProtocol(protocolName);
            }
        }

        @Override
        public Work<ConfigLevelContext> enableWork() {
            return new Work<ConfigLevelContext>() {

                @Override
                public boolean run(ConfigLevelContext context) throws TransactionFailure {
                    /*
                     * Get an existing or new writeable admin-http-redirect protocol.
                     */

                    final Protocol adminHttpRedirectProtocol_w =
                            context.writableProtocol(
                            REDIRECT_PROTOCOL_NAME,
                            false);

                    if (adminHttpRedirectProtocol_w == null) {
                        return true;
                    }

                    final HttpRedirect httpRedirect_w = writeableHttpRedirect(
                            context.t, adminHttpRedirectProtocol_w);

                    final Protocol puProtocol_w = context.writableProtocol(
                            PORT_UNIF_PROTOCOL_NAME,
                            false);

                    final PortUnification portUnif_w = writeablePortUnification(
                            context.t, puProtocol_w);

                    final ProtocolFinder httpFinder = writeableProtocolFinder(
                            context.t, portUnif_w, ProtocolFinderInfo.HTTP_FINDER);

                    final ProtocolFinder adminHttpRedirectFinder = writeableProtocolFinder(
                            context.t, portUnif_w, ProtocolFinderInfo.ADMIN_HTTP_REDIRECT_FINDER);

                    assignAdminListenerProtocol(context.t, context.config_w, PORT_UNIF_PROTOCOL_NAME);
                   
                    return true;
                }
            };
        }

        @Override
        public Work<ConfigLevelContext> disableWork() {
            return new Work<ConfigLevelContext>() {

            @Override
                public boolean run(final ConfigLevelContext context) throws TransactionFailure {
                    final Config config_w = context.config_w;
                    final Transaction t = context.t;
                    assignAdminListenerProtocol(t, config_w, UNSECURE_ADMIN_LISTENER_PROTOCOL_NAME);

                    context.deleteProtocol(PORT_UNIF_PROTOCOL_NAME);
                    context.deleteProtocol(REDIRECT_PROTOCOL_NAME);
                    return true;
                }

            };
        }

    };

//    /**
//     * Details for managing the protocol associated directly with the
//     * admin listener.  This logic takes care of creating
//     * the sec-admin-listener protocol and assoociating it with
//     * the admin listener, or deleting the sec-admin-listener protocol and
//     * associating the admin listener back with the original protocol.
//     */
//    private SecureAdminWork adminListenerProtocolSetting = new SecureAdminWork<Config>() {
//
//        private final static String ADMIN_LISTENER_NETWORK_LISTENER_NAME = "admin-listener";
//        private final static String ORIGINAL_ADMIN_LISTENER_PROTOCOL_NAME = "admin-listener";
//
//
//        @Override
//        public boolean onEnable(
//                final Transaction t,
//                final AdminCommandContext context,
//                final Config tConfig) throws TransactionFailure {
//            writeableAdminNetworkListener(tConfig).
//                    setProtocol(SEC_ADMIN_LISTENER_PROTOCOL_NAME);
//            return true;
//        }
//
//        @Override
//        public boolean onDisable(
//                final Transaction t,
//                final AdminCommandContext context,
//                final Config tConfig
//                ) throws TransactionFailure {
//            writeableAdminNetworkListener(tConfig).
//                    setProtocol(ORIGINAL_ADMIN_LISTENER_PROTOCOL_NAME);
//            return true;
//        }
//
//        private NetworkListener writeableAdminNetworkListener(
//                final Config tConfig) throws TransactionFailure {
//            return tConfig.getNetworkConfig().
//                    getNetworkListener(ADMIN_LISTENER_NETWORK_LISTENER_NAME);
//        }

//        private NetworkListener writeableAdminNetworkListener(
//                final Transaction t,
//                final Config tConfig) throws TransactionFailure {
//            ConfigSupport.apply(new SingleConfigCode<NetworkListener>() {
//                @Override
//                public Object run(NetworkListener nl) throws PropertyVetoException, TransactionFailure {
//
//                    try {
//
//                        for (Config c : configs.getConfig()) {
//                            final MessagePart partForThisConfig = report.getTopMessagePart().addChild();
//
//                            /*
//                             * Again, delegate to update the admin
//                             * listener configuration.
//                             */
//                            updateAdminListenerConfig(context, t, c, partForThisConfig);
//                        }
//
//                        t.commit();
//                    } catch (RetryableException ex) {
//                        throw new RuntimeException(ex);
//                    }
//
//                    return Boolean.TRUE;
//                }
//            }, tConfig.getNetworkConfig().getNetworkListener(ADMIN_LISTENER_NETWORK_LISTENER_NAME));
//        }
//
//    };

    /**
     * Tasks executed once per enable or disable.
     */
    final Step<TopLevelContext>[] secureAdminSteps =
            new Step[] {
        perDomainStep
    };

   
    /**
     * Tasks executed once per config during an enable or disable.
     */
    final Step<ConfigLevelContext>[] perConfigSteps =
            new Step[] {
        secAdminListenerProtocolStep,
        secAdminPortUnifAndRedirectStep
    };

    /**
     * Returns the error key for finding a message describing an error
     * during the operation - either enable or disable.
     * <p>
     * Each concrete subclass overrides this to supply the relevant message key.
     *
     * @return the message key corresponding to the error message to display
     */
    protected abstract String transactionErrorMessageKey();

    /**
     * Returns an Iterator over the work (enable work for enable-secure-admin,
     * disable for disable-secure-admin) for the steps related to
     * just the top-level secure-admin element.
     *
     * @return
     */
    abstract Iterator<Work<TopLevelContext>> secureAdminSteps();

    /**
     * Returna an Iterator over the work related to each configuration that
     * has to be modified.
     *
     * @return
     */
    abstract Iterator<Work<ConfigLevelContext>> perConfigSteps();

    /**
     * Performs the enable/disable logic for secure admin.
     * <p>
     * This is separate from the execute method so it can be invoked during
     * upgrade.
     *
     * @throws TransactionFailure
     */
    public void run() throws TransactionFailure, SecureAdminCommandException {
        ConfigSupport.apply(new SingleConfigCode<Domain>() {
            @Override
            public Object run(Domain domain_w) throws PropertyVetoException, TransactionFailure {

                // get the transaction
                final Transaction t = Transaction.getTransaction(domain_w);
                final TopLevelContext topLevelContext =
                        new TopLevelContext(t, domain_w);
                if (t!=null) {

                    /*
                     * Do the work on just the secure-admin element.
                     */
                    for (Iterator<Work<TopLevelContext>> it = secureAdminSteps(); it.hasNext();) {
                        final Work<TopLevelContext> step = it.next();
                        if ( ! step.run(topLevelContext) ) {
                            t.rollback();
                            return Boolean.FALSE;
                        }
                    }

                    /*
                     * Now apply the required changes to the admin listener
                     * in the DAS configuration.
                     */
                    final Configs configs = domain_w.getConfigs();
                    final Config c = configs.getConfigByName(DAS_CONFIG_NAME);
                    final Config c_w = t.enroll(c);
                    ConfigLevelContext configLevelContext =
                            new ConfigLevelContext(topLevelContext, c_w);
                    for (Iterator<Work<ConfigLevelContext>> it = perConfigSteps(); it.hasNext();) {
                        final Work<ConfigLevelContext> step = it.next();
                        if ( ! step.run(configLevelContext)) {
                            t.rollback();
                            return Boolean.FALSE;
                        }
                    }

                }

                return Boolean.TRUE;
            }
        }, domain);
    }
    /**
     * Executes the particular xxx-secure-admin command (enable or disable).
     * @param context
     */
    @Override
    public void execute(final AdminCommandContext context) {
        final ActionReport report = context.getActionReport();

        try {
            report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
            run();
            report.setMessage(Strings.get("restartReq"));
        } catch (TransactionFailure ex) {
            report.failure(context.getLogger(), Strings.get(transactionErrorMessageKey()), ex);
        } catch (SecureAdminCommandException ex) {
            report.failure(context.getLogger(), ex.getLocalizedMessage());
        }
    }
   
    /*
     * Exeutes the command with no action report.  Primarily useful from the
     * upgrade class (which does not have a convenient action report).
     */
    void execute() throws TransactionFailure, SecureAdminCommandException {
        try {
            run();
        } catch (TransactionFailure ex) {
            logger.log(Level.SEVERE, Strings.get(transactionErrorMessageKey()), ex);
            throw ex;
        } catch (SecureAdminCommandException ex) {
            logger.log(Level.SEVERE, ex.getLocalizedMessage());
            throw ex;
        }
    }
}
TOP

Related Classes of com.sun.enterprise.security.admin.cli.SecureAdminCommand$ConfigLevelContext

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.