You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2017/08/29 16:30:24 UTC
[07/25] geode git commit: GEODE-3436: Restore refactoring of
Refactoring FunctionCommands
GEODE-3436: Restore refactoring of Refactoring FunctionCommands
* See initial commit GEODE-3260 (90f5440de8ec747f301a309a0a34101e8defcd29)
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/39fff454
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/39fff454
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/39fff454
Branch: refs/heads/develop
Commit: 39fff4544c8ddc0b96ff58ed56c7394b1e9e10e4
Parents: 0c124b7
Author: YehEmily <em...@gmail.com>
Authored: Mon Aug 7 12:56:17 2017 -0700
Committer: Jinmei Liao <ji...@pivotal.io>
Committed: Tue Aug 29 09:27:25 2017 -0700
----------------------------------------------------------------------
.../cli/commands/DestroyFunctionCommand.java | 163 ++++++
.../cli/commands/ExecuteFunctionCommand.java | 330 ++++++++++++
.../internal/cli/commands/FunctionCommands.java | 537 -------------------
.../cli/commands/ListFunctionCommand.java | 103 ++++
.../controllers/FunctionCommandsController.java | 13 +-
.../internal/security/TestCommand.java | 4 +-
6 files changed, 606 insertions(+), 544 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/39fff454/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyFunctionCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyFunctionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyFunctionCommand.java
new file mode 100644
index 0000000..37beb97
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyFunctionCommand.java
@@ -0,0 +1,163 @@
+/*
+ * 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.internal.cli.commands;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.execute.Execution;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionException;
+import org.apache.geode.cache.execute.FunctionService;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
+import org.apache.geode.management.internal.cli.GfshParseResult;
+import org.apache.geode.management.internal.cli.functions.UnregisterFunction;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.ErrorResultData;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission;
+
+public class DestroyFunctionCommand implements GfshCommand {
+ @CliCommand(value = CliStrings.DESTROY_FUNCTION, help = CliStrings.DESTROY_FUNCTION__HELP)
+ @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION},
+ interceptor = "org.apache.geode.management.internal.cli.commands.DestroyFunctionCommand$Interceptor")
+ @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
+ operation = ResourcePermission.Operation.MANAGE, target = ResourcePermission.Target.JAR)
+ // TODO: Add optioncontext for functionId
+ public Result destroyFunction(
+ @CliOption(key = CliStrings.DESTROY_FUNCTION__ID, mandatory = true,
+ help = CliStrings.DESTROY_FUNCTION__HELP) String functionId,
+ @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+ optionContext = ConverterHint.MEMBERGROUP,
+ help = CliStrings.DESTROY_FUNCTION__ONGROUPS__HELP) String[] groups,
+ @CliOption(key = CliStrings.MEMBER, optionContext = ConverterHint.MEMBERIDNAME,
+ help = CliStrings.DESTROY_FUNCTION__ONMEMBER__HELP) String memberId) {
+ try {
+ InternalCache cache = getCache();
+ Set<DistributedMember> dsMembers = new HashSet<>();
+ if (groups != null && memberId != null) {
+ return ResultBuilder
+ .createUserErrorResult(CliStrings.DESTROY_FUNCTION__MSG__PROVIDE_OPTION);
+ } else if (groups != null && groups.length > 0) {
+ // execute on group members
+ for (String grp : groups) {
+ dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(grp));
+ }
+ @SuppressWarnings("unchecked")
+ Result results = executeFunction(cache, dsMembers, functionId);
+ return results;
+ } else if (memberId != null) {
+ // execute on member
+ dsMembers.add(getMember(cache, memberId));
+ @SuppressWarnings("unchecked")
+ Result results = executeFunction(cache, dsMembers, functionId);
+ return results;
+ } else {
+ // no option provided.
+ @SuppressWarnings("unchecked")
+ Result results = executeFunction(cache, cache.getMembers(), functionId);
+ return results;
+ }
+ } catch (Exception e) {
+ ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+ .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(e.getMessage());
+ return ResultBuilder.buildResult(errorResultData);
+ }
+ }
+
+ private Result executeFunction(InternalCache cache, Set<DistributedMember> DsMembers,
+ String functionId) {
+ // unregister on a set of of members
+ Function unregisterFunction = new UnregisterFunction();
+ FunctionService.registerFunction(unregisterFunction);
+ List resultList;
+
+ if (DsMembers.isEmpty()) {
+ return ResultBuilder.createInfoResult("No members for execution");
+ }
+ Object[] obj = new Object[1];
+ obj[0] = functionId;
+
+ Execution execution = FunctionService.onMembers(DsMembers).setArguments(obj);
+
+ if (execution == null) {
+ cache.getLogger().error("executeUnregister execution is null");
+ ErrorResultData errorResultData =
+ ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+ .addLine(CliStrings.DESTROY_FUNCTION__MSG__CANNOT_EXECUTE);
+ return (ResultBuilder.buildResult(errorResultData));
+ }
+ try {
+ resultList = (ArrayList) execution.execute(unregisterFunction).getResult();
+ } catch (FunctionException ex) {
+ ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+ .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(ex.getMessage());
+ return (ResultBuilder.buildResult(errorResultData));
+ }
+ String resultStr = ((String) resultList.get(0));
+ if (resultStr.equals("Succeeded in unregistering")) {
+ StringBuilder members = new StringBuilder();
+ for (DistributedMember member : DsMembers) {
+ members.append(member.getId());
+ members.append(",");
+ }
+ return ResultBuilder.createInfoResult("Destroyed " + functionId + " Successfully on "
+ + members.toString().substring(0, members.toString().length() - 1));
+ } else {
+ return ResultBuilder.createInfoResult("Failed in unregistering");
+ }
+ }
+
+ /**
+ * Interceptor used by gfsh to intercept execution of destroy.
+ */
+ public static class Interceptor extends AbstractCliAroundInterceptor {
+ @Override
+ public Result preExecution(GfshParseResult parseResult) {
+ Map<String, String> paramValueMap = parseResult.getParamValueStrings();
+ paramValueMap.entrySet();
+ String onGroup = paramValueMap.get(CliStrings.GROUP);
+ String onMember = paramValueMap.get(CliStrings.MEMBER);
+
+ if ((onGroup == null && onMember == null)) {
+ Response response = readYesNo("Do you really want to destroy "
+ + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID) + " on entire DS?", Response.NO);
+ if (response == Response.NO) {
+ return ResultBuilder.createShellClientAbortOperationResult(
+ "Aborted destroy of " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
+ } else {
+ return ResultBuilder
+ .createInfoResult("Destroying " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
+ }
+ } else {
+ return ResultBuilder
+ .createInfoResult("Destroying " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/39fff454/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommand.java
new file mode 100644
index 0000000..a016ccf
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommand.java
@@ -0,0 +1,330 @@
+/*
+ * 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.internal.cli.commands;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.execute.Execution;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionException;
+import org.apache.geode.cache.execute.FunctionService;
+import org.apache.geode.cache.execute.ResultCollector;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.ClassPathLoader;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.DistributedRegionMXBean;
+import org.apache.geode.management.ManagementService;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.MBeanJMXAdapter;
+import org.apache.geode.management.internal.cli.CliUtil;
+import org.apache.geode.management.internal.cli.LogWrapper;
+import org.apache.geode.management.internal.cli.functions.UserFunctionExecution;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.CompositeResultData;
+import org.apache.geode.management.internal.cli.result.ErrorResultData;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.result.TabularResultData;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission;
+
+public class ExecuteFunctionCommand implements GfshCommand {
+ @CliCommand(value = CliStrings.EXECUTE_FUNCTION, help = CliStrings.EXECUTE_FUNCTION__HELP)
+ @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION})
+ @ResourceOperation(resource = ResourcePermission.Resource.DATA,
+ operation = ResourcePermission.Operation.WRITE)
+ public Result executeFunction(
+ // TODO: Add optioncontext for functionID
+ @CliOption(key = CliStrings.EXECUTE_FUNCTION__ID, mandatory = true,
+ help = CliStrings.EXECUTE_FUNCTION__ID__HELP) String functionId,
+ @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+ optionContext = ConverterHint.MEMBERGROUP,
+ help = CliStrings.EXECUTE_FUNCTION__ONGROUPS__HELP) String[] onGroups,
+ @CliOption(key = CliStrings.MEMBER, optionContext = ConverterHint.MEMBERIDNAME,
+ help = CliStrings.EXECUTE_FUNCTION__ONMEMBER__HELP) String onMember,
+ @CliOption(key = CliStrings.EXECUTE_FUNCTION__ONREGION,
+ optionContext = ConverterHint.REGION_PATH,
+ help = CliStrings.EXECUTE_FUNCTION__ONREGION__HELP) String onRegion,
+ @CliOption(key = CliStrings.EXECUTE_FUNCTION__ARGUMENTS,
+ help = CliStrings.EXECUTE_FUNCTION__ARGUMENTS__HELP) String[] arguments,
+ @CliOption(key = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR,
+ help = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR__HELP) String resultCollector,
+ @CliOption(key = CliStrings.EXECUTE_FUNCTION__FILTER,
+ help = CliStrings.EXECUTE_FUNCTION__FILTER__HELP) String filterString) {
+ CompositeResultData executeFunctionResultTable = ResultBuilder.createCompositeResultData();
+ TabularResultData resultTable = executeFunctionResultTable.addSection().addTable("Table1");
+ String headerText = "Execution summary";
+ resultTable.setHeader(headerText);
+ ResultCollector resultCollectorInstance = null;
+ Set<String> filters = new HashSet<>();
+ Execution execution;
+ if (functionId != null) {
+ functionId = functionId.trim();
+ }
+ if (onRegion != null) {
+ onRegion = onRegion.trim();
+ }
+ if (onMember != null) {
+ onMember = onMember.trim();
+ }
+ if (filterString != null) {
+ filterString = filterString.trim();
+ }
+
+ try {
+ // validate otherwise return right away. no need to process anything
+ if (functionId == null || functionId.length() == 0) {
+ ErrorResultData errorResultData =
+ ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+ .addLine(CliStrings.EXECUTE_FUNCTION__MSG__MISSING_FUNCTIONID);
+ return ResultBuilder.buildResult(errorResultData);
+ }
+
+ if (isMoreThanOneTrue(onRegion != null, onMember != null, onGroups != null)) {
+ // Provide Only one of region/member/groups
+ ErrorResultData errorResultData =
+ ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+ .addLine(CliStrings.EXECUTE_FUNCTION__MSG__OPTIONS);
+ return ResultBuilder.buildResult(errorResultData);
+ } else if ((onRegion == null || onRegion.length() == 0) && (filterString != null)) {
+ ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+ .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+ .addLine(CliStrings.EXECUTE_FUNCTION__MSG__MEMBER_SHOULD_NOT_HAVE_FILTER_FOR_EXECUTION);
+ return ResultBuilder.buildResult(errorResultData);
+ }
+
+ InternalCache cache = getCache();
+
+ if (resultCollector != null) {
+ resultCollectorInstance =
+ (ResultCollector) ClassPathLoader.getLatest().forName(resultCollector).newInstance();
+ }
+
+ if (filterString != null && filterString.length() > 0) {
+ filters.add(filterString);
+ }
+
+ if (onRegion == null && onMember == null && onGroups == null) {
+ // run function on all the members excluding locators bug#46113
+ // if user wish to execute on locator then he can choose --member or --group option
+ Set<DistributedMember> dsMembers = CliUtil.getAllNormalMembers(cache);
+ if (dsMembers.size() > 0) {
+ new UserFunctionExecution();
+ LogWrapper.getInstance().info(CliStrings
+ .format(CliStrings.EXECUTE_FUNCTION__MSG__EXECUTING_0_ON_ENTIRE_DS, functionId));
+ for (DistributedMember member : dsMembers) {
+ executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
+ member, resultTable, onRegion);
+ }
+ return ResultBuilder.buildResult(resultTable);
+ } else {
+ return ResultBuilder
+ .createUserErrorResult(CliStrings.EXECUTE_FUNCTION__MSG__DS_HAS_NO_MEMBERS);
+ }
+ } else if (onRegion != null && onRegion.length() > 0) {
+ if (cache.getRegion(onRegion) == null) {
+ // find a member where region is present
+ DistributedRegionMXBean bean = ManagementService.getManagementService(getCache())
+ .getDistributedRegionMXBean(onRegion);
+ if (bean == null) {
+ bean = ManagementService.getManagementService(getCache())
+ .getDistributedRegionMXBean(Region.SEPARATOR + onRegion);
+
+ if (bean == null) {
+ return ResultBuilder.createGemFireErrorResult(CliStrings
+ .format(CliStrings.EXECUTE_FUNCTION__MSG__MXBEAN_0_FOR_NOT_FOUND, onRegion));
+ }
+ }
+
+ DistributedMember member = null;
+ String[] membersName = bean.getMembers();
+ Set<DistributedMember> dsMembers = CliUtil.getAllMembers(cache);
+ Iterator it = dsMembers.iterator();
+ boolean matchFound = false;
+
+ if (membersName.length > 0) {
+ while (it.hasNext() && !matchFound) {
+ DistributedMember dsmember = (DistributedMember) it.next();
+ for (String memberName : membersName) {
+ if (MBeanJMXAdapter.getMemberNameOrId(dsmember).equals(memberName)) {
+ member = dsmember;
+ matchFound = true;
+ break;
+ }
+ }
+ }
+ }
+ if (matchFound) {
+ executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
+ member, resultTable, onRegion);
+ return ResultBuilder.buildResult(resultTable);
+ } else {
+ return ResultBuilder.createGemFireErrorResult(CliStrings.format(
+ CliStrings.EXECUTE_FUNCTION__MSG__NO_ASSOCIATED_MEMBER_REGION, " " + onRegion));
+ }
+ } else {
+ execution = FunctionService.onRegion(cache.getRegion(onRegion));
+ if (execution != null) {
+ if (resultCollectorInstance != null) {
+ execution = execution.withCollector(resultCollectorInstance);
+ }
+ if (filters.size() > 0) {
+ execution = execution.withFilter(filters);
+ }
+ if (arguments != null && arguments.length > 0) {
+ execution = execution.setArguments(arguments);
+ }
+
+ try {
+ List<Object> results = (List<Object>) execution.execute(functionId).getResult();
+ if (results.size() > 0) {
+ StringBuilder strResult = new StringBuilder();
+ for (Object obj : results) {
+ strResult.append(obj);
+ }
+ toTabularResultData(resultTable,
+ cache.getDistributedSystem().getDistributedMember().getId(),
+ strResult.toString());
+ }
+ return ResultBuilder.buildResult(resultTable);
+ } catch (FunctionException e) {
+ return ResultBuilder.createGemFireErrorResult(CliStrings.format(
+ CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_REGION_1_DETAILS_2,
+ functionId, onRegion, e.getMessage()));
+ }
+ } else {
+ return ResultBuilder.createGemFireErrorResult(CliStrings.format(
+ CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_REGION_1_DETAILS_2,
+ functionId, onRegion,
+ CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR));
+ }
+ }
+ } else if (onGroups != null) {
+ // execute on group members
+ Set<DistributedMember> dsMembers = new HashSet<>();
+ for (String grp : onGroups) {
+ dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(grp));
+ }
+
+ if (dsMembers.size() > 0) {
+ for (DistributedMember member : dsMembers) {
+ executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
+ member, resultTable, onRegion);
+ }
+ return ResultBuilder.buildResult(resultTable);
+ } else {
+ StringBuilder grps = new StringBuilder();
+ for (String grp : onGroups) {
+ grps.append(grp);
+ grps.append(", ");
+ }
+ return ResultBuilder.createUserErrorResult(
+ CliStrings.format(CliStrings.EXECUTE_FUNCTION__MSG__GROUPS_0_HAS_NO_MEMBERS,
+ grps.toString().substring(0, grps.toString().length() - 1)));
+ }
+ } else if (onMember != null && onMember.length() > 0) {
+ DistributedMember member = CliUtil.getDistributedMemberByNameOrId(onMember); // fix for bug
+ // 45658
+ if (member != null) {
+ executeAndGetResults(functionId, filterString, resultCollector, arguments, cache, member,
+ resultTable, onRegion);
+ } else {
+ toTabularResultData(resultTable, onMember, CliStrings
+ .format(CliStrings.EXECUTE_FUNCTION__MSG__NO_ASSOCIATED_MEMBER + " " + onMember));
+ }
+ return ResultBuilder.buildResult(resultTable);
+ }
+ } catch (Exception e) {
+ ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+ .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(e.getMessage());
+ return ResultBuilder.buildResult(errorResultData);
+ }
+ return null;
+ }
+
+ private boolean isMoreThanOneTrue(Boolean... values) {
+ return Stream.of(values).mapToInt(BooleanUtils::toInteger).sum() > 1;
+ }
+
+ void executeAndGetResults(String functionId, String filterString, String resultCollector,
+ String[] arguments, InternalCache cache, DistributedMember member,
+ TabularResultData resultTable, String onRegion) {
+ StringBuilder resultMessage = new StringBuilder();
+ try {
+ Function function = new UserFunctionExecution();
+ Object[] args = new Object[5];
+ args[0] = functionId;
+ if (filterString != null) {
+ args[1] = filterString;
+ }
+ if (resultCollector != null) {
+ args[2] = resultCollector;
+ }
+ if (arguments != null && arguments.length > 0) {
+ args[3] = "";
+ for (String str : arguments) {
+ // send via CSV separated value format
+ if (str != null) {
+ args[3] = args[3] + str + ",";
+ }
+ }
+ }
+ args[4] = onRegion;
+
+ Execution execution = FunctionService.onMember(member).setArguments(args);
+ if (execution != null) {
+ List<Object> results = (List<Object>) execution.execute(function).getResult();
+ if (results != null) {
+ for (Object resultObj : results) {
+ if (resultObj != null) {
+ if (resultObj instanceof String) {
+ resultMessage.append(((String) resultObj));
+ } else if (resultObj instanceof Exception) {
+ resultMessage.append(((Exception) resultObj).getMessage());
+ } else {
+ resultMessage.append(resultObj);
+ }
+ }
+ }
+ }
+ toTabularResultData(resultTable, member.getId(), resultMessage.toString());
+ } else {
+ toTabularResultData(resultTable, member.getId(),
+ CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR);
+ }
+ } catch (Exception e) {
+ resultMessage.append(CliStrings.format(
+ CliStrings.EXECUTE_FUNCTION__MSG__COULD_NOT_EXECUTE_FUNCTION_0_ON_MEMBER_1_ERROR_2,
+ functionId, member.getId(), e.getMessage()));
+ toTabularResultData(resultTable, member.getId(), resultMessage.toString());
+ }
+ }
+
+ private void toTabularResultData(TabularResultData table, String memberId, String memberResult) {
+ table.accumulate("Member ID/Name", memberId);
+ table.accumulate("Function Execution Result", memberResult);
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/39fff454/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/FunctionCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/FunctionCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/FunctionCommands.java
deleted file mode 100644
index 21d89c1..0000000
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/FunctionCommands.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * 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.internal.cli.commands;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.stream.Stream;
-
-import org.apache.commons.lang.BooleanUtils;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-
-import org.apache.geode.SystemFailure;
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.execute.Execution;
-import org.apache.geode.cache.execute.Function;
-import org.apache.geode.cache.execute.FunctionException;
-import org.apache.geode.cache.execute.FunctionService;
-import org.apache.geode.cache.execute.ResultCollector;
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.internal.ClassPathLoader;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.DistributedRegionMXBean;
-import org.apache.geode.management.ManagementService;
-import org.apache.geode.management.cli.CliMetaData;
-import org.apache.geode.management.cli.ConverterHint;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.cli.Result.Status;
-import org.apache.geode.management.internal.MBeanJMXAdapter;
-import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
-import org.apache.geode.management.internal.cli.CliUtil;
-import org.apache.geode.management.internal.cli.GfshParseResult;
-import org.apache.geode.management.internal.cli.LogWrapper;
-import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
-import org.apache.geode.management.internal.cli.functions.ListFunctionFunction;
-import org.apache.geode.management.internal.cli.functions.UnregisterFunction;
-import org.apache.geode.management.internal.cli.functions.UserFunctionExecution;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.CompositeResultData;
-import org.apache.geode.management.internal.cli.result.ErrorResultData;
-import org.apache.geode.management.internal.cli.result.ResultBuilder;
-import org.apache.geode.management.internal.cli.result.TabularResultData;
-import org.apache.geode.management.internal.security.ResourceOperation;
-import org.apache.geode.security.ResourcePermission.Operation;
-import org.apache.geode.security.ResourcePermission.Resource;
-import org.apache.geode.security.ResourcePermission.Target;
-
-/**
- * @since GemFire 7.0
- */
-@SuppressWarnings("unused")
-public class FunctionCommands implements GfshCommand {
-
- private final ListFunctionFunction listFunctionFunction = new ListFunctionFunction();
-
- @CliCommand(value = CliStrings.EXECUTE_FUNCTION, help = CliStrings.EXECUTE_FUNCTION__HELP)
- @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION})
- @ResourceOperation(resource = Resource.DATA, operation = Operation.WRITE)
- public Result executeFunction(
- // TODO: Add optioncontext for functionID
- @CliOption(key = CliStrings.EXECUTE_FUNCTION__ID, mandatory = true,
- help = CliStrings.EXECUTE_FUNCTION__ID__HELP) String functionId,
- @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
- optionContext = ConverterHint.MEMBERGROUP,
- help = CliStrings.EXECUTE_FUNCTION__ONGROUPS__HELP) String[] onGroups,
- @CliOption(key = CliStrings.MEMBER, optionContext = ConverterHint.MEMBERIDNAME,
- help = CliStrings.EXECUTE_FUNCTION__ONMEMBER__HELP) String onMember,
- @CliOption(key = CliStrings.EXECUTE_FUNCTION__ONREGION,
- optionContext = ConverterHint.REGION_PATH,
- help = CliStrings.EXECUTE_FUNCTION__ONREGION__HELP) String onRegion,
- @CliOption(key = CliStrings.EXECUTE_FUNCTION__ARGUMENTS,
- help = CliStrings.EXECUTE_FUNCTION__ARGUMENTS__HELP) String[] arguments,
- @CliOption(key = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR,
- help = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR__HELP) String resultCollector,
- @CliOption(key = CliStrings.EXECUTE_FUNCTION__FILTER,
- help = CliStrings.EXECUTE_FUNCTION__FILTER__HELP) String filterString) {
-
- Result result = null;
- CompositeResultData executeFunctionResultTable = ResultBuilder.createCompositeResultData();
- TabularResultData resultTable = executeFunctionResultTable.addSection().addTable("Table1");
- String headerText = "Execution summary";
- resultTable.setHeader(headerText);
- ResultCollector resultCollectorInstance = null;
- Function function;
- Set<String> filters = new HashSet<>();
- Execution execution;
- if (functionId != null) {
- functionId = functionId.trim();
- }
- if (onRegion != null) {
- onRegion = onRegion.trim();
- }
- if (onMember != null) {
- onMember = onMember.trim();
- }
- if (filterString != null) {
- filterString = filterString.trim();
- }
-
- try {
- // validate otherwise return right away. no need to process anything
- if (functionId == null || functionId.length() == 0) {
- ErrorResultData errorResultData =
- ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
- .addLine(CliStrings.EXECUTE_FUNCTION__MSG__MISSING_FUNCTIONID);
- result = ResultBuilder.buildResult(errorResultData);
- return result;
- }
-
- if (isMoreThanOneIsTrue(onRegion != null, onMember != null, onGroups != null)) {
- // Provide Only one of region/member/groups
- ErrorResultData errorResultData =
- ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
- .addLine(CliStrings.EXECUTE_FUNCTION__MSG__OPTIONS);
- result = ResultBuilder.buildResult(errorResultData);
- return result;
- } else if ((onRegion == null || onRegion.length() == 0) && (filterString != null)) {
- ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
- .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
- .addLine(CliStrings.EXECUTE_FUNCTION__MSG__MEMBER_SHOULD_NOT_HAVE_FILTER_FOR_EXECUTION);
- result = ResultBuilder.buildResult(errorResultData);
- return result;
- }
-
- InternalCache cache = getCache();
-
- if (resultCollector != null) {
- resultCollectorInstance =
- (ResultCollector) ClassPathLoader.getLatest().forName(resultCollector).newInstance();
- }
-
- if (filterString != null && filterString.length() > 0) {
- filters.add(filterString);
- }
-
- if (onRegion == null && onMember == null && onGroups == null) {
- // run function on all the members excluding locators bug#46113
- // if user wish to execute on locator then he can choose --member or --group option
- Set<DistributedMember> dsMembers = CliUtil.getAllNormalMembers(cache);
- if (dsMembers.size() > 0) {
- function = new UserFunctionExecution();
- LogWrapper.getInstance().info(CliStrings
- .format(CliStrings.EXECUTE_FUNCTION__MSG__EXECUTING_0_ON_ENTIRE_DS, functionId));
- for (DistributedMember member : dsMembers) {
- executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
- member, resultTable, onRegion);
- }
- return ResultBuilder.buildResult(resultTable);
- } else {
- return ResultBuilder
- .createUserErrorResult(CliStrings.EXECUTE_FUNCTION__MSG__DS_HAS_NO_MEMBERS);
- }
- } else if (onRegion != null && onRegion.length() > 0) {
- if (cache.getRegion(onRegion) == null) {
- // find a member where region is present
- DistributedRegionMXBean bean = ManagementService.getManagementService(getCache())
- .getDistributedRegionMXBean(onRegion);
- if (bean == null) {
- bean = ManagementService.getManagementService(getCache())
- .getDistributedRegionMXBean(Region.SEPARATOR + onRegion);
-
- if (bean == null) {
- return ResultBuilder.createGemFireErrorResult(CliStrings
- .format(CliStrings.EXECUTE_FUNCTION__MSG__MXBEAN_0_FOR_NOT_FOUND, onRegion));
- }
- }
-
- DistributedMember member = null;
- String[] membersName = bean.getMembers();
- Set<DistributedMember> dsMembers = CliUtil.getAllMembers(cache);
- Iterator it = dsMembers.iterator();
- boolean matchFound = false;
-
- if (membersName.length > 0) {
- while (it.hasNext() && !matchFound) {
- DistributedMember dsmember = (DistributedMember) it.next();
- for (String memberName : membersName) {
- if (MBeanJMXAdapter.getMemberNameOrId(dsmember).equals(memberName)) {
- member = dsmember;
- matchFound = true;
- break;
- }
- }
- }
- }
- if (matchFound) {
- executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
- member, resultTable, onRegion);
- return ResultBuilder.buildResult(resultTable);
- } else {
- return ResultBuilder.createGemFireErrorResult(CliStrings.format(
- CliStrings.EXECUTE_FUNCTION__MSG__NO_ASSOCIATED_MEMBER_REGION, " " + onRegion));
- }
- } else {
- execution = FunctionService.onRegion(cache.getRegion(onRegion));
- if (execution != null) {
- if (resultCollectorInstance != null) {
- execution = execution.withCollector(resultCollectorInstance);
- }
- if (filters != null && filters.size() > 0) {
- execution = execution.withFilter(filters);
- }
- if (arguments != null && arguments.length > 0) {
- execution = execution.setArguments(arguments);
- }
-
- try {
- List<Object> results = (List<Object>) execution.execute(functionId).getResult();
- if (results.size() > 0) {
- StringBuilder strResult = new StringBuilder();
- for (Object obj : results) {
- strResult.append(obj);
- }
- toTabularResultData(resultTable,
- cache.getDistributedSystem().getDistributedMember().getId(),
- strResult.toString());
- }
- return ResultBuilder.buildResult(resultTable);
- } catch (FunctionException e) {
- return ResultBuilder.createGemFireErrorResult(CliStrings.format(
- CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_REGION_1_DETAILS_2,
- functionId, onRegion, e.getMessage()));
- }
- } else {
- return ResultBuilder.createGemFireErrorResult(CliStrings.format(
- CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_REGION_1_DETAILS_2,
- functionId, onRegion,
- CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR));
- }
- }
- } else if (onGroups != null) {
- // execute on group members
- Set<DistributedMember> dsMembers = new HashSet<>();
- for (String grp : onGroups) {
- dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(grp));
- }
-
- StringBuilder successMessage = new StringBuilder();
- if (dsMembers.size() > 0) {
- for (DistributedMember member : dsMembers) {
- executeAndGetResults(functionId, filterString, resultCollector, arguments, cache,
- member, resultTable, onRegion);
- }
- return ResultBuilder.buildResult(resultTable);
- } else {
- StringBuilder grps = new StringBuilder();
- for (String grp : onGroups) {
- grps.append(grp);
- grps.append(", ");
- }
- return ResultBuilder.createUserErrorResult(
- CliStrings.format(CliStrings.EXECUTE_FUNCTION__MSG__GROUPS_0_HAS_NO_MEMBERS,
- grps.toString().substring(0, grps.toString().length() - 1)));
- }
- } else if (onMember != null && onMember.length() > 0) {
- DistributedMember member = CliUtil.getDistributedMemberByNameOrId(onMember); // fix for bug
- // 45658
- if (member != null) {
- executeAndGetResults(functionId, filterString, resultCollector, arguments, cache, member,
- resultTable, onRegion);
- } else {
- toTabularResultData(resultTable, onMember, CliStrings
- .format(CliStrings.EXECUTE_FUNCTION__MSG__NO_ASSOCIATED_MEMBER + " " + onMember));
- }
- return ResultBuilder.buildResult(resultTable);
- }
- } catch (Exception e) {
- ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
- .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(e.getMessage());
- result = ResultBuilder.buildResult(errorResultData);
- return result;
- }
-
- return result;
- }
-
- private boolean isMoreThanOneIsTrue(Boolean... values) {
- return Stream.of(values).mapToInt(BooleanUtils::toInteger).sum() > 1;
- }
-
- void executeAndGetResults(String functionId, String filterString, String resultCollector,
- String[] arguments, InternalCache cache, DistributedMember member,
- TabularResultData resultTable, String onRegion) {
- StringBuilder resultMessage = new StringBuilder();
- try {
- Function function = new UserFunctionExecution();
- Object[] args = new Object[5];
- args[0] = functionId;
- if (filterString != null) {
- args[1] = filterString;
- }
- if (resultCollector != null) {
- args[2] = resultCollector;
- }
- if (arguments != null && arguments.length > 0) {
- args[3] = "";
- for (String str : arguments) {
- // send via CSV separated value format
- if (str != null) {
- args[3] = args[3] + str + ",";
- }
- }
- }
- args[4] = onRegion;
-
- Execution execution = FunctionService.onMember(member).setArguments(args);
- if (execution != null) {
- List<Object> results = (List<Object>) execution.execute(function).getResult();
- if (results != null) {
- for (Object resultObj : results) {
- if (resultObj != null) {
- if (resultObj instanceof String) {
- resultMessage.append(((String) resultObj));
- } else if (resultObj instanceof Exception) {
- resultMessage.append(((Exception) resultObj).getMessage());
- } else {
- resultMessage.append(resultObj);
- }
- }
- }
- }
- toTabularResultData(resultTable, member.getId(), resultMessage.toString());
- } else {
- toTabularResultData(resultTable, member.getId(),
- CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR);
- }
- } catch (Exception e) {
- resultMessage.append(CliStrings.format(
- CliStrings.EXECUTE_FUNCTION__MSG__COULD_NOT_EXECUTE_FUNCTION_0_ON_MEMBER_1_ERROR_2,
- functionId, member.getId(), e.getMessage()));
- toTabularResultData(resultTable, member.getId(), resultMessage.toString());
- }
- }
-
- protected void toTabularResultData(TabularResultData table, String memberId,
- String memberResult) {
- String newLine = System.getProperty("line.separator");
- table.accumulate("Member ID/Name", memberId);
- table.accumulate("Function Execution Result", memberResult);
- }
-
- @CliCommand(value = CliStrings.DESTROY_FUNCTION, help = CliStrings.DESTROY_FUNCTION__HELP)
- @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION},
- interceptor = "org.apache.geode.management.internal.cli.commands.FunctionCommands$Interceptor")
- @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.MANAGE, target = Target.JAR)
- // TODO: Add optioncontext for functionId
- public Result destroyFunction(
- @CliOption(key = CliStrings.DESTROY_FUNCTION__ID, mandatory = true,
- help = CliStrings.DESTROY_FUNCTION__HELP) String functionId,
- @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
- optionContext = ConverterHint.MEMBERGROUP,
- help = CliStrings.DESTROY_FUNCTION__ONGROUPS__HELP) String[] groups,
- @CliOption(key = CliStrings.MEMBER, optionContext = ConverterHint.MEMBERIDNAME,
- help = CliStrings.DESTROY_FUNCTION__ONMEMBER__HELP) String memberId) {
- Result result;
- try {
- InternalCache cache = getCache();
- Set<DistributedMember> dsMembers = new HashSet<>();
- if (groups != null && memberId != null) {
- return ResultBuilder
- .createUserErrorResult(CliStrings.DESTROY_FUNCTION__MSG__PROVIDE_OPTION);
- } else if (groups != null && groups.length > 0) {
- // execute on group members
- for (String grp : groups) {
- dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(grp));
- }
- @SuppressWarnings("unchecked")
- Result results = executeFunction(cache, dsMembers, functionId);
- return results;
- } else if (memberId != null) {
- // execute on member
- dsMembers.add(getMember(cache, memberId));
- @SuppressWarnings("unchecked")
- Result results = executeFunction(cache, dsMembers, functionId);
- return results;
- } else {
- // no option provided.
- @SuppressWarnings("unchecked")
- Result results = executeFunction(cache, cache.getMembers(), functionId);
- return results;
- }
- } catch (Exception e) {
- ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
- .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(e.getMessage());
- result = ResultBuilder.buildResult(errorResultData);
- return result;
- }
- }
-
- /**
- * Interceptor used by gfsh to intercept execution of destroy.
- */
- public static class Interceptor extends AbstractCliAroundInterceptor {
- @Override
- public Result preExecution(GfshParseResult parseResult) {
- Map<String, String> paramValueMap = parseResult.getParamValueStrings();
- Set<Entry<String, String>> setEnvMap = paramValueMap.entrySet();
- String onGroup = paramValueMap.get(CliStrings.GROUP);
- String onMember = paramValueMap.get(CliStrings.MEMBER);
-
- if ((onGroup == null && onMember == null)) {
- Response response = readYesNo("Do you really want to destroy "
- + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID) + " on entire DS?", Response.NO);
- if (response == Response.NO) {
- return ResultBuilder.createShellClientAbortOperationResult(
- "Aborted destroy of " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
- } else {
- return ResultBuilder
- .createInfoResult("Destroying " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
- }
- } else {
- return ResultBuilder
- .createInfoResult("Destroying " + paramValueMap.get(CliStrings.DESTROY_FUNCTION__ID));
- }
- }
- }
-
- Result executeFunction(InternalCache cache, Set<DistributedMember> DsMembers, String functionId) {
- // unregister on a set of of members
- Function unregisterFunction = new UnregisterFunction();
- FunctionService.registerFunction(unregisterFunction);
- List resultList;
-
- if (DsMembers.isEmpty()) {
- return ResultBuilder.createInfoResult("No members for execution");
- }
- Object[] obj = new Object[1];
- obj[0] = functionId;
-
- Execution execution = FunctionService.onMembers(DsMembers).setArguments(obj);
-
- if (execution == null) {
- cache.getLogger().error("executeUnregister execution is null");
- ErrorResultData errorResultData =
- ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
- .addLine(CliStrings.DESTROY_FUNCTION__MSG__CANNOT_EXECUTE);
- return (ResultBuilder.buildResult(errorResultData));
- }
- try {
- resultList = (ArrayList) execution.execute(unregisterFunction).getResult();
- } catch (FunctionException ex) {
- ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
- .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(ex.getMessage());
- return (ResultBuilder.buildResult(errorResultData));
- }
- String resultStr = ((String) resultList.get(0));
- if (resultStr.equals("Succeeded in unregistering")) {
- StringBuilder members = new StringBuilder();
- for (DistributedMember member : DsMembers) {
- members.append(member.getId());
- members.append(",");
- }
- return ResultBuilder.createInfoResult("Destroyed " + functionId + " Successfully on "
- + members.toString().substring(0, members.toString().length() - 1));
- } else {
- return ResultBuilder.createInfoResult("Failed in unregistering");
- }
- }
-
- @CliCommand(value = CliStrings.LIST_FUNCTION, help = CliStrings.LIST_FUNCTION__HELP)
- @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION})
- @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
- public Result listFunction(
- @CliOption(key = CliStrings.LIST_FUNCTION__MATCHES,
- help = CliStrings.LIST_FUNCTION__MATCHES__HELP) String matches,
- @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
- optionContext = ConverterHint.MEMBERGROUP,
- help = CliStrings.LIST_FUNCTION__GROUP__HELP) String[] groups,
- @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
- optionContext = ConverterHint.MEMBERIDNAME,
- help = CliStrings.LIST_FUNCTION__MEMBER__HELP) String[] members) {
- TabularResultData tabularData = ResultBuilder.createTabularResultData();
- boolean accumulatedData = false;
-
- InternalCache cache = getCache();
-
- Set<DistributedMember> targetMembers = CliUtil.findMembers(groups, members);
-
- if (targetMembers.isEmpty()) {
- return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
- }
-
- try {
- ResultCollector<?, ?> rc =
- CliUtil.executeFunction(this.listFunctionFunction, new Object[] {matches}, targetMembers);
- List<CliFunctionResult> results = CliFunctionResult.cleanResults((List<?>) rc.getResult());
-
- for (CliFunctionResult result : results) {
- if (result.getThrowable() != null) {
- tabularData.accumulate("Member", result.getMemberIdOrName());
- tabularData.accumulate("Function", "<ERROR: " + result.getThrowable().getMessage() + ">");
- accumulatedData = true;
- tabularData.setStatus(Status.ERROR);
- } else if (result.isSuccessful()) {
- String[] strings = (String[]) result.getSerializables();
- Arrays.sort(strings);
- for (String string : strings) {
- tabularData.accumulate("Member", result.getMemberIdOrName());
- tabularData.accumulate("Function", string);
- accumulatedData = true;
- }
- }
- }
-
- if (!accumulatedData) {
- return ResultBuilder
- .createInfoResult(CliStrings.LIST_FUNCTION__NO_FUNCTIONS_FOUND_ERROR_MESSAGE);
- }
- return ResultBuilder.buildResult(tabularData);
- } catch (VirtualMachineError e) {
- SystemFailure.initiateFailure(e);
- throw e;
- } catch (Throwable th) {
- SystemFailure.checkFailure();
- return ResultBuilder.createGemFireErrorResult(
- "Exception while attempting to list functions: " + th.getMessage());
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/geode/blob/39fff454/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListFunctionCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListFunctionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListFunctionCommand.java
new file mode 100644
index 0000000..c7fe51b
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListFunctionCommand.java
@@ -0,0 +1,103 @@
+/*
+ * 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.internal.cli.commands;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.SystemFailure;
+import org.apache.geode.cache.execute.ResultCollector;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.management.cli.CliMetaData;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.CliUtil;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
+import org.apache.geode.management.internal.cli.functions.ListFunctionFunction;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.result.TabularResultData;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission;
+
+public class ListFunctionCommand implements GfshCommand {
+ private final ListFunctionFunction listFunctionFunction = new ListFunctionFunction();
+
+ @CliCommand(value = CliStrings.LIST_FUNCTION, help = CliStrings.LIST_FUNCTION__HELP)
+ @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_FUNCTION})
+ @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
+ operation = ResourcePermission.Operation.READ)
+ public Result listFunction(
+ @CliOption(key = CliStrings.LIST_FUNCTION__MATCHES,
+ help = CliStrings.LIST_FUNCTION__MATCHES__HELP) String matches,
+ @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+ optionContext = ConverterHint.MEMBERGROUP,
+ help = CliStrings.LIST_FUNCTION__GROUP__HELP) String[] groups,
+ @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
+ optionContext = ConverterHint.MEMBERIDNAME,
+ help = CliStrings.LIST_FUNCTION__MEMBER__HELP) String[] members) {
+ TabularResultData tabularData = ResultBuilder.createTabularResultData();
+ boolean accumulatedData = false;
+
+ getCache(); // TODO PSR: Can this safely be removed?
+
+ Set<DistributedMember> targetMembers = CliUtil.findMembers(groups, members);
+
+ if (targetMembers.isEmpty()) {
+ return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+ }
+
+ try {
+ ResultCollector<?, ?> rc =
+ CliUtil.executeFunction(this.listFunctionFunction, new Object[] {matches}, targetMembers);
+ List<CliFunctionResult> results = CliFunctionResult.cleanResults((List<?>) rc.getResult());
+
+ for (CliFunctionResult result : results) {
+ if (result.getThrowable() != null) {
+ tabularData.accumulate("Member", result.getMemberIdOrName());
+ tabularData.accumulate("Function", "<ERROR: " + result.getThrowable().getMessage() + ">");
+ accumulatedData = true;
+ tabularData.setStatus(Result.Status.ERROR);
+ } else if (result.isSuccessful()) {
+ String[] strings = (String[]) result.getSerializables();
+ Arrays.sort(strings);
+ for (String string : strings) {
+ tabularData.accumulate("Member", result.getMemberIdOrName());
+ tabularData.accumulate("Function", string);
+ accumulatedData = true;
+ }
+ }
+ }
+
+ if (!accumulatedData) {
+ return ResultBuilder
+ .createInfoResult(CliStrings.LIST_FUNCTION__NO_FUNCTIONS_FOUND_ERROR_MESSAGE);
+ }
+ return ResultBuilder.buildResult(tabularData);
+ } catch (VirtualMachineError e) {
+ SystemFailure.initiateFailure(e);
+ throw e;
+ } catch (Throwable th) {
+ SystemFailure.checkFailure();
+ return ResultBuilder.createGemFireErrorResult(
+ "Exception while attempting to list functions: " + th.getMessage());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/39fff454/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/FunctionCommandsController.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/FunctionCommandsController.java b/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/FunctionCommandsController.java
index 855947e..da3fc65 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/FunctionCommandsController.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/FunctionCommandsController.java
@@ -14,9 +14,8 @@
*/
package org.apache.geode.management.internal.web.controllers;
-import org.apache.geode.internal.lang.StringUtils;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
+import java.util.concurrent.Callable;
+
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
@@ -25,14 +24,18 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
-import java.util.concurrent.Callable;
+import org.apache.geode.internal.lang.StringUtils;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
/**
* The FunctionCommandsController class implements GemFire Management REST API web service endpoints
* for the Gfsh Function Commands.
* <p/>
*
- * @see org.apache.geode.management.internal.cli.commands.FunctionCommands
+ * @see org.apache.geode.management.internal.cli.commands.DestroyFunctionCommand
+ * @see org.apache.geode.management.internal.cli.commands.ExecuteFunctionCommand
+ * @see org.apache.geode.management.internal.cli.commands.ListFunctionCommand
* @see org.apache.geode.management.internal.web.controllers.AbstractCommandsController
* @see org.springframework.stereotype.Controller
* @see org.springframework.web.bind.annotation.PathVariable
http://git-wip-us.apache.org/repos/asf/geode/blob/39fff454/geode-core/src/test/java/org/apache/geode/management/internal/security/TestCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/security/TestCommand.java b/geode-core/src/test/java/org/apache/geode/management/internal/security/TestCommand.java
index b19cfd0..e0d13b6 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/security/TestCommand.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/security/TestCommand.java
@@ -184,8 +184,8 @@ public class TestCommand {
clusterRead);
createTestCommand("import cluster-configuration --zip-file-name=value.zip", clusterManage);
- // FunctionCommands
- // createTestCommand("destroy function --id=InterestCalculations", dataManage);
+ // DestroyFunctionCommand, ExecuteFunctionCommand, ListFunctionCommand
+ createTestCommand("destroy function --id=InterestCalculations", dataManage);
createTestCommand("execute function --id=InterestCalculations --groups=Group1", dataWrite);
createTestCommand("list functions", clusterRead);