/*
* 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 org.apache.geode.management.cli;
import java.util.Collections;
import java.util.Map;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheClosedException;
import org.apache.geode.internal.i18n.LocalizedStrings;
import org.apache.geode.management.DependenciesNotFoundException;
import org.apache.geode.management.internal.cli.CliUtil;
import org.apache.geode.management.internal.cli.remote.MemberCommandService;
/**
* Processes remote GemFire Command Line Interface (CLI) commands. Refer to the vFabric GemFire
* documentation for information regarding local vs. remote commands.
* <p>
* <b>NOTE:</b> <code>CommandService</code> is currently available only on GemFire Manager nodes.
*
*
* @since GemFire 7.0
*/
public abstract class CommandService {
protected static final Map<String, String> EMPTY_ENV = Collections.emptyMap();
private static CommandService localCommandService;
/* ************* Methods to be implemented by sub-classes START *********** */
/**
* Returns whether the underlying <code>Cache</code> exists and is not closed. The Cache must be
* ready in order for commands to be processed using this <code>CommandService</code>. A call to
* this method should be made before attempting to process commands.
*
* @return True if the <code>Cache</code> exists and is not closed, false otherwise.
*/
public abstract boolean isUsable();
/**
* Processes the specified command string. Only remote commands can be processed using this
* method. Refer to the vFabric GemFire documentation for details.
*
* @param commandString Command string to be processed.
* @return The {@link Result} of the execution of this command string.
*/
public abstract Result processCommand(String commandString);
/**
* Processes the specified command string. Only remote commands can be processed using this
* method. Refer to the vFabric GemFire documentation for details.
*
* @param commandString Command string to be processed.
* @param env Environmental values that will be used during the execution of this command.
* @return The {@link Result} of the execution of this command string.
*/
protected abstract Result processCommand(String commandString, Map<String, String> env);
/**
* Creates a <code>CommandStatement</code> from the specified command string. Only remote commands
* can be processed using this method. Refer to the vFabric GemFire documentation for details.
*
* @param commandString Command string from which to create a <code>CommandStatement</code>.
* @return A <code>CommandStatement</code> which can be used to repeatedly process the same
* command.
*
* @see CommandStatement#process()
*/
public abstract CommandStatement createCommandStatement(String commandString);
/**
* Creates a <code>CommandStatement</code> from the specified command string. Only remote commands
* can be processed using this method. Refer to the vFabric GemFire documentation for details.
*
* @param commandString Command string from which to create a <code>CommandStatement</code>.
* @param env Environmental values that will be used during the execution of this command.
* @return A <code>CommandStatement</code> which can be used to repeatedly process the same
* command.
*
* @see CommandStatement#process()
*/
protected abstract CommandStatement createCommandStatement(String commandString,
Map<String, String> env);
/* ************** Methods to be implemented by sub-classes END ************ */
/* **************************** factory methods *************************** */
/**
* Returns a newly created or existing instance of the
* <code>CommandService<code> associated with the
* specified <code>Cache</code>.
*
* @param cache Underlying <code>Cache</code> instance to be used to create a Command Service.
* @throws CommandServiceException If command service could not be initialized.
*/
public static final CommandService createLocalCommandService(Cache cache)
throws CommandServiceException {
if (cache == null || cache.isClosed()) {
throw new CacheClosedException(
"Can not create command service as cache doesn't exist or cache is closed.");
}
/*
* if (!cache.isServer()) { throw new IllegalArgumentException("Server cache is required."); }
*/
if (localCommandService == null || !localCommandService.isUsable()) {
String nonExistingDependency = CliUtil.cliDependenciesExist(false);
if (nonExistingDependency != null) {
throw new DependenciesNotFoundException(
LocalizedStrings.CommandServiceManager_COULD_NOT_FIND__0__LIB_NEEDED_FOR_CLI_GFSH
.toLocalizedString(new Object[] {nonExistingDependency}));
}
localCommandService = new MemberCommandService(cache);
}
return localCommandService;
}
/**
* Returns an existing 'usable' <code>CommandService></code>. A <code>CommandService</code> is
* considered usable if at has an underlying <code>Cache</code> which is not closed.
*
* @return A usable <code>CommandService</code> or null if one cannot be found.
*/
public static final CommandService getUsableLocalCommandService() {
if (localCommandService != null && localCommandService.isUsable()) {
return localCommandService;
}
return null;
}
// public static CommandService createCommandService(RegionService regionService) {
// if (regionService == null || regionService.isClosed()) {
// throw new CacheClosedException("Can not create command service as region service doesn't exist
// or cache is closed.");
// }
//
// CommandService commandService;
//
// if (Cache.class.isInstance(regionService) &&
// ((Cache) regionService).isServer() &&
// CacheFactory.getAnyInstance() == regionService) {
// commandService = createLocalCommandService((Cache) regionService);
// } else {
// Pool poolToUse = null;
// if (ProxyCache.class.isInstance(regionService)) {
// ProxyCache proxyCache = (ProxyCache) regionService;
// poolToUse = proxyCache.getUserAttributes().getPool();
// } else if (ClientCache.class.isInstance(regionService)) {
// ClientCache localCache = (ClientCache) regionService;
// poolToUse = localCache.getDefaultPool();
// } else {
// throw new IllegalArgumentException("Can not create Command Service for given Region Service: "
// + regionService);
// }
// commandService = new ProxyCommandService(poolToUse);
// }
//
// return commandService;
// }
//
// public static CommandService createRemoteCommandService(String poolName) {
// Pool poolToUse = PoolManager.find(poolName);
//
// if (poolToUse == null) {
// throw new IllegalArgumentException("Can not create Command Service as a Pool with name \"" +
// poolName+"\" was not found.");
// }
//
// return new ProxyCommandService(poolToUse);
// }
}