Index: src/main/java/com/sun/enterprise/v3/admin/cluster/StartClusterCommand.java =================================================================== --- src/main/java/com/sun/enterprise/v3/admin/cluster/StartClusterCommand.java (revision 38988) +++ src/main/java/com/sun/enterprise/v3/admin/cluster/StartClusterCommand.java (working copy) @@ -35,7 +35,11 @@ */ package com.sun.enterprise.v3.admin.cluster; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; import java.util.logging.Logger; +import com.sun.enterprise.config.serverbeans.*; import org.jvnet.hk2.annotations.*; import org.jvnet.hk2.component.*; import org.glassfish.api.I18n; @@ -47,11 +51,11 @@ import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.ActionReport; import org.glassfish.api.ActionReport.ExitCode; -import com.sun.enterprise.config.serverbeans.Server; -import com.sun.enterprise.config.serverbeans.Servers; -import com.sun.enterprise.config.serverbeans.Configs; -import com.sun.enterprise.config.serverbeans.Domain; import com.sun.enterprise.admin.util.RemoteInstanceCommandHelper; +import static org.glassfish.api.ActionReport.ExitCode.*; +import org.glassfish.gms.bootstrap.GMSAdapter; +import org.glassfish.gms.bootstrap.GMSAdapterService; +import com.sun.enterprise.ee.cms.core.GMSConstants; @I18n("start.cluster.command") @Service(name = "start-cluster") @@ -72,6 +76,11 @@ private boolean verbose; private RemoteInstanceCommandHelper helper; + @Inject + GMSAdapterService gmsAdapterService; + + static final private List EMPTY_LIST = new LinkedList(); + @Override public void postConstruct() { helper = new RemoteInstanceCommandHelper(habitat); @@ -97,6 +106,46 @@ ClusterCommandHelper clusterHelper = new ClusterCommandHelper(domain, runner); + com.sun.enterprise.ee.cms.core.GroupManagementService gms = null; + boolean gmsStartCluster = false; + List clusterMembers = null; + if (gmsAdapterService.isGmsEnabled()) { + GMSAdapter gmsadapter = gmsAdapterService.getGMSAdapterByName(clusterName); + + // gmsadapter can be null if GMSEnabled=false for clusterName. + if (gmsadapter != null) { + gms = gmsadapter.getModule(); + if (gms != null) { + clusterMembers = getClusterMembers(); + + // no need to announce a zero instance cluster. + if (clusterMembers != null && clusterMembers.size() > 0) { + + // one or more clustered instances for this cluster in domain.xml. + // now check if any clustered instance are already running. + // DAS is a SPECTATOR so it will not be in list of current core members. + // If one or more clustered instances is already running, do not consider this a GROUP_STARTUP, + // but treat as a series of individual INSTANCE_STARTUP for instances that do get started. + // no gms calls needed if not a GROUP_STARTUP. + List startedGMSMembers = gms.getGroupHandle().getCurrentCoreMembers(); + if (startedGMSMembers.size() == 0) { + try { + // must be called on DAS only. + gms.announceGroupStartup(clusterName, GMSConstants.groupStartupState.INITIATED, clusterMembers); + gmsStartCluster = true; + } catch (Throwable t) { + + // ensure gms group startup announcement does not interfere with starting cluster. + // any exception here should not interfer with starting cluster. + // todo: improve logging + logger.warning(t.getLocalizedMessage()); + } + } // else from GMS perspective treat remaining instances getting started as INSTANCE_START, not GROUP_START. + // nothing gms specific to do for this case. + } + } + } + } try { // Run start-instance against each instance in the cluster String commandName = "start-instance"; @@ -109,6 +158,75 @@ report.setActionExitCode(ExitCode.FAILURE); report.setMessage(msg); return; + } finally { + if (gmsStartCluster) { + announceGMSGroupStartupComplete(gms, clusterMembers, report, logger); + } } } + + private List getClusterMembers() { + List clusterMembers = EMPTY_LIST; + Cluster cluster = domain.getClusterNamed(clusterName); + List targetServers = null; + if (cluster != null) { + // Get the list of servers in the cluster. + targetServers = domain.getServersInTarget(clusterName); + if (targetServers != null) { + clusterMembers = new ArrayList(targetServers.size()); + for (Server server : targetServers) { + clusterMembers.add(server.getName()); + } + } + } + return clusterMembers; + } + + private void announceGMSGroupStartupComplete(com.sun.enterprise.ee.cms.core.GroupManagementService gms, + List clusterMembers, + ActionReport report, + Logger logger) { + GMSConstants.groupStartupState groupStartupState = GMSConstants.groupStartupState.COMPLETED_FAILED; + List members = EMPTY_LIST; + + if (report != null) { + switch (report.getActionExitCode()) { + case SUCCESS: + // all instances started + members = clusterMembers; + groupStartupState = GMSConstants.groupStartupState.COMPLETED_SUCCESS; + break; + + case FAILURE: + // no instances started + members = clusterMembers; // all failing instances. + groupStartupState = GMSConstants.groupStartupState.COMPLETED_FAILED; + + + break; + + case WARNING: + // at least one instance started + + // List failedMembers = ....; + groupStartupState = GMSConstants.groupStartupState.COMPLETED_FAILED; + + // todo: extract list of failed members from report. + // members list is suppose to be list of failed instances when COMPLETED_FAILED. + members = EMPTY_LIST; + break; + + default: + } + } + try { + // must be called on DAS only. + gms.announceGroupStartup(clusterName, groupStartupState, members); + } catch (Throwable t) { + // ensure gms group startup announcement does not interfere with starting cluster. + + // todo: improve logging + logger.warning(t.getLocalizedMessage()); + } + } } Index: pom.xml =================================================================== --- pom.xml (revision 38988) +++ pom.xml (working copy) @@ -137,6 +137,15 @@ ${project.version} test + + org.glassfish.cluster + gms-bootstrap + ${project.version} + + + org.shoal + shoal-gms-api +