Return-Path:
X-Original-To: apmail-geode-commits-archive@minotaur.apache.org
Delivered-To: apmail-geode-commits-archive@minotaur.apache.org
Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
by minotaur.apache.org (Postfix) with SMTP id 3AE4518605
for ;
Thu, 25 Feb 2016 20:27:05 +0000 (UTC)
Received: (qmail 59366 invoked by uid 500); 25 Feb 2016 20:27:05 -0000
Delivered-To: apmail-geode-commits-archive@geode.apache.org
Received: (qmail 59331 invoked by uid 500); 25 Feb 2016 20:27:05 -0000
Mailing-List: contact commits-help@geode.incubator.apache.org; run by ezmlm
Precedence: bulk
List-Help:
List-Unsubscribe:
List-Post:
List-Id:
Reply-To: dev@geode.incubator.apache.org
Delivered-To: mailing list commits@geode.incubator.apache.org
Received: (qmail 59318 invoked by uid 99); 25 Feb 2016 20:27:05 -0000
Received: from pnap-us-west-generic-nat.apache.org (HELO
spamd1-us-west.apache.org) (209.188.14.142)
by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 25 Feb 2016 20:27:05 +0000
Received: from localhost (localhost [127.0.0.1])
by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org)
with ESMTP id 8DB33C0854
for ; Thu, 25 Feb 2016 20:27:04 +0000 (UTC)
X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org
X-Spam-Flag: NO
X-Spam-Score: 0.98
X-Spam-Level:
X-Spam-Status: No, score=0.98 tagged_above=-999 required=6.31
tests=[KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_MSPIKE_H3=-0.01,
RCVD_IN_MSPIKE_WL=-0.01] autolearn=disabled
Received: from mx1-lw-us.apache.org ([10.40.0.8])
by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new,
port 10024)
with ESMTP id ICZ6sAKcT2EI for ;
Thu, 25 Feb 2016 20:26:59 +0000 (UTC)
Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with SMTP
id 197515FBE8
for ;
Thu, 25 Feb 2016 20:26:51 +0000 (UTC)
Received: (qmail 56207 invoked by uid 99); 25 Feb 2016 20:26:49 -0000
Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org)
(140.211.11.23)
by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 25 Feb 2016 20:26:49 +0000
Received: by git1-us-west.apache.org (ASF Mail Server at
git1-us-west.apache.org, from userid 33)
id E08CAE8F1B; Thu, 25 Feb 2016 20:26:49 +0000 (UTC)
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
From: jensdeppe@apache.org
To: commits@geode.incubator.apache.org
Date: Thu, 25 Feb 2016 20:27:24 -0000
Message-Id:
In-Reply-To: <73e7879c18f143a3b34041911bfd1983@git.apache.org>
References: <73e7879c18f143a3b34041911bfd1983@git.apache.org>
X-Mailer: ASF-Git Admin Mailer
Subject: [36/50] [abbrv] incubator-geode git commit: Merge branch 'develop'
into feature/GEODE-17
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
index 0000000,8eae00b..3ec52e3
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
@@@ -1,0 -1,2803 +1,2816 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ package com.gemstone.gemfire.management.internal.cli.commands;
+
+ import java.awt.Desktop;
+ import java.io.BufferedReader;
+ import java.io.BufferedWriter;
+ import java.io.File;
+ import java.io.FileFilter;
+ import java.io.FileNotFoundException;
+ import java.io.FileReader;
+ import java.io.FileWriter;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.InputStreamReader;
+ import java.net.InetAddress;
+ import java.net.MalformedURLException;
+ import java.net.URI;
+ import java.net.UnknownHostException;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.EmptyStackException;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Properties;
+ import java.util.Set;
+ import java.util.Stack;
+ import java.util.TreeSet;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.atomic.AtomicReference;
+
+ import javax.management.MalformedObjectNameException;
+ import javax.management.ObjectName;
+ import javax.management.Query;
+ import javax.management.QueryExp;
+ import javax.net.ssl.SSLException;
+ import javax.net.ssl.SSLHandshakeException;
+
+ import com.gemstone.gemfire.GemFireException;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.cache.server.CacheServer;
+ import com.gemstone.gemfire.distributed.AbstractLauncher;
+ import com.gemstone.gemfire.distributed.AbstractLauncher.ServiceState;
+ import com.gemstone.gemfire.distributed.AbstractLauncher.Status;
+ import com.gemstone.gemfire.distributed.LocatorLauncher;
+ import com.gemstone.gemfire.distributed.LocatorLauncher.LocatorState;
+ import com.gemstone.gemfire.distributed.ServerLauncher;
+ import com.gemstone.gemfire.distributed.ServerLauncher.ServerState;
+ import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+ import com.gemstone.gemfire.distributed.internal.tcpserver.TcpClient;
+ import com.gemstone.gemfire.internal.DistributionLocator;
+ import com.gemstone.gemfire.internal.GemFireVersion;
+ import com.gemstone.gemfire.internal.OSProcess;
+ import com.gemstone.gemfire.internal.SocketCreator;
+ import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberPattern;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.lang.ClassUtils;
+ import com.gemstone.gemfire.internal.lang.ObjectUtils;
+ import com.gemstone.gemfire.internal.lang.StringUtils;
+ import com.gemstone.gemfire.internal.lang.SystemUtils;
+ import com.gemstone.gemfire.internal.process.ClusterConfigurationNotAvailableException;
+ import com.gemstone.gemfire.internal.process.NonBlockingProcessStreamReader;
+ import com.gemstone.gemfire.internal.process.ProcessLauncherContext;
+ import com.gemstone.gemfire.internal.process.ProcessStreamReader;
+ import com.gemstone.gemfire.internal.process.ProcessStreamReader.InputListener;
+ import com.gemstone.gemfire.internal.process.ProcessStreamReader.ReadingMode;
+ import com.gemstone.gemfire.internal.process.ProcessType;
+ import com.gemstone.gemfire.internal.process.ProcessUtils;
+ import com.gemstone.gemfire.internal.process.signal.SignalEvent;
+ import com.gemstone.gemfire.internal.process.signal.SignalListener;
+ import com.gemstone.gemfire.internal.util.IOUtils;
+ import com.gemstone.gemfire.internal.util.StopWatch;
+ import com.gemstone.gemfire.lang.AttachAPINotFoundException;
+ import com.gemstone.gemfire.management.DistributedSystemMXBean;
+ import com.gemstone.gemfire.management.MemberMXBean;
+ import com.gemstone.gemfire.management.cli.CliMetaData;
+ import com.gemstone.gemfire.management.cli.ConverterHint;
+ import com.gemstone.gemfire.management.cli.Result;
+ import com.gemstone.gemfire.management.internal.ManagementConstants;
+ import com.gemstone.gemfire.management.internal.cli.CliUtil;
+ import com.gemstone.gemfire.management.internal.cli.LogWrapper;
+ import com.gemstone.gemfire.management.internal.cli.converters.ConnectionEndpointConverter;
+ import com.gemstone.gemfire.management.internal.cli.domain.ConnectToLocatorResult;
+ import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
+ import com.gemstone.gemfire.management.internal.cli.result.InfoResultData;
+ import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
+ import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
+ import com.gemstone.gemfire.management.internal.cli.shell.JmxOperationInvoker;
+ import com.gemstone.gemfire.management.internal.cli.shell.OperationInvoker;
+ import com.gemstone.gemfire.management.internal.cli.util.CauseFinder;
+ import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
+ import com.gemstone.gemfire.management.internal.cli.util.ConnectionEndpoint;
+ import com.gemstone.gemfire.management.internal.cli.util.JConsoleNotFoundException;
+ import com.gemstone.gemfire.management.internal.cli.util.VisualVmNotFoundException;
+ import com.gemstone.gemfire.management.internal.configuration.domain.SharedConfigurationStatus;
+ import com.gemstone.gemfire.management.internal.configuration.messages.SharedConfigurationStatusRequest;
+ import com.gemstone.gemfire.management.internal.configuration.messages.SharedConfigurationStatusResponse;
-
++import com.gemstone.gemfire.management.internal.security.Resource;
++import com.gemstone.gemfire.management.internal.security.ResourceConstants;
++import com.gemstone.gemfire.management.internal.security.ResourceOperation;
+ import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+ import org.springframework.shell.core.annotation.CliCommand;
+ import org.springframework.shell.core.annotation.CliOption;
+
+ /**
+ * The LauncherLifecycleCommands class encapsulates all GemFire launcher commands for GemFire tools (like starting
+ * GemFire Monitor (GFMon) and Visual Statistics Display (VSD)) as well external tools (like jconsole).
+ *
+ * @author John Blum
+ * @see com.gemstone.gemfire.distributed.LocatorLauncher
+ * @see com.gemstone.gemfire.distributed.ServerLauncher
+ * @see com.gemstone.gemfire.management.internal.cli.commands.AbstractCommandsSupport
+ * @see com.gemstone.gemfire.management.internal.cli.shell.Gfsh
+ * @since 7.0
+ */
+ @SuppressWarnings("unused")
+ public class LauncherLifecycleCommands extends AbstractCommandsSupport {
+
+ private static final String LOCATOR_TERM_NAME = "Locator";
+ private static final String SERVER_TERM_NAME = "Server";
+
+ private static final long PROCESS_STREAM_READER_JOIN_TIMEOUT_MILLIS = 30*1000;
+ private static final long PROCESS_STREAM_READER_ASYNC_STOP_TIMEOUT_MILLIS = 5*1000;
+ private static final long WAITING_FOR_STOP_TO_MAKE_PID_GO_AWAY_TIMEOUT_MILLIS = 30*1000;
+ private static final long WAITING_FOR_PID_FILE_TO_CONTAIN_PID_TIMEOUT_MILLIS = 2*1000;
+
+ protected static final int CMS_INITIAL_OCCUPANCY_FRACTION = 60;
+ protected static final int DEFAULT_PROCESS_OUTPUT_WAIT_TIME_MILLISECONDS = 5000;
+ protected static final int INVALID_PID = -1;
+ protected static final int MINIMUM_HEAP_FREE_RATIO = 10;
+ protected static final int NUM_ATTEMPTS_FOR_SHARED_CONFIGURATION_STATUS = 3;
+
+ protected static final AtomicReference ATTACH_API_AVAILABLE = new AtomicReference<>(null);
+
+ protected static final String ATTACH_API_CLASS_NAME = "com.sun.tools.attach.AttachNotSupportedException";
+ protected static final String GEMFIRE_HOME = System.getenv("GEMFIRE");
+ protected static final String JAVA_HOME = System.getProperty("java.home");
+ protected static final String LOCALHOST = "localhost";
+
+ // MUST CHANGE THIS TO REGEX SINCE VERSION CHANGES IN JAR NAME
+ protected static final String GEMFIRE_JAR_PATHNAME = IOUtils.appendToPath(GEMFIRE_HOME, "lib", GemFireVersion.getGemFireJarFileName());
+
+ protected static final String CORE_DEPENDENCIES_JAR_PATHNAME =
+ IOUtils.appendToPath(GEMFIRE_HOME, "lib", "geode-dependencies.jar");
+
+ protected static final String SPRING_AOP_JAR_NAME_PREFIX = "spring-aop";
+ protected static final String SPRING_BEANS_JAR_NAME_PREFIX = "spring-beans";
+ protected static final String SPRING_CONTEXT_JAR_NAME_PREFIX = "spring-context";
+ protected static final String SPRING_CONTEXT_SUPPORT_JAR_NAME_PREFIX = "spring-context-support";
+ protected static final String SPRING_DATA_COMMONS_JAR_NAME_PREFIX = "spring-data-commons";
+ protected static final String SPRING_DATA_GEMFIRE_JAR_NAME_PREFIX = "spring-data-gemfire";
+ protected static final String SPRING_EXPRESSION_JAR_NAME_PREFIX = "spring-expression";
+ protected static final String SPRING_TX_JAR_NAME_PREFIX = "spring-tx";
+
+ protected static final Set SPRING_JAR_NAME_PREFIXES;
+
+ static {
+ Set springJarNamePrefixes = new HashSet<>(8);
+
+ springJarNamePrefixes.add(SPRING_AOP_JAR_NAME_PREFIX);
+ springJarNamePrefixes.add(SPRING_BEANS_JAR_NAME_PREFIX);
+ springJarNamePrefixes.add(SPRING_CONTEXT_JAR_NAME_PREFIX);
+ springJarNamePrefixes.add(SPRING_CONTEXT_SUPPORT_JAR_NAME_PREFIX);
+ springJarNamePrefixes.add(SPRING_DATA_COMMONS_JAR_NAME_PREFIX);
+ springJarNamePrefixes.add(SPRING_DATA_GEMFIRE_JAR_NAME_PREFIX);
+ springJarNamePrefixes.add(SPRING_EXPRESSION_JAR_NAME_PREFIX);
+ springJarNamePrefixes.add(SPRING_TX_JAR_NAME_PREFIX);
+
+ SPRING_JAR_NAME_PREFIXES = Collections.unmodifiableSet(springJarNamePrefixes);
+ }
+
+ protected static boolean isAttachApiAvailable() {
+ if (ATTACH_API_AVAILABLE.get() == null) {
+ try {
+ ClassUtils.forName(ATTACH_API_CLASS_NAME, new AttachAPINotFoundException());
+ ATTACH_API_AVAILABLE.set(Boolean.TRUE);
+ }
+ catch (AttachAPINotFoundException ignore) {
+ ATTACH_API_AVAILABLE.set(Boolean.FALSE);
+ }
+ }
+
+ return ATTACH_API_AVAILABLE.get();
+ }
+
+ @CliCommand(value = CliStrings.START_LOCATOR, help = CliStrings.START_LOCATOR__HELP)
+ @CliMetaData(shellOnly = true, relatedTopic = { CliStrings.TOPIC_GEMFIRE_LOCATOR, CliStrings.TOPIC_GEMFIRE_LIFECYCLE })
++ @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+ public Result startLocator(@CliOption(key = CliStrings.START_LOCATOR__MEMBER_NAME,
+ mandatory = true,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__MEMBER_NAME__HELP)
+ final String memberName,
+ @CliOption(key = CliStrings.START_LOCATOR__BIND_ADDRESS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__BIND_ADDRESS__HELP)
+ final String bindAddress,
+ @CliOption(key = CliStrings.START_LOCATOR__CLASSPATH,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__CLASSPATH__HELP)
+ final String classpath,
+ @CliOption(key = CliStrings.START_LOCATOR__FORCE,
+ unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_LOCATOR__FORCE__HELP)
+ final Boolean force,
+ @CliOption(key = CliStrings.START_LOCATOR__GROUP,
+ optionContext = ConverterHint.MEMBERGROUP,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__GROUP__HELP)
+ final String group,
+ @CliOption(key = CliStrings.START_LOCATOR__HOSTNAME_FOR_CLIENTS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__HOSTNAME_FOR_CLIENTS__HELP)
+ final String hostnameForClients,
+ @CliOption(key = CliStrings.START_LOCATOR__INCLUDE_SYSTEM_CLASSPATH,
+ specifiedDefaultValue = "true",
+ unspecifiedDefaultValue = "false",
+ help = CliStrings.START_LOCATOR__INCLUDE_SYSTEM_CLASSPATH__HELP)
+ final Boolean includeSystemClasspath,
+ @CliOption(key = CliStrings.START_LOCATOR__LOCATORS,
+ optionContext = ConverterHint.LOCATOR_DISCOVERY_CONFIG,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__LOCATORS__HELP)
+ final String locators,
+ @CliOption(key = CliStrings.START_LOCATOR__LOG_LEVEL,
+ optionContext = ConverterHint.LOG_LEVEL,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__LOG_LEVEL__HELP)
+ final String logLevel,
+ @CliOption(key = CliStrings.START_LOCATOR__MCAST_ADDRESS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__MCAST_ADDRESS__HELP)
+ final String mcastBindAddress,
+ @CliOption(key = CliStrings.START_LOCATOR__MCAST_PORT,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__MCAST_PORT__HELP)
+ final Integer mcastPort,
+ @CliOption(key = CliStrings.START_LOCATOR__PORT,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__PORT__HELP)
+ final Integer port,
+ @CliOption(key = CliStrings.START_LOCATOR__DIR,
+ optionContext = ConverterHint.DIR_PATHSTRING,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__DIR__HELP)
+ String workingDirectory,
+ @CliOption(key = CliStrings.START_LOCATOR__PROPERTIES,
+ optionContext = ConverterHint.FILE_PATHSTRING,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__PROPERTIES__HELP)
+ String gemfirePropertiesPathname,
+ @CliOption(key = CliStrings.START_LOCATOR__SECURITY_PROPERTIES,
+ optionContext = ConverterHint.FILE_PATHSTRING,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__SECURITY_PROPERTIES__HELP)
+ String gemfireSecurityPropertiesPathname,
+ @CliOption(key = CliStrings.START_LOCATOR__INITIALHEAP,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__INITIALHEAP__HELP)
+ final String initialHeap,
+ @CliOption(key = CliStrings.START_LOCATOR__MAXHEAP,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__MAXHEAP__HELP)
+ final String maxHeap,
+ @CliOption(key = CliStrings.START_LOCATOR__J,
+ optionContext = ConverterHint.STRING_LIST,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_LOCATOR__J__HELP)
+ @CliMetaData(valueSeparator = ",")
+ final String[] jvmArgsOpts,
+ @CliOption (key = CliStrings.START_LOCATOR__CONNECT,
+ unspecifiedDefaultValue = "true",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_LOCATOR__CONNECT__HELP)
+ final boolean connect,
+ @CliOption(key = CliStrings.START_LOCATOR__ENABLE__SHARED__CONFIGURATION,
+ unspecifiedDefaultValue = "true",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_LOCATOR__ENABLE__SHARED__CONFIGURATION__HELP)
+ final boolean enableSharedConfiguration,
+ @CliOption(key = CliStrings.START_LOCATOR__LOAD__SHARED_CONFIGURATION__FROM__FILESYSTEM,
+ unspecifiedDefaultValue = "false",
+ help = CliStrings.START_LOCATOR__LOAD__SHARED_CONFIGURATION__FROM__FILESYSTEM__HELP)
+ final boolean loadSharedConfigurationFromDirectory,
+ @CliOption(key = CliStrings.START_LOCATOR__CLUSTER__CONFIG__DIR,
+ unspecifiedDefaultValue = "",
+ help = CliStrings.START_LOCATOR__CLUSTER__CONFIG__DIR__HELP)
+ final String clusterConfigDir
+ ) {
+ try {
+ if (workingDirectory == null) {
+ // attempt to use or make sub-directory using memberName...
+ File locatorWorkingDirectory = new File(memberName);
+
+ if (!(locatorWorkingDirectory.exists() || locatorWorkingDirectory.mkdir())) {
+ throw new IllegalStateException(CliStrings.format(CliStrings.START_LOCATOR__MSG__COULD_NOT_CREATE_DIRECTORY_0_VERIFY_PERMISSIONS,
+ locatorWorkingDirectory.getAbsolutePath()));
+ }
+
+ workingDirectory = IOUtils.tryGetCanonicalPathElseGetAbsolutePath(locatorWorkingDirectory);
+ }
+
+ gemfirePropertiesPathname = CliUtil.resolvePathname(gemfirePropertiesPathname);
+
+ if (!StringUtils.isBlank(gemfirePropertiesPathname) && !IOUtils.isExistingPathname(gemfirePropertiesPathname)) {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(CliStrings.GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
+ StringUtils.EMPTY_STRING, gemfirePropertiesPathname));
+ }
+
+ gemfireSecurityPropertiesPathname = CliUtil.resolvePathname(gemfireSecurityPropertiesPathname);
+
+ if (!StringUtils.isBlank(gemfireSecurityPropertiesPathname) && !IOUtils.isExistingPathname(gemfireSecurityPropertiesPathname)) {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(CliStrings.GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
+ "Security ", gemfireSecurityPropertiesPathname));
+ }
+
+ File locatorPidFile = new File(workingDirectory, ProcessType.LOCATOR.getPidFileName());
+
+ final int oldPid = readPid(locatorPidFile);
+
+ Properties gemfireProperties = new Properties();
+
+ gemfireProperties.setProperty(DistributionConfig.GROUPS_NAME, StringUtils.valueOf(group, StringUtils.EMPTY_STRING));
+ gemfireProperties.setProperty(DistributionConfig.LOCATORS_NAME, StringUtils.valueOf(locators, StringUtils.EMPTY_STRING));
+ gemfireProperties.setProperty(DistributionConfig.LOG_LEVEL_NAME, StringUtils.valueOf(logLevel, StringUtils.EMPTY_STRING));
+ gemfireProperties.setProperty(DistributionConfig.MCAST_ADDRESS_NAME, StringUtils.valueOf(mcastBindAddress, StringUtils.EMPTY_STRING));
+ gemfireProperties.setProperty(DistributionConfig.MCAST_PORT_NAME, StringUtils.valueOf(mcastPort, StringUtils.EMPTY_STRING));
+ gemfireProperties.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, StringUtils.valueOf(enableSharedConfiguration, StringUtils.EMPTY_STRING));
+ gemfireProperties.setProperty(DistributionConfig.LOAD_CLUSTER_CONFIG_FROM_DIR_NAME, StringUtils.valueOf(loadSharedConfigurationFromDirectory, StringUtils.EMPTY_STRING));
+ gemfireProperties.setProperty(DistributionConfig.CLUSTER_CONFIGURATION_DIR, StringUtils.valueOf(clusterConfigDir, StringUtils.EMPTY_STRING));
+
+ // read the OSProcess enable redirect system property here -- TODO: replace with new GFSH argument
+ final boolean redirectOutput = Boolean.getBoolean(OSProcess.ENABLE_OUTPUT_REDIRECTION_PROPERTY);
+ LocatorLauncher locatorLauncher = new LocatorLauncher.Builder()
+ .setBindAddress(bindAddress)
+ .setForce(force)
+ .setHostnameForClients(hostnameForClients)
+ .setMemberName(memberName)
+ .setPort(port)
+ .setRedirectOutput(redirectOutput)
+ .setWorkingDirectory(workingDirectory)
+ .build();
+
+ String[] locatorCommandLine = createStartLocatorCommandLine(locatorLauncher, gemfirePropertiesPathname,
+ gemfireSecurityPropertiesPathname, gemfireProperties, classpath, includeSystemClasspath, jvmArgsOpts, initialHeap, maxHeap);
+
+ //getGfsh().logInfo(StringUtils.concat(locatorCommandLine, " "), null);
+
+ final Process locatorProcess = new ProcessBuilder(locatorCommandLine)
+ .directory(new File(locatorLauncher.getWorkingDirectory()))
+ .start();
+
+ locatorProcess.getInputStream().close();
+ locatorProcess.getOutputStream().close();
+
+ // fix TRAC bug #51967 by using NON_BLOCKING on Windows
+ final ReadingMode readingMode = SystemUtils.isWindows() ? ReadingMode.NON_BLOCKING : ReadingMode.BLOCKING;
+
+ final StringBuffer message = new StringBuffer(); // need thread-safe StringBuffer
+ InputListener inputListener = new InputListener() {
+ @Override
+ public void notifyInputLine(String line) {
+ message.append(line);
+ if (readingMode == ReadingMode.BLOCKING) {
+ message.append(StringUtils.LINE_SEPARATOR);
+ }
+ }
+ };
+
+ ProcessStreamReader stderrReader = new ProcessStreamReader.Builder(locatorProcess)
+ .inputStream(locatorProcess.getErrorStream())
+ .inputListener(inputListener)
+ .readingMode(readingMode)
+ .continueReadingMillis(2*1000)
+ .build()
+ .start();
+
+ LocatorState locatorState;
+
+ String previousLocatorStatusMessage = null;
+
+ LauncherSignalListener locatorSignalListener = new LauncherSignalListener();
+
+ final boolean registeredLocatorSignalListener = getGfsh().getSignalHandler().registerListener(locatorSignalListener);
+
+ try {
+ getGfsh().logInfo(String.format(CliStrings.START_LOCATOR__RUN_MESSAGE,
+ IOUtils.tryGetCanonicalPathElseGetAbsolutePath(new File(locatorLauncher.getWorkingDirectory()))), null);
+
+ do {
+ try {
+ final int exitValue = locatorProcess.exitValue();
+
+ stderrReader.join(PROCESS_STREAM_READER_JOIN_TIMEOUT_MILLIS); // was Long.MAX_VALUE
+
+ //Gfsh.println(message);
+
+ return ResultBuilder.createShellClientErrorResult(String.format(
+ CliStrings.START_LOCATOR__PROCESS_TERMINATED_ABNORMALLY_ERROR_MESSAGE,
+ exitValue, locatorLauncher.getWorkingDirectory(), message.toString()));
+ }
+ catch (IllegalThreadStateException ignore) {
+ // the IllegalThreadStateException is expected; it means the Locator's process has not terminated,
+ // and basically should not
+ Gfsh.print(".");
+
+ synchronized (this) {
+ TimeUnit.MILLISECONDS.timedWait(this, 500);
+ }
+
+ locatorState = (ProcessUtils.isAttachApiAvailable() ? locatorStatus(locatorPidFile, oldPid, memberName)
+ : locatorStatus(workingDirectory, memberName));
+
+ String currentLocatorStatusMessage = locatorState.getStatusMessage();
+
+ if (isStartingOrNotResponding(locatorState.getStatus())
+ && !(StringUtils.isBlank(currentLocatorStatusMessage)
+ || currentLocatorStatusMessage.equalsIgnoreCase(previousLocatorStatusMessage)))
+ {
+ Gfsh.println();
+ Gfsh.println(currentLocatorStatusMessage);
+ previousLocatorStatusMessage = currentLocatorStatusMessage;
+ }
+ }
+ }
+ while (!(registeredLocatorSignalListener && locatorSignalListener.isSignaled())
+ && isStartingOrNotResponding(locatorState.getStatus()));
+ }
+ finally {
+ stderrReader.stopAsync(PROCESS_STREAM_READER_ASYNC_STOP_TIMEOUT_MILLIS); // stop will close ErrorStream
+ getGfsh().getSignalHandler().unregisterListener(locatorSignalListener);
+ }
+
+ Gfsh.println();
+
+ final boolean asyncStart = (registeredLocatorSignalListener && locatorSignalListener.isSignaled()
+ && isStartingNotRespondingOrNull(locatorState));
+
+ InfoResultData infoResultData = ResultBuilder.createInfoResultData();
+
+ if (asyncStart) {
+ infoResultData.addLine(String.format(CliStrings.ASYNC_PROCESS_LAUNCH_MESSAGE, LOCATOR_TERM_NAME));
+ }
+ else {
+ infoResultData.addLine(locatorState.toString());
+
+ String locatorHostName = StringUtils.defaultIfBlank(locatorLauncher.getHostnameForClients(), getLocalHost());
+ int locatorPort = locatorLauncher.getPort();
+
+ // AUTO-CONNECT
+ // If the connect succeeds add the connected message to the result,
+ // Else, ask the user to use the "connect" command to connect to the Locator.
+ if (shouldAutoConnect(connect)) {
+ doAutoConnect(locatorHostName, locatorPort, gemfirePropertiesPathname, gemfireSecurityPropertiesPathname,
+ infoResultData);
+ }
+
+ // Report on the state of the Shared Configuration service if enabled...
+ if (enableSharedConfiguration) {
+ infoResultData.addLine(getSharedConfigurationStatusFromLocator(locatorHostName, locatorPort));
+ }
+ }
+
+ return ResultBuilder.buildResult(infoResultData);
+ }
+ catch (IllegalArgumentException e) {
+ String message = e.getMessage();
+ if (message != null && message.matches(LocalizedStrings.Launcher_Builder_UNKNOWN_HOST_ERROR_MESSAGE.toLocalizedString(".+"))) {
+ message = CliStrings.format(CliStrings.LAUNCHERLIFECYCLECOMMANDS__MSG__FAILED_TO_START_0_REASON_1, LOCATOR_TERM_NAME, message);
+ }
+ return ResultBuilder.createUserErrorResult(message);
+ }
+ catch (IllegalStateException e) {
+ return ResultBuilder.createUserErrorResult(e.getMessage());
+ }
+ catch (VirtualMachineError e) {
+ SystemFailure.initiateFailure(e);
+ throw e;
+ }
+ catch (Throwable t) {
+ SystemFailure.checkFailure();
+ String errorMessage = String.format(CliStrings.START_LOCATOR__GENERAL_ERROR_MESSAGE,
+ StringUtils.defaultIfBlank(workingDirectory, memberName), getLocatorId(bindAddress, port),
+ toString(t, getGfsh().getDebug()));
+ getGfsh().logToFile(errorMessage, t);
+ return ResultBuilder.createShellClientErrorResult(errorMessage);
+ }
+ finally {
+ Gfsh.redirectInternalJavaLoggers();
+ }
+ }
+
+ protected String[] createStartLocatorCommandLine(final LocatorLauncher launcher,
+ final String gemfirePropertiesPathname,
+ final String gemfireSecurityPropertiesPathname,
+ final Properties gemfireProperties,
+ final String userClasspath,
+ final Boolean includeSystemClasspath,
+ final String[] jvmArgsOpts,
+ final String initialHeap,
+ final String maxHeap)
+ throws MalformedObjectNameException
+ {
+ List commandLine = new ArrayList<>();
+
+ commandLine.add(getJavaPath());
+ commandLine.add("-server");
+ commandLine.add("-classpath");
+ commandLine.add(getLocatorClasspath(Boolean.TRUE.equals(includeSystemClasspath), userClasspath));
+
+ addCurrentLocators(commandLine, gemfireProperties);
+ addGemFirePropertyFile(commandLine, gemfirePropertiesPathname);
+ addGemFireSecurityPropertyFile(commandLine, gemfireSecurityPropertiesPathname);
+ addGemFireSystemProperties(commandLine, gemfireProperties);
+ addJvmArgumentsAndOptions(commandLine, jvmArgsOpts);
+ addInitialHeap(commandLine, initialHeap);
+ addMaxHeap(commandLine, maxHeap);
+
+ commandLine.add("-D".concat(AbstractLauncher.SIGNAL_HANDLER_REGISTRATION_SYSTEM_PROPERTY.concat("=true")));
+ commandLine.add("-Djava.awt.headless=true");
+ commandLine.add("-Dsun.rmi.dgc.server.gcInterval".concat("=").concat(Long.toString(Long.MAX_VALUE-1)));
+ commandLine.add(LocatorLauncher.class.getName());
+ commandLine.add(LocatorLauncher.Command.START.getName());
+
+ if (!StringUtils.isBlank(launcher.getMemberName())) {
+ commandLine.add(launcher.getMemberName());
+ }
+
+ if (launcher.getBindAddress() != null) {
+ commandLine.add("--bind-address=" + launcher.getBindAddress().getCanonicalHostName());
+ }
+
+ if (launcher.isDebugging() || isDebugging()) {
+ commandLine.add("--debug");
+ }
+
+ if (launcher.isForcing()) {
+ commandLine.add("--force");
+ }
+
+ if (!StringUtils.isBlank(launcher.getHostnameForClients())) {
+ commandLine.add("--hostname-for-clients=" + launcher.getHostnameForClients());
+ }
+
+ if (launcher.getPort() != null) {
+ commandLine.add("--port=" + launcher.getPort());
+ }
+
+ if (launcher.isRedirectingOutput()) {
+ commandLine.add("--redirect-output");
+ }
+
+ return commandLine.toArray(new String[commandLine.size()]);
+ }
+
+ // TODO should we connect implicitly when in non-interactive, headless mode (e.g. gfsh -e "start locator ...")?
+ // With execute option (-e), there could be multiple commands which might presume that a prior "start locator"
+ // has formed the connection.
+ private boolean shouldAutoConnect(final boolean connect) {
+ return (connect && !(getGfsh() == null || isConnectedAndReady()));
+ }
+
+ private boolean doAutoConnect(final String locatorHostname,
+ final int locatorPort,
+ final String gemfirePropertiesPathname,
+ final String gemfireSecurityPropertiesPathname,
+ final InfoResultData infoResultData)
+ {
+ boolean connectSuccess = false;
+ boolean jmxManagerAuthEnabled = false;
+ boolean jmxManagerSslEnabled = false;
+
+ Map configurationProperties = loadConfigurationProperties(gemfireSecurityPropertiesPathname,
+ loadConfigurationProperties(gemfirePropertiesPathname));
+ Map locatorConfigurationProperties = new HashMap<>(configurationProperties);
+
+ String responseFailureMessage = null;
+
+ for (int attempts = 0; (attempts < 10 && !connectSuccess); attempts++) {
+ try {
+ ConnectToLocatorResult connectToLocatorResult = ShellCommands.connectToLocator(locatorHostname, locatorPort,
+ ShellCommands.getConnectLocatorTimeoutInMS() / 4, locatorConfigurationProperties);
+
+ ConnectionEndpoint memberEndpoint = connectToLocatorResult.getMemberEndpoint();
+
+ jmxManagerSslEnabled = connectToLocatorResult.isJmxManagerSslEnabled();
+
+ if (!jmxManagerSslEnabled) {
+ configurationProperties.clear();
+ }
+
+ getGfsh().setOperationInvoker(new JmxOperationInvoker(memberEndpoint.getHost(), memberEndpoint.getPort(),
- null, null, configurationProperties));
++ null, null, configurationProperties, null));
+
+ String shellAndLogMessage = CliStrings.format(CliStrings.CONNECT__MSG__SUCCESS, memberEndpoint.toString(false));
+
+ infoResultData.addLine("\n");
+ infoResultData.addLine(shellAndLogMessage);
+ getGfsh().logToFile(shellAndLogMessage, null);
+
+ connectSuccess = true;
+ responseFailureMessage = null;
+ }
+ catch (IllegalStateException unexpected) {
+ if (CauseFinder.indexOfCause(unexpected, ClassCastException.class, false) != -1) {
+ responseFailureMessage = "The Locator might require SSL Configuration.";
+ }
+ }
+ catch (SecurityException ignore) {
+ getGfsh().logToFile(ignore.getMessage(), ignore);
+ jmxManagerAuthEnabled = true;
+ break; // no need to continue after SecurityException
+ }
+ catch (SSLException ignore) {
+ if (ignore instanceof SSLHandshakeException) {
+ // try to connect again without SSL since the SSL handshake failed implying a plain text connection...
+ locatorConfigurationProperties.clear();
+ }
+ else {
+ // another type of SSL error occurred (possibly a configuration issue); pass the buck...
+ getGfsh().logToFile(ignore.getMessage(), ignore);
+ responseFailureMessage = "Check your SSL configuration and try again.";
+ break;
+ }
+ }
+ catch (Exception ignore) {
+ getGfsh().logToFile(ignore.getMessage(), ignore);
+ responseFailureMessage = "Failed to connect; unknown cause: " + ignore.getMessage();
+ }
+ }
+
+ if (!connectSuccess) {
+ doOnConnectionFailure(locatorHostname, locatorPort, jmxManagerAuthEnabled, jmxManagerSslEnabled, infoResultData);
+ }
+
+ if (!StringUtils.isBlank(responseFailureMessage)) {
+ infoResultData.addLine("\n");
+ infoResultData.addLine(responseFailureMessage);
+ }
+
+ return connectSuccess;
+ }
+
+ private void doOnConnectionFailure(final String locatorHostName,
+ final int locatorPort,
+ final boolean jmxManagerAuthEnabled,
+ final boolean jmxManagerSslEnabled,
+ final InfoResultData infoResultData)
+ {
+ infoResultData.addLine("\n");
+ infoResultData.addLine(CliStrings.format(CliStrings.START_LOCATOR__USE__0__TO__CONNECT,
+ new CommandStringBuilder(CliStrings.CONNECT).addOption(CliStrings.CONNECT__LOCATOR,
+ locatorHostName + "[" + locatorPort + "]").toString()));
+
+ StringBuilder message = new StringBuilder();
+
+ if (jmxManagerAuthEnabled) {
+ message.append("Authentication");
+ }
+ if (jmxManagerSslEnabled) {
+ message.append(jmxManagerAuthEnabled ? " and " : StringUtils.EMPTY_STRING).append("SSL configuration");
+ }
+ if (jmxManagerAuthEnabled || jmxManagerSslEnabled) {
+ message.append(" required to connect to the Manager.");
+ infoResultData.addLine("\n");
+ infoResultData.addLine(message.toString());
+ }
+ }
+
+ private Map loadConfigurationProperties(final String configurationPropertiesPathname) {
+ return loadConfigurationProperties(configurationPropertiesPathname, null);
+ }
+
+ private Map loadConfigurationProperties(final String configurationPropertiesPathname,
+ Map configurationProperties)
+ {
+ configurationProperties = (configurationProperties != null ? configurationProperties
+ : new HashMap());
+
+ if (IOUtils.isExistingPathname(configurationPropertiesPathname)) {
+ try {
+ configurationProperties.putAll(ShellCommands.loadPropertiesFromURL(
+ new File(configurationPropertiesPathname).toURI().toURL()));
+ }
+ catch (MalformedURLException ignore) {
+ LogWrapper.getInstance().warning(String.format(
+ "Failed to load GemFire configuration properties from pathname (%1$s)!",
+ configurationPropertiesPathname), ignore);
+ }
+ }
+
+ return configurationProperties;
+ }
+
+ private String getSharedConfigurationStatusFromLocatorState(LocatorState locatorState) throws ClassNotFoundException, IOException {
+ return getSharedConfigurationStatusFromLocator(locatorState.getHost(), Integer.parseInt(locatorState.getPort()));
+ }
+
+ private String getSharedConfigurationStatusFromLocator(String locatorHostName, int locatorPort) throws ClassNotFoundException, IOException {
+ final StringBuilder buffer = new StringBuilder();
+
+ try {
+ final InetAddress networkAddress = InetAddress.getByName(locatorHostName);
+
+ SharedConfigurationStatusResponse statusResponse = (SharedConfigurationStatusResponse)
+ TcpClient.requestToServer(networkAddress, locatorPort, new SharedConfigurationStatusRequest(), 10000, true);
+
+ for (int i=0; i pmpSet = statusResponse.getOtherLocatorInformation();
+ if (!pmpSet.isEmpty()) {
+ buffer.append("\nThis locator might have stale cluster configuration data.");
+ buffer.append("\nFollowing locators contain potentially newer cluster configuration data");
+
+ for (PersistentMemberPattern pmp : pmpSet) {
+ buffer.append("\nHost : ").append(pmp.getHost());
+ buffer.append("\nDirectory : ").append(pmp.getDirectory());
+ }
+ }
+ else {
+ buffer.append("\nPlease check the log file for errors");
+ }
+ break;
+ case UNDETERMINED:
+ buffer.append("\nUnable to determine the status of shared configuration service, please check the log file");
+ break;
+ case NOT_STARTED:
+ buffer.append("\nCluster configuration service has not been started yet");
+ break;
+ case STARTED:
+ buffer.append("\nCluster configuration service has been started, but its not running yet");
+ break;
+ }
+ }
+ catch (Exception e) {
+ // TODO fix this once Trac Bug #50513 gets fixed
+ // NOTE this ClassCastException occurs if the a plain text TCP/IP connection is used to connect to a Locator
+ // configured with SSL.
+ getGfsh().logToFile(String.format("Failed to get the status of the Shared Configuration Service running on Locator (%1$s[%2$d])!",
+ locatorHostName, locatorPort), e);
+ }
+
+ return buffer.toString();
+ }
+
+ @CliCommand(value = CliStrings.STATUS_LOCATOR, help = CliStrings.STATUS_LOCATOR__HELP)
+ @CliMetaData(shellOnly = true, relatedTopic = { CliStrings.TOPIC_GEMFIRE_LOCATOR, CliStrings.TOPIC_GEMFIRE_LIFECYCLE })
++ @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+ public Result statusLocator(@CliOption(key = CliStrings.STATUS_LOCATOR__MEMBER,
+ optionContext = ConverterHint.LOCATOR_MEMBER_IDNAME,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.STATUS_LOCATOR__MEMBER__HELP)
+ final String member,
+ @CliOption(key = CliStrings.STATUS_LOCATOR__HOST,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.STATUS_LOCATOR__HOST__HELP)
+ final String locatorHost,
+ @CliOption(key = CliStrings.STATUS_LOCATOR__PORT,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.STATUS_LOCATOR__PORT__HELP)
+ final Integer locatorPort,
+ @CliOption(key = CliStrings.STATUS_LOCATOR__PID,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.STATUS_LOCATOR__PID__HELP)
+ final Integer pid,
+ @CliOption(key = CliStrings.STATUS_LOCATOR__DIR,
+ optionContext = ConverterHint.DIR_PATHSTRING,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.STATUS_LOCATOR__DIR__HELP)
+ final String workingDirectory)
+ {
+ try {
+ if (!StringUtils.isBlank(member)) {
+ if (isConnectedAndReady()) {
+ final MemberMXBean locatorProxy = getMemberMXBean(member);
+
+ if (locatorProxy != null) {
+ LocatorState state = LocatorState.fromJson(locatorProxy.status());
+ return createStatusLocatorResult(state);
+ }
+ else {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(
+ CliStrings.STATUS_LOCATOR__NO_LOCATOR_FOUND_FOR_MEMBER_ERROR_MESSAGE, member));
+ }
+ }
+ else {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(
+ CliStrings.STATUS_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE, LOCATOR_TERM_NAME));
+ }
+ }
+ else {
+ final LocatorLauncher locatorLauncher = new LocatorLauncher.Builder()
+ .setCommand(LocatorLauncher.Command.STATUS)
+ .setBindAddress(locatorHost)
+ .setDebug(isDebugging())
+ .setPid(pid)
+ .setPort(locatorPort)
+ .setWorkingDirectory(workingDirectory)
+ .build();
+
+ final LocatorState state = locatorLauncher.status();
+ return createStatusLocatorResult(state);
+ }
+ }
+ catch (IllegalArgumentException e) {
+ return ResultBuilder.createUserErrorResult(e.getMessage());
+ }
+ catch (IllegalStateException e) {
+ return ResultBuilder.createUserErrorResult(e.getMessage());
+ }
+ catch (VirtualMachineError e) {
+ SystemFailure.initiateFailure(e);
+ throw e;
+ }
+ catch (Throwable t) {
+ SystemFailure.checkFailure();
+ return ResultBuilder.createShellClientErrorResult(String.format(CliStrings.STATUS_LOCATOR__GENERAL_ERROR_MESSAGE,
+ getLocatorId(locatorHost, locatorPort), StringUtils.defaultIfBlank(workingDirectory, SystemUtils.CURRENT_DIRECTORY),
+ toString(t, getGfsh().getDebug())));
+ }
+ }
+
+ @CliCommand(value=CliStrings.STOP_LOCATOR, help=CliStrings.STOP_LOCATOR__HELP)
+ @CliMetaData(shellOnly=true, relatedTopic = {CliStrings.TOPIC_GEMFIRE_LOCATOR, CliStrings.TOPIC_GEMFIRE_LIFECYCLE})
++ @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+ public Result stopLocator(@CliOption(key = CliStrings.STOP_LOCATOR__MEMBER,
+ optionContext = ConverterHint.LOCATOR_MEMBER_IDNAME,
+ unspecifiedDefaultValue=CliMetaData.ANNOTATION_NULL_VALUE,
+ help=CliStrings.STOP_LOCATOR__MEMBER__HELP)
+ final String member,
+ @CliOption(key=CliStrings.STOP_LOCATOR__PID,
+ unspecifiedDefaultValue=CliMetaData.ANNOTATION_NULL_VALUE,
+ help=CliStrings.STOP_LOCATOR__PID__HELP)
+ final Integer pid,
+ @CliOption(key=CliStrings.STOP_LOCATOR__DIR,
+ optionContext = ConverterHint.DIR_PATHSTRING,
+ unspecifiedDefaultValue=CliMetaData.ANNOTATION_NULL_VALUE,
+ help=CliStrings.STOP_LOCATOR__DIR__HELP)
+ final String workingDirectory)
+ {
+ LocatorState locatorState;
+
+ try {
+ if (!StringUtils.isBlank(member)) {
+ if (isConnectedAndReady()) {
+ final MemberMXBean locatorProxy = getMemberMXBean(member);
+
+ if (locatorProxy != null) {
+ if (!locatorProxy.isLocator()) {
+ throw new IllegalStateException(CliStrings.format(CliStrings.STOP_LOCATOR__NOT_LOCATOR_ERROR_MESSAGE, member));
+ }
+
+ if (locatorProxy.isServer()) {
+ throw new IllegalStateException(CliStrings.format(CliStrings.STOP_LOCATOR__LOCATOR_IS_CACHE_SERVER_ERROR_MESSAGE, member));
+ }
+
+ locatorState = LocatorState.fromJson(locatorProxy.status());
+ locatorProxy.shutDownMember();
+ }
+ else {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(
+ CliStrings.STOP_LOCATOR__NO_LOCATOR_FOUND_FOR_MEMBER_ERROR_MESSAGE, member));
+ }
+ }
+ else {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(
+ CliStrings.STOP_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE, LOCATOR_TERM_NAME));
+ }
+ }
+ else {
+ final LocatorLauncher locatorLauncher = new LocatorLauncher.Builder()
+ .setCommand(LocatorLauncher.Command.STOP)
+ .setDebug(isDebugging())
+ .setPid(pid)
+ .setWorkingDirectory(workingDirectory)
+ .build();
+
+ locatorState = locatorLauncher.status();
+ locatorLauncher.stop();
+ }
+
+ if (Status.ONLINE.equals(locatorState.getStatus())) {
+ getGfsh().logInfo(String.format(CliStrings.STOP_LOCATOR__STOPPING_LOCATOR_MESSAGE,
+ locatorState.getWorkingDirectory(), locatorState.getServiceLocation(), locatorState.getMemberName(),
+ locatorState.getPid(), locatorState.getLogFile()), null);
+
+ StopWatch stopWatch = new StopWatch(true);
+ while (isVmWithProcessIdRunning(locatorState.getPid())) {
+ Gfsh.print(".");
+ if (stopWatch.elapsedTimeMillis() > WAITING_FOR_STOP_TO_MAKE_PID_GO_AWAY_TIMEOUT_MILLIS) {
+ break;
+ }
+ synchronized (this) {
+ TimeUnit.MILLISECONDS.timedWait(this, 500);
+ }
+ }
+
+ return ResultBuilder.createInfoResult(StringUtils.EMPTY_STRING);
+ }
+ else {
+ return ResultBuilder.createUserErrorResult(locatorState.toString());
+ }
+ }
+ catch (IllegalArgumentException e) {
+ return ResultBuilder.createUserErrorResult(e.getMessage());
+ }
+ catch (IllegalStateException e) {
+ return ResultBuilder.createUserErrorResult(e.getMessage());
+ }
+ catch (VirtualMachineError e) {
+ SystemFailure.initiateFailure(e);
+ throw e;
+ }
+ catch (Throwable t) {
+ SystemFailure.checkFailure();
+ return ResultBuilder.createShellClientErrorResult(String.format(CliStrings.STOP_LOCATOR__GENERAL_ERROR_MESSAGE,
+ toString(t, getGfsh().getDebug())));
+ } finally {
+ Gfsh.redirectInternalJavaLoggers();
+ }
+ }
+
+ // TODO re-evaluate whether a MalformedObjectNameException should be thrown here; just because we were not able to find
+ // the "current" Locators in order to conveniently add the new member to the GemFire cluster does not mean we should
+ // throw an Exception!
+ protected void addCurrentLocators(final List commandLine, final Properties gemfireProperties) throws MalformedObjectNameException {
+ if (StringUtils.isBlank(gemfireProperties.getProperty(DistributionConfig.LOCATORS_NAME))) {
+ String currentLocators = getCurrentLocators();
+
+ if (!StringUtils.isBlank(currentLocators)) {
+ commandLine.add("-D".concat(ProcessLauncherContext.OVERRIDDEN_DEFAULTS_PREFIX)
+ .concat(DistributionConfig.LOCATORS_NAME).concat("=").concat(currentLocators));
+ }
+ }
+ }
+
+ protected Result createStatusLocatorResult(final LocatorState state) throws NumberFormatException, IOException, ClassNotFoundException {
+ InfoResultData infoResultData = ResultBuilder.createInfoResultData();
+ infoResultData.addLine(state.toString());
+ infoResultData.addLine(getSharedConfigurationStatusFromLocatorState(state));
+ return ResultBuilder.buildResult(infoResultData);
+ }
+
+ protected void addGemFirePropertyFile(final List commandLine, final String gemfirePropertiesPathname) {
+ if (!StringUtils.isBlank(gemfirePropertiesPathname)) {
+ commandLine.add("-DgemfirePropertyFile=" + gemfirePropertiesPathname);
+ }
+ }
+
+ protected void addGemFireSecurityPropertyFile(final List commandLine, final String gemfireSecurityPropertiesPathname) {
+ if (!StringUtils.isBlank(gemfireSecurityPropertiesPathname)) {
+ commandLine.add("-DgemfireSecurityPropertyFile=" + gemfireSecurityPropertiesPathname);
+ }
+ }
+
+ protected void addGemFireSystemProperties(final List commandLine, final Properties gemfireProperties) {
+ for (final Object property : gemfireProperties.keySet()) {
+ final String propertyName = property.toString();
+ final String propertyValue = gemfireProperties.getProperty(propertyName);
+ if (!StringUtils.isBlank(propertyValue)) {
+ commandLine.add("-Dgemfire." + propertyName + "=" + propertyValue);
+ }
+ }
+ }
+
+ protected void addInitialHeap(final List commandLine, final String initialHeap) {
+ if (!StringUtils.isBlank(initialHeap)) {
+ commandLine.add("-Xms" + initialHeap);
+ }
+ }
+
+ protected void addJvmArgumentsAndOptions(final List commandLine, final String[] jvmArgsOpts) {
+ if (jvmArgsOpts != null) {
+ commandLine.addAll(Arrays.asList(jvmArgsOpts));
+ }
+ }
+
+ // Fix for Bug #47192 - "Causing the GemFire member (JVM process) to exit on OutOfMemoryErrors"
+ protected void addJvmOptionsForOutOfMemoryErrors(final List commandLine) {
+ if (SystemUtils.isHotSpotVM()) {
+ if (SystemUtils.isWindows()) {
+ // ProcessBuilder "on Windows" needs every word (space separated) to be
+ // a different element in the array/list. See #47312. Need to study why!
+ commandLine.add("-XX:OnOutOfMemoryError=taskkill /F /PID %p");
+ }
+ else { // All other platforms (Linux, Mac OS X, UNIX, etc)
+ commandLine.add("-XX:OnOutOfMemoryError=kill -KILL %p");
+ }
+ }
+ else if (SystemUtils.isJ9VM()) {
+ // NOTE IBM states the following IBM J9 JVM command-line option/switch has side-effects on "performance",
+ // as noted in the reference documentation...
+ // http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic=/com.ibm.java.doc.diagnostics.60/diag/appendixes/cmdline/commands_jvm.html
+ commandLine.add("-Xcheck:memory");
+ }
+ else if (SystemUtils.isJRockitVM()) {
+ // NOTE the following Oracle JRockit JVM documentation was referenced to identify the appropriate JVM option to
+ // set when handling OutOfMemoryErrors.
+ // http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionXX.html
+ commandLine.add("-XXexitOnOutOfMemory");
+ }
+ }
+
+ protected void addMaxHeap(final List commandLine, final String maxHeap) {
+ if (!StringUtils.isBlank(maxHeap)) {
+ commandLine.add("-Xmx" + maxHeap);
+ commandLine.add("-XX:+UseConcMarkSweepGC");
+ commandLine.add("-XX:CMSInitiatingOccupancyFraction=" + CMS_INITIAL_OCCUPANCY_FRACTION);
+ //commandLine.add("-XX:MinHeapFreeRatio=" + MINIMUM_HEAP_FREE_RATIO);
+ }
+ }
+
+ protected LocatorState locatorStatus(final File locatorPidFile, final int oldPid, final String memberName) {
+ final int newPid = readPid(locatorPidFile);
+
+ if (newPid != INVALID_PID && newPid != oldPid) {
+ LocatorState locatorState = new LocatorLauncher.Builder().setPid(newPid).build().status();
+
+ if (ObjectUtils.equals(locatorState.getMemberName(), memberName)) {
+ return locatorState;
+ }
+ }
+
+ return new LocatorState(new LocatorLauncher.Builder().build(), Status.NOT_RESPONDING);
+ }
+
+ protected LocatorState locatorStatus(final String workingDirectory, final String memberName) {
+ LocatorState locatorState = new LocatorLauncher.Builder().setWorkingDirectory(workingDirectory).build().status();
+
+ if (ObjectUtils.equals(locatorState.getMemberName(), memberName)) {
+ return locatorState;
+ }
+
+ return new LocatorState(new LocatorLauncher.Builder().build(), Status.NOT_RESPONDING);
+ }
+
+ protected String readErrorStream(final Process process) throws IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+ StringBuilder message = new StringBuilder();
+
+ for (String line = reader.readLine(); line != null; line = reader.readLine()) {
+ message.append(line);
+ message.append(StringUtils.LINE_SEPARATOR);
+ }
+
+ IOUtils.close(reader);
+
+ return message.toString();
+ }
+
+ protected int readPid(final File pidFile) {
+ assert pidFile != null : "The file from which to read the process ID (pid) cannot be null!";
+
+ if (pidFile.isFile()) {
+ BufferedReader fileReader = null;
+ try {
+ fileReader = new BufferedReader(new FileReader(pidFile));
+ return Integer.parseInt(fileReader.readLine());
+ }
+ catch (IOException ignore) {
+ }
+ catch (NumberFormatException ignore) {
+ }
+ finally {
+ IOUtils.close(fileReader);
+ }
+ }
+
+ return INVALID_PID;
+ }
+
+ protected ServerState serverStatus(final File serverPidFile, final int oldPid, final String memberName) {
+ final int newPid = readPid(serverPidFile);
+
+ if (newPid != INVALID_PID && newPid != oldPid) {
+ ServerState serverState = new ServerLauncher.Builder().setPid(newPid).setDisableDefaultServer(true)
+ .build().status();
+
+ if (ObjectUtils.equals(serverState.getMemberName(), memberName)) {
+ return serverState;
+ }
+ }
+
+ return new ServerState(new ServerLauncher.Builder().build(), Status.NOT_RESPONDING);
+ }
+
+ protected ServerState serverStatus(final String workingDirectory, final String memberName) {
+ ServerState serverState = new ServerLauncher.Builder().setWorkingDirectory(workingDirectory)
+ .setDisableDefaultServer(true).build().status();
+
+ if (ObjectUtils.equals(serverState.getMemberName(), memberName)) {
+ return serverState;
+ }
+
+ return new ServerState(new ServerLauncher.Builder().build(), Status.NOT_RESPONDING);
+ }
+
+ @Deprecated
+ protected String getClasspath(final String userClasspath) {
+ String classpath = getSystemClasspath();
+
+ if (!StringUtils.isBlank(userClasspath)) {
+ classpath += (File.pathSeparator + userClasspath);
+ }
+
+ return classpath;
+ }
+
+ protected String getLocatorClasspath(final boolean includeSystemClasspath, final String userClasspath) {
+ return toClasspath(includeSystemClasspath, new String[] { CORE_DEPENDENCIES_JAR_PATHNAME }, userClasspath);
+ }
+
+ protected String getServerClasspath(final boolean includeSystemClasspath,
+ final boolean includeSpringDependencies,
+ final String userClasspath)
+ {
+ List jarFilePathnames = new ArrayList<>();
+
+ jarFilePathnames.add(CORE_DEPENDENCIES_JAR_PATHNAME);
+
+ if (includeSpringDependencies) {
+ jarFilePathnames.addAll(getSpringJars());
+ }
+
+ return toClasspath(includeSystemClasspath, jarFilePathnames.toArray(new String[jarFilePathnames.size()]),
+ userClasspath);
+ }
+
+ protected List getSpringJars() {
+ File gemfireHomeDirectory= new File(GEMFIRE_HOME);
+
+ assertArgument(gemfireHomeDirectory.isDirectory(),
+ "Please set the GEMFIRE environment variable to the product installation directory.");
+
+ List springJarFilePathnames = new ArrayList<>(SPRING_JAR_NAME_PREFIXES.size());
+
+ for (File jarFile : new File(gemfireHomeDirectory, "lib").listFiles(new FileFilter() {
+ @Override public boolean accept(final File pathname) {
+ return (pathname.getName().startsWith("spring-") && pathname.getAbsolutePath().endsWith(".jar"));
+ }
+ })) {
+ String jarFileName = jarFile.getName();
+ String jarFileNamePrefix = jarFileName.substring(0, jarFileName.lastIndexOf("-"));
+
+ if (SPRING_JAR_NAME_PREFIXES.contains(jarFileNamePrefix.toLowerCase().trim())) {
+ springJarFilePathnames.add(jarFile.getAbsolutePath());
+ }
+ }
+
+ assertState(springJarFilePathnames.size() == SPRING_JAR_NAME_PREFIXES.size(),
+ "Unable to find all the necessary Spring JAR files in $GEMFIRE/lib (%1$s): expected (%2$s); but was (%3$s)",
+ gemfireHomeDirectory, SPRING_JAR_NAME_PREFIXES, springJarFilePathnames);
+
+ return springJarFilePathnames;
+ }
+
+ protected String getSystemClasspath() {
+ return System.getProperty("java.class.path");
+ }
+
+ String toClasspath(final boolean includeSystemClasspath, String[] jarFilePathnames, String... userClasspaths) {
+ // gemfire jar must absolutely be the first JAR file on the CLASSPATH!!!
+ String classpath = getGemFireJarPath();
+
+ userClasspaths = (userClasspaths != null ? userClasspaths : StringUtils.EMPTY_STRING_ARRAY);
+
+ // Then, include user-specified classes on CLASSPATH to enable the user to override GemFire JAR dependencies
+ // with application-specific versions; this logic/block corresponds to classes/jar-files specified with the
+ // --classpath option to the 'start locator' and 'start server commands'; also this will override any
+ // System CLASSPATH environment variable setting, which is consistent with the Java platform behavior...
+ for (String userClasspath : userClasspaths) {
+ if (!StringUtils.isBlank(userClasspath)) {
+ classpath += (classpath.isEmpty() ? StringUtils.EMPTY_STRING : File.pathSeparator);
+ classpath += userClasspath;
+ }
+ }
+
+ // Now, include any System-specified CLASSPATH environment variable setting...
+ if (includeSystemClasspath) {
+ classpath += File.pathSeparator;
+ classpath += getSystemClasspath();
+ }
+
+ jarFilePathnames = (jarFilePathnames != null ? jarFilePathnames : StringUtils.EMPTY_STRING_ARRAY);
+
+ // And finally, include all GemFire dependencies on the CLASSPATH...
+ for (String jarFilePathname : jarFilePathnames) {
+ if (!StringUtils.isBlank(jarFilePathname)) {
+ classpath += (classpath.isEmpty() ? StringUtils.EMPTY_STRING : File.pathSeparator);
+ classpath += jarFilePathname;
+ }
+ }
+
+ return classpath;
+ }
+
+ protected String getGemFireJarPath() {
+ String classpath = getSystemClasspath();
+ String gemfireJarPath = GEMFIRE_JAR_PATHNAME;
+
+ for (String classpathElement : classpath.split(File.pathSeparator)) {
+ // MUST CHANGE THIS TO REGEX SINCE VERSION CHANGES IN JAR NAME
+ if (classpathElement.endsWith("gemfire-core-8.2.0.0-SNAPSHOT.jar")) {
+ gemfireJarPath = classpathElement;
+ break;
+ }
+ }
+
+ return gemfireJarPath;
+ }
+
+ protected String getJavaPath() {
+ return new File(new File(JAVA_HOME, "bin"), "java").getPath();
+ }
+
+ @Deprecated
+ protected String getToolsJarPath() throws AttachAPINotFoundException {
+ String toolsJarPathname = null;
+
+ if (!SystemUtils.isMacOSX()) {
+ toolsJarPathname = IOUtils.appendToPath(JAVA_HOME, "lib", "tools.jar");
+
+ if (!IOUtils.isExistingPathname(toolsJarPathname)) {
+ // perhaps the java.home System property refers to the JRE ($JAVA_HOME/jre)...
+ String JDK_HOME = new File(JAVA_HOME).getParentFile().getPath();
+ toolsJarPathname = IOUtils.appendToPath(JDK_HOME, "lib", "tools.jar");
+ }
+
+ try {
+ IOUtils.verifyPathnameExists(toolsJarPathname);
+ }
+ catch (IOException e) {
+ throw new AttachAPINotFoundException(getAttachAPINotFoundMessage());
+ }
+ }
+
+ return toolsJarPathname;
+ }
+
+ // TODO refactor the following method into a common base class or utility class
+ protected String getLocalHost() {
+ try {
+ return SocketCreator.getLocalHost().getCanonicalHostName();
+ }
+ catch (UnknownHostException ignore) {
+ return LOCALHOST;
+ }
+ }
+
+ protected String getAttachAPINotFoundMessage() {
+ return CliStrings.format(CliStrings.ATTACH_API_IN_0_NOT_FOUND_ERROR_MESSAGE,
+ ((SystemUtils.isMacOSX() && SystemUtils.isAppleJVM()) ? "classes.jar" : "tools.jar"));
+ }
+
+ protected String getLocatorId(final String host, final Integer port) {
+ final String locatorHost = (host != null ? host : getLocalHost());
+ final String locatorPort = StringUtils.valueOf(port, String.valueOf(DistributionLocator.DEFAULT_LOCATOR_PORT));
+ return locatorHost.concat("[").concat(locatorPort).concat("]");
+ }
+
+ /**
+ * Gets a proxy to the DistributedSystemMXBean from the GemFire Manager's MBeanServer, or null if unable to find
+ * the DistributedSystemMXBean.
+ *
+ * @return a proxy to the DistributedSystemMXBean from the GemFire Manager's MBeanServer, or null if unable to find
+ * the DistributedSystemMXBean.
+ */
+ protected DistributedSystemMXBean getDistributedSystemMXBean() throws IOException, MalformedObjectNameException {
+ assertState(isConnectedAndReady(), "Gfsh must be connected in order to get proxy to a GemFire DistributedSystemMXBean.");
+ return getGfsh().getOperationInvoker().getDistributedSystemMXBean();
+ }
+
+ /**
+ * Gets a proxy to the MemberMXBean for the GemFire member specified by member name or ID from the GemFire Manager's
+ * MBeanServer.
+ *
+ * @param member a String indicating the GemFire member's name or ID.
+ * @return a proxy to the MemberMXBean having the specified GemFire member's name or ID from the GemFire Manager's
+ * MBeanServer, or null if no GemFire member could be found with the specified member name or ID.
+ * @see #getMemberMXBean(String, String)
+ */
+ protected MemberMXBean getMemberMXBean(final String member) throws IOException {
+ return getMemberMXBean(null, member);
+ }
+
+ protected MemberMXBean getMemberMXBean(final String serviceName, final String member) throws IOException {
+ assertState(isConnectedAndReady(), "Gfsh must be connected in order to get proxy to a GemFire Member MBean.");
+
+ MemberMXBean memberBean = null;
+
+ try {
+ String objectNamePattern = ManagementConstants.OBJECTNAME__PREFIX;
+
+ objectNamePattern += (StringUtils.isBlank(serviceName) ? StringUtils.EMPTY_STRING
+ : "service=" + serviceName + StringUtils.COMMA_DELIMITER);
+ objectNamePattern += "type=Member,*";
+
+ // NOTE throws a MalformedObjectNameException, however, this should not happen since the ObjectName is constructed
+ // here in a conforming pattern
+ final ObjectName objectName = ObjectName.getInstance(objectNamePattern);
+
+ final QueryExp query = Query.or(
+ Query.eq(Query.attr("Name"), Query.value(member)),
+ Query.eq(Query.attr("Id"), Query.value(member))
+ );
+
+ final Set memberObjectNames = getGfsh().getOperationInvoker().queryNames(objectName, query);
+
+ if (!memberObjectNames.isEmpty()) {
+ memberBean = getGfsh().getOperationInvoker().getMBeanProxy(memberObjectNames.iterator().next(), MemberMXBean.class);
+ }
+ }
+ catch (MalformedObjectNameException e) {
+ getGfsh().logSevere(e.getMessage(), e);
+ }
+
+ return memberBean;
+ }
+
+ protected String getServerId(final String host, final Integer port) {
+ String serverHost = (host != null ? host : getLocalHost());
+ String serverPort = StringUtils.valueOf(port, String.valueOf(CacheServer.DEFAULT_PORT));
+ return serverHost.concat("[").concat(serverPort).concat("]");
+ }
+
+ protected boolean isStartingNotRespondingOrNull(final ServiceState serviceState) {
+ return (serviceState == null || isStartingOrNotResponding(serviceState.getStatus()));
+ }
+
+ protected boolean isStartingOrNotResponding(final Status processStatus) {
+ return (Status.NOT_RESPONDING.equals(processStatus) || Status.STARTING.equals(processStatus));
+ }
+
+ protected boolean isVmWithProcessIdRunning(final Integer pid) {
+ // note: this will use JNA if available or Attach if available or return false if neither is available
+ return ProcessUtils.isProcessAlive(pid);
+ }
+
+ @CliCommand(value = CliStrings.START_SERVER, help = CliStrings.START_SERVER__HELP)
+ @CliMetaData(shellOnly = true, relatedTopic = { CliStrings.TOPIC_GEMFIRE_SERVER, CliStrings.TOPIC_GEMFIRE_LIFECYCLE })
++ @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+ public Result startServer(@CliOption(key = CliStrings.START_SERVER__ASSIGN_BUCKETS,
+ unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_SERVER__ASSIGN_BUCKETS__HELP)
+ final Boolean assignBuckets,
+ @CliOption(key = CliStrings.START_SERVER__BIND_ADDRESS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__BIND_ADDRESS__HELP)
+ final String bindAddress,
+ @CliOption(key = CliStrings.START_SERVER__CACHE_XML_FILE,
+ optionContext = ConverterHint.FILE_PATHSTRING,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__CACHE_XML_FILE__HELP)
+ String cacheXmlPathname,
+ @CliOption(key = CliStrings.START_SERVER__CLASSPATH,
+ /*optionContext = ConverterHint.FILE_PATHSTRING, // there's an issue with TAB here*/
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__CLASSPATH__HELP)
+ final String classpath,
+ @CliOption(key = CliStrings.START_SERVER__CRITICAL__HEAP__PERCENTAGE,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__CRITICAL__HEAP__HELP)
+ final Float criticalHeapPercentage,
+ @CliOption(key = CliStrings.START_SERVER__CRITICAL_OFF_HEAP_PERCENTAGE,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__CRITICAL_OFF_HEAP__HELP)
+ final Float criticalOffHeapPercentage,
+ @CliOption(key = CliStrings.START_SERVER__DIR,
+ optionContext = ConverterHint.DIR_PATHSTRING,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__DIR__HELP)
+ String workingDirectory,
+ @CliOption(key = CliStrings.START_SERVER__DISABLE_DEFAULT_SERVER,
+ unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_SERVER__DISABLE_DEFAULT_SERVER__HELP)
+ final Boolean disableDefaultServer,
+ @CliOption(key = CliStrings.START_SERVER__DISABLE_EXIT_WHEN_OUT_OF_MEMORY,
+ unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_SERVER__DISABLE_EXIT_WHEN_OUT_OF_MEMORY_HELP)
+ final Boolean disableExitWhenOutOfMemory,
+ @CliOption(key = CliStrings.START_SERVER__ENABLE_TIME_STATISTICS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_SERVER__ENABLE_TIME_STATISTICS__HELP)
+ final Boolean enableTimeStatistics,
+ @CliOption(key = CliStrings.START_SERVER__EVICTION__HEAP__PERCENTAGE,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__EVICTION__HEAP__PERCENTAGE__HELP)
+ final Float evictionHeapPercentage,
+ @CliOption(key = CliStrings.START_SERVER__EVICTION_OFF_HEAP_PERCENTAGE,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__EVICTION_OFF_HEAP_PERCENTAGE__HELP)
+ final Float evictionOffHeapPercentage,
+ @CliOption(key = CliStrings.START_SERVER__FORCE,
+ unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_SERVER__FORCE__HELP)
+ final Boolean force,
+ @CliOption(key = CliStrings.START_SERVER__GROUP,
+ optionContext = ConverterHint.MEMBERGROUP,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__GROUP__HELP)
+ final String group,
+ @CliOption(key = CliStrings.START_SERVER__HOSTNAME__FOR__CLIENTS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__HOSTNAME__FOR__CLIENTS__HELP)
+ final String hostNameForClients,
+ @CliOption(key = CliStrings.START_SERVER__INCLUDE_SYSTEM_CLASSPATH,
+ specifiedDefaultValue = "true",
+ unspecifiedDefaultValue = "false",
+ help = CliStrings.START_SERVER__INCLUDE_SYSTEM_CLASSPATH__HELP)
+ final Boolean includeSystemClasspath,
+ @CliOption(key = CliStrings.START_SERVER__INITIAL_HEAP,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__INITIAL_HEAP__HELP)
+ final String initialHeap,
+ @CliOption(key = CliStrings.START_SERVER__J,
+ optionContext = ConverterHint.STRING_LIST,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__J__HELP)
+ @CliMetaData(valueSeparator = ",")
+ final String[] jvmArgsOpts,
+ @CliOption(key = CliStrings.START_SERVER__LOCATORS,
+ optionContext = ConverterHint.LOCATOR_DISCOVERY_CONFIG,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__LOCATORS__HELP)
+ final String locators,
+ @CliOption(key = CliStrings.START_SERVER__LOCATOR_WAIT_TIME,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__LOCATOR_WAIT_TIME_HELP)
+ final Integer locatorWaitTime,
+ @CliOption(key = CliStrings.START_SERVER__LOCK_MEMORY,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_SERVER__LOCK_MEMORY__HELP)
+ final Boolean lockMemory,
+ @CliOption(key = CliStrings.START_SERVER__LOG_LEVEL,
+ optionContext = ConverterHint.LOG_LEVEL,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__LOG_LEVEL__HELP)
+ final String logLevel,
+ @CliOption(key = CliStrings.START_SERVER__MAX__CONNECTIONS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MAX__CONNECTIONS__HELP)
+ final Integer maxConnections,
+ @CliOption(key = CliStrings.START_SERVER__MAXHEAP,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MAXHEAP__HELP)
+ final String maxHeap,
+ @CliOption(key = CliStrings.START_SERVER__MAX__MESSAGE__COUNT,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MAX__MESSAGE__COUNT__HELP)
+ final Integer maxMessageCount,
+ @CliOption(key = CliStrings.START_SERVER__MAX__THREADS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MAX__THREADS__HELP)
+ final Integer maxThreads,
+ @CliOption(key = CliStrings.START_SERVER__MCAST_ADDRESS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MCAST_ADDRESS__HELP)
+ final String mcastBindAddress,
+ @CliOption(key = CliStrings.START_SERVER__MCAST_PORT,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MCAST_PORT__HELP)
+ final Integer mcastPort,
+ @CliOption(key = CliStrings.START_SERVER__MEMCACHED_PORT,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MEMCACHED_PORT__HELP)
+ final Integer memcachedPort,
+ @CliOption(key = CliStrings.START_SERVER__MEMCACHED_PROTOCOL,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MEMCACHED_PROTOCOL__HELP)
+ final String memcachedProtocol,
+ @CliOption(key = CliStrings.START_SERVER__MEMCACHED_BIND_ADDRESS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MEMCACHED_BIND_ADDRESS__HELP)
+ final String memcachedBindAddress,
+ @CliOption(key = CliStrings.START_SERVER__REDIS_PORT,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__REDIS_PORT__HELP)
+ final Integer redisPort,
+ @CliOption(key = CliStrings.START_SERVER__REDIS_BIND_ADDRESS,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__REDIS_BIND_ADDRESS__HELP)
+ final String redisBindAddress,
+ @CliOption(key = CliStrings.START_SERVER__REDIS_PASSWORD,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__REDIS_PASSWORD__HELP)
+ final String redisPassword,
+ @CliOption(key = CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE__HELP)
+ final Integer messageTimeToLive,
+ @CliOption(key = CliStrings.START_SERVER__NAME,
+ mandatory = true,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__NAME__HELP)
+ final String memberName,
+ @CliOption(key = CliStrings.START_SERVER__OFF_HEAP_MEMORY_SIZE,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__OFF_HEAP_MEMORY_SIZE__HELP)
+ final String offHeapMemorySize,
+ @CliOption(key = CliStrings.START_SERVER__PROPERTIES,
+ optionContext = ConverterHint.FILE_PATHSTRING,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__PROPERTIES__HELP)
+ String gemfirePropertiesPathname,
+ @CliOption(key = CliStrings.START_SERVER__REBALANCE,
+ unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_SERVER__REBALANCE__HELP)
+ final Boolean rebalance,
+ @CliOption(key = CliStrings.START_SERVER__SECURITY_PROPERTIES,
+ optionContext = ConverterHint.FILE_PATHSTRING,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__SECURITY_PROPERTIES__HELP)
+ String gemfireSecurityPropertiesPathname,
+ @CliOption(key = CliStrings.START_SERVER__SERVER_BIND_ADDRESS,
+ unspecifiedDefaultValue = CacheServer.DEFAULT_BIND_ADDRESS,
+ help = CliStrings.START_SERVER__SERVER_BIND_ADDRESS__HELP)
+ final String serverBindAddress,
+ @CliOption(key = CliStrings.START_SERVER__SERVER_PORT,
+ unspecifiedDefaultValue = ("" + CacheServer.DEFAULT_PORT),
+ help = CliStrings.START_SERVER__SERVER_PORT__HELP)
+ final Integer serverPort,
+ @CliOption(key = CliStrings.START_SERVER__SOCKET__BUFFER__SIZE,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__SOCKET__BUFFER__SIZE__HELP)
+ final Integer socketBufferSize,
+ @CliOption(key = CliStrings.START_SERVER__SPRING_XML_LOCATION,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__SPRING_XML_LOCATION_HELP)
+ final String springXmlLocation,
+ @CliOption(key = CliStrings.START_SERVER__STATISTIC_ARCHIVE_FILE,
+ unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+ help = CliStrings.START_SERVER__STATISTIC_ARCHIVE_FILE__HELP)
+ final String statisticsArchivePathname,
+ @CliOption(key = CliStrings.START_SERVER__USE_CLUSTER_CONFIGURATION,
+ unspecifiedDefaultValue = "true",
+ specifiedDefaultValue = "true",
+ help = CliStrings.START_SERVER__USE_CLUSTER_CONFIGURATION__HELP)
+ final Boolean requestSharedConfiguration)
+ // NOTICE: keep the parameters in alphabetical order based on their CliStrings.START_SERVER_* text
+ {
+
+ try {
+ if (workingDirectory == null) {
+ // attempt to use or make sub-directory using memberName...
+ File serverWorkingDirectory = new File(memberName);
+
+ if (!(serverWorkingDirectory.exists() || serverWorkingDirectory.mkdir())) {
+ throw new IllegalStateException(CliStrings.format(CliStrings.START_SERVER__MSG__COULD_NOT_CREATE_DIRECTORY_0_VERIFY_PERMISSIONS,
+ serverWorkingDirectory.getAbsolutePath()));
+ }
+
+ workingDirectory = IOUtils.tryGetCanonicalPathElseGetAbsolutePath(serverWorkingDirectory);
+ }
+
+ cacheXmlPathname = CliUtil.resolvePathname(cacheXmlPathname);
+
+ if (!StringUtils.isBlank(cacheXmlPathname) && !IOUtils.isExistingPathname(cacheXmlPathname)) {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(CliStrings.CACHE_XML_NOT_FOUND_MESSAGE, cacheXmlPathname));
+ }
+
+ gemfirePropertiesPathname = CliUtil.resolvePathname(gemfirePropertiesPathname);
+
+ if (!StringUtils.isBlank(gemfirePropertiesPathname) && !IOUtils.isExistingPathname(gemfirePropertiesPathname)) {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(CliStrings.GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
+ StringUtils.EMPTY_STRING, gemfirePropertiesPathname));
+ }
+
+ gemfireSecurityPropertiesPathname = CliUtil.resolvePathname(gemfireSecurityPropertiesPathname);
+
+ if (!StringUtils.isBlank(gemfireSecurityPropertiesPathname) && !IOUtils.isExistingPathname(gemfireSecurityPropertiesPathname)) {
+ return ResultBuilder.createUserErrorResult(CliStrings.format(CliStrings.GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
+ "Security ", gemfireSecurityPropertiesPathname));
+ }
+
+ File serverPidFile = new File(workingDirectory, ProcessType.SERVER.getPidFileName());
+
+