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

com.sun.enterprise.admin.util.ClusterOperationUtil Maven / Gradle / Ivy

There is a newer version: 10.0-b28
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2010 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.util;

import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.enterprise.util.StringUtils;
import com.sun.enterprise.admin.remote.RemoteAdminCommand;

import java.io.File;

import com.sun.logging.LogDomains;
import org.glassfish.api.ActionReport;
import org.glassfish.api.admin.*;
import org.glassfish.internal.api.Target;
import org.glassfish.config.support.CommandTarget;
import org.jvnet.hk2.component.Habitat;

import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;

/**
 *
 */
public class ClusterOperationUtil {
    private static final Logger logger = LogDomains.getLogger(ClusterOperationUtil.class,
                                        LogDomains.ADMIN_LOGGER);
    private static final LocalStringManagerImpl strings =
                        new LocalStringManagerImpl(ClusterOperationUtil.class);

    //TODO : Begin temp fix for undoable commands
    private static List completedInstances = new ArrayList();

    public static List getCompletedInstances() {
        return completedInstances;
    }

    public static void clearInstanceList() {
        completedInstances.clear();
    }
    //TODO : End temp fix for undoable commands

    public static ActionReport.ExitCode replicateCommand(String commandName,
                                                   FailurePolicy failPolicy,
                                                   FailurePolicy offlinePolicy,
                                                   List instancesForReplication,
                                                   AdminCommandContext context,
                                                   ParameterMap parameters,
                                                   Habitat habitat) {
        return replicateCommand(commandName, failPolicy, offlinePolicy, 
                instancesForReplication, context, parameters, habitat, null);
    }

    /**
     * Replicates a given command on the given list of targets, optionally gathering
     * downloaded result payloads from the instance commands into a directory.
     * 

* If intermediateDownloadDir is non-null, then any files returned from * the instances in the payload of the HTTP response will be stored in a * directory tree like this: *

     * ${intermediateDownloadDir}/
     *     ${instanceA}/
     *         file(s) returned from instance A
     *     ${instanceB}/
     *         file(s) returned from instance B
     *     ...
     * 
* where ${instanceA}, ${instanceB}, etc. are the names of the instances to * which the command was replicated. This method does no further processing * on the downloaded files but leaves that to the calling command. */ public static ActionReport.ExitCode replicateCommand(String commandName, FailurePolicy failPolicy, FailurePolicy offlinePolicy, List instancesForReplication, AdminCommandContext context, ParameterMap parameters, Habitat habitat, final File intermediateDownloadDir) { ActionReport.ExitCode returnValue = ActionReport.ExitCode.SUCCESS; InstanceStateService instanceState = habitat.getComponent(InstanceStateService.class); validateIntermediateDownloadDir(intermediateDownloadDir); RemoteInstanceCommandHelper rich = new RemoteInstanceCommandHelper(habitat); Map> futures = new HashMap>(); try { for(Server svr : instancesForReplication) { if (instanceState.getState(svr.getName()) == InstanceState.StateType.NEVER_STARTED) { // Do not replicate commands to instances that have never been started. continue; } String host = svr.getAdminHost(); int port = rich.getAdminPort(svr); ActionReport aReport = context.getActionReport().addSubActionsReport(); InstanceCommandResult aResult = new InstanceCommandResult(); InstanceCommandExecutor ice = new InstanceCommandExecutor(habitat, commandName, failPolicy, offlinePolicy, svr, host, port, logger, parameters, aReport, aResult); if (CommandTarget.DAS.isValid(habitat, ice.getServer().getName())) continue; if (intermediateDownloadDir != null) { ice.setFileOutputDirectory( subdirectoryForInstance(intermediateDownloadDir, ice)); } Future f = instanceState.submitJob(svr, ice, aResult); if(f==null) { logger.severe(strings.getLocalString("clusterutil.instancehasnostate", "Could not find state of instance registered in the state service")); continue; } futures.put(svr.getName(), f); logger.fine(strings.getLocalString("dynamicreconfiguration.diagnostics.jobsubmitted", "Successfully submitted command {0} for execution at instance {1}", commandName, svr.getName())); } } catch (Exception ex) { ActionReport aReport = context.getActionReport().addSubActionsReport(); ActionReport.ExitCode finalResult = FailurePolicy.applyFailurePolicy(failPolicy, ActionReport.ExitCode.FAILURE); aReport.setActionExitCode(finalResult); aReport.setMessage(strings.getLocalString("glassfish.clusterexecutor.replicationfailed", "Error during command replication : {0}", ex.getMessage())); context.getLogger().severe("Error during command replication; Reason : " + ex.getLocalizedMessage()); if(returnValue ==ActionReport.ExitCode.SUCCESS) returnValue = finalResult; } boolean gotFirstResponse = false; long maxWaitTime = RemoteAdminCommand.getReadTimeout(); long timeBeforeAsadminTimeout = maxWaitTime; long waitStart = System.currentTimeMillis(); for(String s : futures.keySet()) { ActionReport.ExitCode finalResult; try { logger.fine(strings.getLocalString("dynamicreconfiguration.diagnostics.waitingonjob", "Waiting for command {0} to be completed at instance {1}", commandName, s)); Future aFuture = futures.get(s); InstanceCommandResult aResult = aFuture.get(maxWaitTime, TimeUnit.MILLISECONDS); long elapsedTime = System.currentTimeMillis() - waitStart; timeBeforeAsadminTimeout -= elapsedTime; if(!gotFirstResponse) { maxWaitTime = elapsedTime * 4; gotFirstResponse = true; } if( (maxWaitTime > timeBeforeAsadminTimeout) || (maxWaitTime < 60000) ) maxWaitTime = timeBeforeAsadminTimeout; InstanceCommandExecutor ice = (InstanceCommandExecutor) aResult.getInstanceCommand(); if(ice.getReport().getActionExitCode() != ActionReport.ExitCode.FAILURE) completedInstances.add(ice.getServer()); finalResult = FailurePolicy.applyFailurePolicy(failPolicy, ice.getReport().getActionExitCode()); if(returnValue == ActionReport.ExitCode.SUCCESS) returnValue = finalResult; if(finalResult != ActionReport.ExitCode.SUCCESS) { instanceState.setState(s, InstanceState.StateType.RESTART_REQUIRED, false); instanceState.addFailedCommandToInstance(s, commandName, parameters); } } catch (Exception ex) { ActionReport aReport = context.getActionReport().addSubActionsReport(); finalResult = ActionReport.ExitCode.FAILURE; finalResult = FailurePolicy.applyFailurePolicy(failPolicy, ActionReport.ExitCode.FAILURE); if(finalResult == ActionReport.ExitCode.FAILURE) { if(ex instanceof TimeoutException) aReport.setMessage(strings.getLocalString("clusterutil.timeoutwhilewaiting", "Timed out while waiting for result from instance {0}", s)); else aReport.setMessage(strings.getLocalString("clusterutil.exceptionwhilewaiting", "Exception while waiting for result from instance {0} : {1}", s, ex.getLocalizedMessage())); } aReport.setActionExitCode(finalResult); if(returnValue == ActionReport.ExitCode.SUCCESS) returnValue = finalResult; instanceState.setState(s, InstanceState.StateType.RESTART_REQUIRED, false); instanceState.addFailedCommandToInstance(s, commandName, parameters); } } return returnValue; } public static ActionReport.ExitCode replicateCommand(String commandName, FailurePolicy failPolicy, FailurePolicy offlinePolicy, Collection targetNames, AdminCommandContext context, ParameterMap parameters, Habitat habitat) { return replicateCommand(commandName, failPolicy, offlinePolicy, targetNames, context, parameters, habitat, null); } /** * Replicates a given command on the given list of targets, optionally gathering * downloaded result payloads from the instance commands into a directory. *

* If intermediateDownloadDir is non-null, then any files returned from * the instances in the payload of the HTTP response will be stored in a * directory tree like this: *

     * ${intermediateDownloadDir}/
     *     ${instanceA}/
     *         file(s) returned from instance A
     *     ${instanceB}/
     *         file(s) returned from instance B
     *     ...
     * 
* where ${instanceA}, ${instanceB}, etc. are the names of the instances to * which the command was replicated. This method does no further processing * on the downloaded files but leaves that to the calling command. */ public static ActionReport.ExitCode replicateCommand(String commandName, FailurePolicy failPolicy, FailurePolicy offlinePolicy, Collection targetNames, AdminCommandContext context, ParameterMap parameters, Habitat habitat, File intermediateDownloadDir) { ActionReport.ExitCode result = ActionReport.ExitCode.SUCCESS; Target targetService = habitat.getComponent(Target.class); for(String t : targetNames) { if(CommandTarget.DAS.isValid(habitat, t) || CommandTarget.DOMAIN.isValid(habitat, t)) continue; //If the target is a cluster and dynamic reconfig enabled is false, no replication if(targetService.isCluster(t)) { String dynRecfg = targetService.getClusterConfig(t).getDynamicReconfigurationEnabled(); if(Boolean.FALSE.equals(Boolean.valueOf(dynRecfg))) { ActionReport aReport = context.getActionReport().addSubActionsReport(); aReport.setActionExitCode(ActionReport.ExitCode.WARNING); aReport.setMessage(strings.getLocalString("glassfish.clusterexecutor.dynrecfgdisabled", "WARNING : The command was not replicated to all cluster instances because the" + " dynamic-reconfig-enabled flag is set to false for cluster {0}", t)); InstanceStateService instanceState = habitat.getComponent(InstanceStateService.class); for(Server s : targetService.getInstances(t)) { instanceState.setState(s.getName(), InstanceState.StateType.RESTART_REQUIRED, false); instanceState.addFailedCommandToInstance(s.getName(), commandName, parameters); } result = ActionReport.ExitCode.WARNING; continue; } } parameters.set("target", t); ActionReport.ExitCode returnValue = ClusterOperationUtil.replicateCommand(commandName, failPolicy, offlinePolicy, targetService.getInstances(t), context, parameters, habitat, intermediateDownloadDir); if(!returnValue.equals(ActionReport.ExitCode.SUCCESS)) { result = returnValue; } } return result; } /** * Makes sure the intermediate download directory is null (meaning the calling * command does not care about any downloaded content from the instances) or * that the specified file is a valid place to store any downloaded files. * Create the directory if it does not already exist. * * @param dir the caller-specified File to check */ private static void validateIntermediateDownloadDir(final File dir) { if (dir == null) { return; } if ( ! dir.exists()) { dir.mkdirs(); } else { if (! dir.isDirectory() || ! dir.canWrite()) { throw new IllegalArgumentException(dir.getAbsolutePath()); } } } private static File subdirectoryForInstance(final File dir, final InstanceCommandExecutor exec) { return new File(dir, exec.getServer().getName()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy