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: 8.0.0-JDK17-M7
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2010-2017 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://oss.oracle.com/licenses/CDDL+GPL-1.1
 * or 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 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.admin.remote.RemoteRestAdminCommand;
import com.sun.enterprise.config.serverbeans.Config;
import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.util.LocalStringManagerImpl;
import java.io.File;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.glassfish.api.ActionReport;
import org.glassfish.api.admin.*;
import org.glassfish.config.support.CommandTarget;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.internal.api.Target;
import org.glassfish.logging.annotation.LogMessageInfo;

/**
 *
 */
public class ClusterOperationUtil {
    private static final Logger logger = AdminLoggerInfo.getLogger();
    
    
    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

    //TODO: Remove after one replication method will be choosen
    private static boolean useRest() {
//        String useRestStr = System.getenv("AS_ADMIN_USE_REST");
//        return Boolean.valueOf(useRestStr);
        return true;
    }
    
    public static ActionReport.ExitCode replicateCommand(String commandName,
                                                   FailurePolicy failPolicy,
                                                   FailurePolicy offlinePolicy,
                                                   FailurePolicy neverStartedPolicy,
                                                   List instancesForReplication,
                                                   AdminCommandContext context,
                                                   ParameterMap parameters,
                                                   ServiceLocator habitat) {
        return replicateCommand(commandName, failPolicy, offlinePolicy, neverStartedPolicy,
                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, FailurePolicy neverStartedPolicy, List instancesForReplication, AdminCommandContext context, ParameterMap parameters, ServiceLocator habitat, final File intermediateDownloadDir) { ActionReport.ExitCode returnValue = ActionReport.ExitCode.SUCCESS; InstanceStateService instanceState = habitat.getService(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. // For certain commands, warn about the failure to replicate even if // the instance has never been started. ActionReport.ExitCode finalResult = FailurePolicy.applyFailurePolicy(neverStartedPolicy, ActionReport.ExitCode.FAILURE); if (!finalResult.equals(ActionReport.ExitCode.SUCCESS)) { ActionReport aReport = context.getActionReport().addSubActionsReport(); if (finalResult.equals(ActionReport.ExitCode.FAILURE)) { aReport.setMessage(strings.getLocalString("clusterutil.failneverstarted", "FAILURE: Instance {0} has never been started; command {1} was not replicated to that instance", svr.getName(), commandName)); } else { aReport.setMessage(strings.getLocalString("clusterutil.warnneverstarted", "WARNING: Instance {0} has never been started; command {1} was not replicated to that instance", svr.getName(), commandName)); } aReport.setActionExitCode(finalResult); if (returnValue == ActionReport.ExitCode.SUCCESS) returnValue = finalResult; } continue; } Config scfg = svr.getConfig(); if (!Boolean.valueOf(scfg.getDynamicReconfigurationEnabled())) { // Do not replicate to servers for which dynamic configuration is disabled ActionReport aReport = context.getActionReport().addSubActionsReport(); aReport.setActionExitCode(ActionReport.ExitCode.WARNING); aReport.setMessage(strings.getLocalString("clusterutil.dynrecfgdisabled", "WARNING: The command {0} was not replicated to instance {1} because the " + "dynamic-reconfiguration-enabled flag is set to false for config {2}", new Object[] {commandName, svr.getName(), scfg.getName()})); instanceState.setState(svr.getName(), InstanceState.StateType.RESTART_REQUIRED, false); instanceState.addFailedCommandToInstance(svr.getName(), commandName, parameters); returnValue = ActionReport.ExitCode.WARNING; 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); //TODO: Remove this if after only one remote admin call method will be choosen Future f; if (useRest()) { InstanceRestCommandExecutor ice = new InstanceRestCommandExecutor(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( new File(intermediateDownloadDir, ice.getServer().getName())); } f = instanceState.submitJob(svr, ice, aResult); } else { logger.log(Level.FINEST, "replicateCommand(): Use traditional way for replication - {0}", commandName); 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( new File(intermediateDownloadDir, ice.getServer().getName())); } f = instanceState.submitJob(svr, ice, aResult); } if (f == null) { logger.severe(AdminLoggerInfo.stateNotFound); 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("clusterutil.replicationfailed", "Error during command replication: {0}", ex.getLocalizedMessage())); logger.log(Level.SEVERE, AdminLoggerInfo.replicationError, ex.getLocalizedMessage()); if(returnValue ==ActionReport.ExitCode.SUCCESS) { returnValue = finalResult; } } boolean gotFirstResponse = false; long maxWaitTime = RemoteRestAdminCommand.getReadTimeout(); long timeBeforeAsadminTimeout = maxWaitTime; long waitStart = System.currentTimeMillis(); for(Map.Entry> fe : futures.entrySet()) { String s = fe.getKey(); 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 = fe.getValue(); 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; } ActionReport iReport; Server iServer; if (useRest()) { InstanceRestCommandExecutor ice = (InstanceRestCommandExecutor) aResult.getInstanceCommand(); iReport = ice.getReport(); iServer = ice.getServer(); } else { InstanceCommandExecutor ice = (InstanceCommandExecutor) aResult.getInstanceCommand(); iReport = ice.getReport(); iServer = ice.getServer(); } if(iReport.getActionExitCode() != ActionReport.ExitCode.FAILURE) { completedInstances.add(iServer); } finalResult = FailurePolicy.applyFailurePolicy(failPolicy, iReport.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 = 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, FailurePolicy neverStartedPolicy, Collection targetNames, AdminCommandContext context, ParameterMap parameters, ServiceLocator habitat) { return replicateCommand(commandName, failPolicy, offlinePolicy, neverStartedPolicy, 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, FailurePolicy neverStartedPolicy, Collection targetNames, AdminCommandContext context, ParameterMap parameters, ServiceLocator habitat, File intermediateDownloadDir) { ActionReport.ExitCode result = ActionReport.ExitCode.SUCCESS; Target targetService = habitat.getService(Target.class); for(String t : targetNames) { if(CommandTarget.DAS.isValid(habitat, t) || CommandTarget.DOMAIN.isValid(habitat, t)) continue; parameters.set("target", t); ActionReport.ExitCode returnValue = replicateCommand(commandName, failPolicy, offlinePolicy, neverStartedPolicy, 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()) { if ( ! dir.mkdirs()) { throw new RuntimeException(strings.getLocalString("clusterutil.errCreDir", "Could not create directory {0}; no further information available", dir.getAbsolutePath())); } } else { if (! dir.isDirectory() || ! dir.canWrite()) { throw new IllegalArgumentException(dir.getAbsolutePath()); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy