You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2016/02/25 21:27:26 UTC

[38/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/DurableClientCommands.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DurableClientCommands.java
index 0000000,b844e85..e6de2ec
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DurableClientCommands.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DurableClientCommands.java
@@@ -1,0 -1,430 +1,437 @@@
+ /*
+  * 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.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.LinkedList;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.TreeMap;
+ import java.util.TreeSet;
+ 
+ import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+ import org.springframework.shell.core.annotation.CliCommand;
+ import org.springframework.shell.core.annotation.CliOption;
+ 
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.cache.execute.ResultCollector;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.internal.lang.StringUtils;
+ import com.gemstone.gemfire.management.cli.Result;
+ import com.gemstone.gemfire.management.internal.cli.CliUtil;
+ import com.gemstone.gemfire.management.cli.CliMetaData;
+ import com.gemstone.gemfire.management.cli.ConverterHint;
+ import com.gemstone.gemfire.management.internal.cli.domain.DurableCqNamesResult;
+ import com.gemstone.gemfire.management.internal.cli.domain.IndexDetails.IndexStatisticsDetails;
+ import com.gemstone.gemfire.management.internal.cli.domain.MemberResult;
+ import com.gemstone.gemfire.management.internal.cli.domain.SubscriptionQueueSizeResult;
+ import com.gemstone.gemfire.management.internal.cli.functions.CloseDurableClientFunction;
+ import com.gemstone.gemfire.management.internal.cli.functions.CloseDurableCqFunction;
+ import com.gemstone.gemfire.management.internal.cli.functions.GetSubscriptionQueueSizeFunction;
+ import com.gemstone.gemfire.management.internal.cli.functions.ListDurableCqNamesFunction;
+ import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
+ import com.gemstone.gemfire.management.internal.cli.result.CommandResultException;
+ import com.gemstone.gemfire.management.internal.cli.result.CompositeResultData;
+ import com.gemstone.gemfire.management.internal.cli.result.ErrorResultData;
+ 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.result.ResultData;
+ import com.gemstone.gemfire.management.internal.cli.result.TabularResultData;
++import com.gemstone.gemfire.management.internal.security.Resource;
++import com.gemstone.gemfire.management.internal.security.ResourceConstants;
++import com.gemstone.gemfire.management.internal.security.ResourceOperation;
+ 
+ /**
+  * The DurableClientCommands class encapsulates all GemFire shell (Gfsh) commands related to 
+  * durable clients and cqs defined in GemFire.
+  * </p>
+  * @author jhuynh
+  * @author bansods
+  */
+ @SuppressWarnings("unused")
+ public class DurableClientCommands extends AbstractCommandsSupport {
+ 
+ 	private static final ListDurableCqNamesFunction listDurableCqNamesFunction = new ListDurableCqNamesFunction();
+ 	private static final CloseDurableClientFunction closeDurableClientFunction = new CloseDurableClientFunction();
+ 	private static final CloseDurableCqFunction closeDurableCqFunction = new CloseDurableCqFunction();
+ 	private static final GetSubscriptionQueueSizeFunction countDurableCqEvents = new GetSubscriptionQueueSizeFunction();
+ 
+ 	@CliCommand(value = CliStrings.LIST_DURABLE_CQS, help = CliStrings.LIST_DURABLE_CQS__HELP)
+ 	@CliMetaData(shellOnly = false)
++	@ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+ 	public Result listDurableClientCqs(
+ 	@CliOption (key = CliStrings.LIST_DURABLE_CQS__DURABLECLIENTID,
+ 	mandatory=true,
+ 	help = CliStrings.LIST_DURABLE_CQS__DURABLECLIENTID__HELP
+ 	) final String durableClientId,
+ 	
+ 	@CliOption (key = CliStrings.LIST_DURABLE_CQS__MEMBER,
+ 	help = CliStrings.LIST_DURABLE_CQS__MEMBER__HELP,
+ 	optionContext=ConverterHint.MEMBERIDNAME
+ 	) final String memberNameOrId,
+ 	
+ 	@CliOption (key = CliStrings.LIST_DURABLE_CQS__GROUP,
+ 	help = CliStrings.LIST_DURABLE_CQS__GROUP__HELP,
+ 	optionContext=ConverterHint.MEMBERGROUP
+ 	) final String group) {
+ 	  Result result = null;
+ 	  try {
+ 
+ 	    boolean noResults = true;
+ 	    Set<DistributedMember> targetMembers;
+ 	    try {
+ 	      targetMembers = CliUtil.findAllMatchingMembers(group, memberNameOrId);
+ 	    } catch (CommandResultException e) {
+ 	      return e.getResult();
+ 	    }
+ 	    final ResultCollector<?,?> rc = CliUtil.executeFunction(new ListDurableCqNamesFunction(), durableClientId, targetMembers);
+ 	    final List<DurableCqNamesResult> results = (List<DurableCqNamesResult>) rc.getResult();
+ 	    Map<String, List<String>> memberCqNamesMap = new TreeMap<String, List<String>>();
+ 	    Map<String, List<String>> errorMessageNodes = new HashMap<String, List<String>>();
+ 	    Map<String, List<String>> exceptionMessageNodes = new HashMap<String, List<String>>();
+ 
+ 	    for (DurableCqNamesResult memberResult : results) {
+ 	      if (memberResult != null) {
+ 	        if (memberResult.isSuccessful()) {
+ 	          memberCqNamesMap.put(memberResult.getMemberNameOrId(), memberResult.getCqNamesList());
+ 	        } else {
+ 	          if (memberResult.isOpPossible()) {
+ 	            groupByMessage(memberResult.getExceptionMessage(), memberResult.getMemberNameOrId(), exceptionMessageNodes);
+ 	          } else {
+ 	            groupByMessage(memberResult.getErrorMessage(), memberResult.getMemberNameOrId(), errorMessageNodes);
+ 	          }
+ 	        }
+ 	      }
+ 	    }
+ 
+ 	    if (!memberCqNamesMap.isEmpty()) {
+ 	      TabularResultData table = ResultBuilder.createTabularResultData();
+ 	      Set<String> members = memberCqNamesMap.keySet();
+ 
+ 	      for (String member : members) {
+ 	        boolean isFirst = true;
+ 	        List<String> cqNames = memberCqNamesMap.get(member);
+ 	        for (String cqName : cqNames) {
+ 	          if (isFirst) {
+ 	            isFirst = false;
+ 	            table.accumulate(CliStrings.LIST_DURABLE_CQS__MEMBER, member);
+ 	          } else {
+ 	            table.accumulate(CliStrings.LIST_DURABLE_CQS__MEMBER, "");
+ 	          }
+ 	          table.accumulate(CliStrings.LIST_DURABLE_CQS__NAME, cqName);
+ 	        }
+ 	      }
+ 	      result = ResultBuilder.buildResult(table);
+ 	    } else {
+ 	      String errorHeader = CliStrings.format(CliStrings.LIST_DURABLE_CQS__FAILURE__HEADER, durableClientId);
+ 	      result = ResultBuilder.buildResult(buildFailureData(null, exceptionMessageNodes, errorMessageNodes, errorHeader));
+ 	    }
+ 	  } catch (Exception e) {
+ 	    result = ResultBuilder.createGemFireErrorResult(e.getMessage());
+ 	  }
+ 
+ 	  return result;
+ 	}
+ 
+ 	@CliCommand(value = CliStrings.COUNT_DURABLE_CQ_EVENTS, help = CliStrings.COUNT_DURABLE_CQ_EVENTS__HELP)
+ 	@CliMetaData(shellOnly = false)
++	@ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+ 	public Result countDurableCqEvents(
+ 	@CliOption (key = CliStrings.COUNT_DURABLE_CQ_EVENTS__DURABLE__CLIENT__ID,
+ 	mandatory=true,
+ 	help = CliStrings.COUNT_DURABLE_CQ_EVENTS__DURABLE__CLIENT__ID__HELP
+ 	) final String durableClientId,
+ 	@CliOption (key = CliStrings.COUNT_DURABLE_CQ_EVENTS__DURABLE__CQ__NAME,
+ 	mandatory = false,
+ 	help = CliStrings.COUNT_DURABLE_CQ_EVENTS__DURABLE__CQ__NAME__HELP
+ 	) final String cqName,
+ 	@CliOption (key = CliStrings.COUNT_DURABLE_CQ_EVENTS__MEMBER,
+ 	mandatory=false,
+ 	help = CliStrings.COUNT_DURABLE_CQ_EVENTS__MEMBER__HELP,
+ 	optionContext = ConverterHint.MEMBERIDNAME
+ 	) final String memberNameOrId,
+ 	@CliOption (key = CliStrings.COUNT_DURABLE_CQ_EVENTS__GROUP,
+ 	mandatory=false,
+ 	help = CliStrings.COUNT_DURABLE_CQ_EVENTS__GROUP__HELP,
+ 	optionContext = ConverterHint.MEMBERGROUP
+ 	) final String group) {
+ 		
+ 	  Result result = null;
+ 	  try {
+ 	    Set<DistributedMember> targetMembers;
+ 	    try {
+ 	      targetMembers = CliUtil.findAllMatchingMembers(group, memberNameOrId);
+ 	    } catch (CommandResultException e) {
+ 	      return e.getResult();
+ 	    }
+ 	    String [] params =  new String[2];
+ 	    params[0] = durableClientId;
+ 	    params[1] = cqName;
+ 	    final ResultCollector<?,?> rc = CliUtil.executeFunction(new GetSubscriptionQueueSizeFunction(), params, targetMembers);
+ 	    final List<SubscriptionQueueSizeResult> funcResults = (List<SubscriptionQueueSizeResult>) rc.getResult();
+ 	    
+ 	    String queueSizeColumnName;
+ 	   
+ 	    if (cqName != null && !cqName.isEmpty()) {
+ 	      queueSizeColumnName = CliStrings.format(CliStrings.COUNT_DURABLE_CQ_EVENTS__SUBSCRIPTION__QUEUE__SIZE__CLIENT, cqName);
+ 	    } else {
+ 	      queueSizeColumnName = CliStrings.format(CliStrings.COUNT_DURABLE_CQ_EVENTS__SUBSCRIPTION__QUEUE__SIZE__CLIENT, durableClientId);
+ 	    }
+ 	    result = buildTableResultForQueueSize(funcResults, queueSizeColumnName);
+ 	  } catch (Exception e) {
+ 	    result = ResultBuilder.createGemFireErrorResult(e.getMessage());
+ 	  }
+ 
+ 	  return result;	
+ 	}
+ 
+ 	@CliCommand(value = CliStrings.CLOSE_DURABLE_CLIENTS, help = CliStrings.CLOSE_DURABLE_CLIENTS__HELP)
+ 	@CliMetaData(shellOnly = false)
++	@ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.CLOSE_DURABLE_CLIENT)
+ 	public Result closeDurableClient(
+ 	@CliOption (key = CliStrings.CLOSE_DURABLE_CLIENTS__CLIENT__ID,
+ 				mandatory=true,
+ 				help = CliStrings.CLOSE_DURABLE_CLIENTS__CLIENT__ID__HELP
+ 	) final String durableClientId,
+ 	@CliOption (key = CliStrings.CLOSE_DURABLE_CLIENTS__MEMBER,
+ 				mandatory=false,
+ 				help = CliStrings.CLOSE_DURABLE_CLIENTS__MEMBER__HELP,
+ 				optionContext = ConverterHint.MEMBERIDNAME
+ 	) final String memberNameOrId,
+ 	@CliOption (key = CliStrings.CLOSE_DURABLE_CLIENTS__GROUP,
+ 			    mandatory=false,
+ 			    help = CliStrings.COUNT_DURABLE_CQ_EVENTS__GROUP__HELP,
+ 			    optionContext = ConverterHint.MEMBERGROUP
+ 	) final String group) {
+ 	 
+ 	  Result result = null;
+ 	  try {
+ 	    Set<DistributedMember> targetMembers;
+ 	    try {
+ 	      targetMembers = CliUtil.findAllMatchingMembers(group, memberNameOrId);
+ 	    } catch (CommandResultException e) {
+ 	      return e.getResult();
+ 	    }
+ 	    final ResultCollector<?,?> rc = CliUtil.executeFunction(new CloseDurableClientFunction(), durableClientId, targetMembers);
+ 	    final List<MemberResult> results = (List<MemberResult>) rc.getResult();
+ 	    String failureHeader = CliStrings.format(CliStrings.CLOSE_DURABLE_CLIENTS__FAILURE__HEADER, durableClientId);
+ 	    String successHeader = CliStrings.format(CliStrings.CLOSE_DURABLE_CLIENTS__SUCCESS, durableClientId);
+ 	    result = buildResult(results, successHeader, failureHeader);
+ 	  } catch (Exception e) {
+ 	    result = ResultBuilder.createGemFireErrorResult(e.getMessage());
+ 	  }
+ 	  return result;
+ 	}
+ 
+ 	
+ 	@CliCommand(value = CliStrings.CLOSE_DURABLE_CQS, help = CliStrings.CLOSE_DURABLE_CQS__HELP)
+ 	@CliMetaData(shellOnly = false)
++	@ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.CLOSE_DURABLE_CQ)
+ 	public Result closeDurableCqs(
+ 	@CliOption (key = CliStrings.CLOSE_DURABLE_CQS__DURABLE__CLIENT__ID,
+ 	mandatory=true,
+ 	help = CliStrings.CLOSE_DURABLE_CQS__DURABLE__CLIENT__ID__HELP
+ 	) final String durableClientId,
+ 			
+ 	@CliOption(key = CliStrings.CLOSE_DURABLE_CQS__NAME,
+ 	mandatory = true,
+ 	help = CliStrings.CLOSE_DURABLE_CQS__NAME__HELP)
+ 	final String cqName,
+ 	
+ 	@CliOption (key = CliStrings.CLOSE_DURABLE_CQS__MEMBER,
+ 	mandatory=false,
+ 	help = CliStrings.CLOSE_DURABLE_CQS__MEMBER__HELP,
+ 	optionContext = ConverterHint.MEMBERIDNAME
+ 	) final String memberNameOrId,
+ 	
+ 	@CliOption (key = CliStrings.CLOSE_DURABLE_CQS__GROUP,
+ 	mandatory=false,
+ 	help = CliStrings.CLOSE_DURABLE_CQS__GROUP__HELP,
+ 	optionContext = ConverterHint.MEMBERGROUP
+ 	) final String group) {
+ 	  Result result = null;
+ 	  try{
+ 	    Set<DistributedMember> targetMembers;
+ 	    try {
+ 	      targetMembers = CliUtil.findAllMatchingMembers(group, memberNameOrId);
+ 	    } catch (CommandResultException e) {
+ 	      return e.getResult();
+ 	    }
+ 
+ 	    String [] params =  new String[2];
+ 	    params[0] = durableClientId;
+ 	    params[1] = cqName;
+ 
+ 	    final ResultCollector<?,?> rc = CliUtil.executeFunction(new CloseDurableCqFunction(), params, targetMembers);
+ 	    final List<MemberResult> results = (List<MemberResult>) rc.getResult();
+ 	    String failureHeader = CliStrings.format(CliStrings.CLOSE_DURABLE_CQS__FAILURE__HEADER, cqName, durableClientId);
+ 	    String successHeader = CliStrings.format(CliStrings.CLOSE_DURABLE_CQS__SUCCESS, cqName, durableClientId);
+ 	    result = buildResult(results, successHeader, failureHeader);
+ 	  } catch (Exception e) {
+ 	    result = ResultBuilder.createGemFireErrorResult(e.getMessage());
+ 	  }
+ 	  return result;
+ 	}
+ 
+ 	
+ 	private Result buildResult (List<MemberResult> results, String successHeader, String failureHeader) {
+ 	  Result result = null;
+ 	  boolean failure = true;
+ 	  boolean partialFailure = false;
+ 	  Map<String, List<String>> errorMap = new HashMap<String, List<String>>();
+ 	  Map<String, List<String>> successMap = new HashMap<String, List<String>>();
+ 	  Map<String, List<String>> exceptionMap = new HashMap<String, List<String>>();
+ 
+ 	  /***
+ 	   * Aggregate the results  from the members
+ 	   */
+ 	  for (MemberResult memberResult : results) {
+ 
+ 	    if (memberResult.isSuccessful()) {
+ 	      failure = false;
+ 	      groupByMessage(memberResult.getSuccessMessage(), memberResult.getMemberNameOrId(), successMap);
+ 	    } else {
+ 
+ 	      if (memberResult.isOpPossible()) {
+ 	        partialFailure = true;
+ 	        groupByMessage(memberResult.getExceptionMessage(), memberResult.getMemberNameOrId(), exceptionMap);
+ 
+ 	      }else {
+ 	        groupByMessage(memberResult.getErrorMessage(), memberResult.getMemberNameOrId(), errorMap);
+ 	      }
+ 	    }
+ 	  }
+ 
+ 	  if  (!failure && !partialFailure) {
+ 	    result = ResultBuilder.buildResult(buildSuccessData(successMap));
+ 	  } else {
+ 	    result = ResultBuilder.buildResult(buildFailureData(successMap, exceptionMap, errorMap, failureHeader));
+ 	  }
+ 	  return result ;
+ 	}
+ 
+ 	private Result buildTableResultForQueueSize (List<SubscriptionQueueSizeResult> results, String queueSizeColumnName) {
+ 	  Result result = null;
+ 	  boolean failure = true;
+ 
+ 	  Map<String, List<String>> failureMap = new HashMap<String, List<String>>();
+ 	  Map<String, Long> memberQueueSizeTable = new TreeMap<String, Long>();
+ 
+ 	  /***
+ 	   * Aggregate the results  from the members
+ 	   */
+ 	  for (SubscriptionQueueSizeResult memberResult : results) {
+ 
+ 	    if (memberResult.isSuccessful()) {
+ 	      failure = false;
+ 	      memberResult.getSubscriptionQueueSize();
+ 	      memberQueueSizeTable.put(memberResult.getMemberNameOrId(), memberResult.getSubscriptionQueueSize());
+ 	    } else {
+ 	      groupByMessage(memberResult.getErrorMessage(), memberResult.getMemberNameOrId(), failureMap);
+ 	    }
+ 	  }
+ 
+ 	  if (!failure) {
+ 	    TabularResultData table = ResultBuilder.createTabularResultData();
+ 
+ 	    Set<String> members = memberQueueSizeTable.keySet();
+ 
+ 	    for (String member : members) {
+ 	      long queueSize = memberQueueSizeTable.get(member);
+ 	      table.accumulate(CliStrings.COUNT_DURABLE_CQ_EVENTS__MEMBER, member);
+ 	      table.accumulate(queueSizeColumnName, queueSize);
+ 	    }
+ 	    result = ResultBuilder.buildResult(table);
+ 
+ 	  } else{
+ 	    ErrorResultData erd = ResultBuilder.createErrorResultData();
+ 	    buildErrorResult(erd, failureMap);
+ 	    result = ResultBuilder.buildResult(erd);
+ 	  }
+ 	  return result ;
+ 	}
+ 
+ 	private void groupByMessage (String message, String memberNameOrId, Map<String, List<String>> map){
+ 	  List<String> members = map.get(message);
+ 
+ 	  if (members == null) {
+ 	    members = new LinkedList<String>();
+ 	  }
+ 	  members.add(memberNameOrId);
+ 	  map.put(message, members);
+ 	}
+ 
+ 
+ 	private InfoResultData buildSuccessData(Map<String, List<String>> successMap) {
+ 	  InfoResultData ird = ResultBuilder.createInfoResultData();
+ 	  Set<String> successMessages = successMap.keySet();
+ 
+ 	  for (String successMessage : successMessages) {
+ 	    ird.addLine(CliStrings.format(CliStrings.ACTION_SUCCCEEDED_ON_MEMBER, successMessage));
+ 	    
+ 	    List<String> successfullMembers = successMap.get(successMessage);
+ 	    int num = 0;
+ 	    for (String member : successfullMembers) {
+ 	      ird.addLine("" + ++num + "." + member);
+ 	    }
+ 	    ird.addLine("\n");
+ 	  }
+ 	  return ird;
+ 	}
+ 
+ 	private ErrorResultData buildFailureData(Map<String, List<String>> successMap, Map<String, List<String>> exceptionMap, Map<String, List<String>> errorMap, String errorHeader) {
+ 	  ErrorResultData erd = ResultBuilder.createErrorResultData();
+ 	  buildErrorResult(erd, successMap);
+ 	  erd.addLine("\n");
+ 	  erd.addLine(errorHeader);
+ 	  buildErrorResult(erd, exceptionMap);
+ 	  buildErrorResult(erd, errorMap);
+ 	  return erd;
+ 	}
+ 	
+ 	private void buildErrorResult(ErrorResultData erd, Map<String, List<String>> resultMap) {
+ 		if (resultMap != null && !resultMap.isEmpty()) {
+ 		    Set<String> messages = resultMap.keySet();
+ 
+ 		    for (String message : messages) {
+ 		      erd.addLine("\n");
+ 		      erd.addLine(message);
+ 		      erd.addLine(CliStrings.OCCURRED_ON_MEMBERS);
+ 		      List<String> members = resultMap.get(message);
+ 		      int num = 0;
+ 		      for (String member : members) {
+ 		        ++num;
+ 	                erd.addLine(""+num + "." + member);
+ 		      }
+ 		    }
+ 		  }
+ 	}
+ 	@CliAvailabilityIndicator({ CliStrings.LIST_DURABLE_CQS, CliStrings.CLOSE_DURABLE_CLIENTS, CliStrings.CLOSE_DURABLE_CQS, CliStrings.COUNT_DURABLE_CQ_EVENTS })
+ 	public boolean durableCommandsAvailable() {
+ 	  boolean isAvailable = true;
+ 	  if (CliUtil.isGfshVM()) { 
+ 	    isAvailable = getGfsh() != null && getGfsh().isConnectedAndReady();
+ 	  }
+ 	  return isAvailable;
+ 	}
+ }
+ 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/ExportImportSharedConfigurationCommands.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/ExportImportSharedConfigurationCommands.java
index 0000000,2e8447a..60eea3e
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/ExportImportSharedConfigurationCommands.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/ExportImportSharedConfigurationCommands.java
@@@ -1,0 -1,292 +1,297 @@@
+ /*
+  * 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.io.File;
+ import java.io.FileNotFoundException;
+ import java.io.IOException;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ 
+ import com.gemstone.gemfire.cache.execute.ResultCollector;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.lang.StringUtils;
+ import com.gemstone.gemfire.management.cli.CliMetaData;
+ import com.gemstone.gemfire.management.cli.Result;
+ import com.gemstone.gemfire.management.internal.cli.AbstractCliAroundInterceptor;
+ import com.gemstone.gemfire.management.internal.cli.CliUtil;
+ import com.gemstone.gemfire.management.internal.cli.GfshParseResult;
+ import com.gemstone.gemfire.management.internal.cli.functions.CliFunctionResult;
+ import com.gemstone.gemfire.management.internal.cli.functions.ExportSharedConfigurationFunction;
+ import com.gemstone.gemfire.management.internal.cli.functions.ImportSharedConfigurationArtifactsFunction;
+ import com.gemstone.gemfire.management.internal.cli.functions.LoadSharedConfigurationFunction;
+ import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
+ import com.gemstone.gemfire.management.internal.cli.remote.CommandExecutionContext;
+ import com.gemstone.gemfire.management.internal.cli.result.FileResult;
+ 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.result.TabularResultData;
++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;
+ 
+ /****
+  * Commands for the shared configuration
+  * @author bansods
+  *
+  */
+ @SuppressWarnings("unused")
+ public class ExportImportSharedConfigurationCommands extends AbstractCommandsSupport {
+ 
+   private final ExportSharedConfigurationFunction exportSharedConfigurationFunction = new ExportSharedConfigurationFunction();
+   private final ImportSharedConfigurationArtifactsFunction importSharedConfigurationFunction = new ImportSharedConfigurationArtifactsFunction();
+   private final LoadSharedConfigurationFunction loadSharedConfiguration = new LoadSharedConfigurationFunction();
+ 
+   @CliCommand(value = { CliStrings.EXPORT_SHARED_CONFIG }, help = CliStrings.EXPORT_SHARED_CONFIG__HELP)
+   @CliMetaData(interceptor = "com.gemstone.gemfire.management.internal.cli.commands.ExportImportSharedConfigurationCommands$ExportInterceptor",  readsSharedConfiguration=true, relatedTopic = {CliStrings.TOPIC_GEMFIRE_CONFIG})
++  @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.EXPORT_CONFIG)
+   public Result exportSharedConfig(
+       @CliOption(key = { CliStrings.EXPORT_SHARED_CONFIG__FILE}, 
+       mandatory = true,
+       help = CliStrings.EXPORT_SHARED_CONFIG__FILE__HELP)
+       String zipFileName,
+ 
+       @CliOption(key = { CliStrings.EXPORT_SHARED_CONFIG__DIR},
+       help = CliStrings.EXPORT_SHARED_CONFIG__DIR__HELP)
+       String dir
+       ) {
+     Result result;
+ 
+     InfoResultData infoData = ResultBuilder.createInfoResultData();
+     TabularResultData errorTable = ResultBuilder.createTabularResultData();
+     GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+     Set<DistributedMember> locators = new HashSet<DistributedMember>(cache.getDistributionManager().getAllHostedLocatorsWithSharedConfiguration().keySet());
+     byte [] byteData;
+     boolean success = false;
+ 
+     if (!locators.isEmpty()) {
+       for (DistributedMember locator : locators) {
+         ResultCollector<?, ?> rc = CliUtil.executeFunction(exportSharedConfigurationFunction, null, locator);
+         @SuppressWarnings("unchecked")
+         List<CliFunctionResult> results = (List<CliFunctionResult>) rc.getResult();
+         CliFunctionResult functionResult = results.get(0);
+ 
+         if (functionResult.isSuccessful()) {
+           byteData = functionResult.getByteData();
+           infoData.addAsFile(zipFileName, byteData, InfoResultData.FILE_TYPE_BINARY, CliStrings.EXPORT_SHARED_CONFIG__DOWNLOAD__MSG, false);
+           success = true;
+           break;
+         } else {
+           errorTable.accumulate(CliStrings.LOCATOR_HEADER, functionResult.getMemberIdOrName());
+           errorTable.accumulate(CliStrings.ERROR__MSG__HEADER, functionResult.getMessage());
+         }
+       }
+       if (success) {
+         result = ResultBuilder.buildResult(infoData);
+       } else {
+         errorTable.setStatus(Result.Status.ERROR);
+         result = ResultBuilder.buildResult(errorTable);
+       }
+     } else {
+       result = ResultBuilder.createGemFireErrorResult(CliStrings.SHARED_CONFIGURATION_NO_LOCATORS_WITH_SHARED_CONFIGURATION);
+     }
+     return result;
+   }
+ 
+   @CliCommand(value = { CliStrings.IMPORT_SHARED_CONFIG }, help = CliStrings.IMPORT_SHARED_CONFIG__HELP)
+   @CliMetaData(interceptor = "com.gemstone.gemfire.management.internal.cli.commands.ExportImportSharedConfigurationCommands$ImportInterceptor", writesToSharedConfiguration=true, relatedTopic = {CliStrings.TOPIC_GEMFIRE_CONFIG})
++  @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.IMPORT_CONFIG)
+   @SuppressWarnings("unchecked")
+   public Result importSharedConfig(
+       @CliOption(key = { CliStrings.IMPORT_SHARED_CONFIG__ZIP},
+       mandatory = true,
+       help = CliStrings.IMPORT_SHARED_CONFIG__ZIP__HELP)
+       String zip) {
+ 
+     GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+ 
+     if (!CliUtil.getAllNormalMembers(cache).isEmpty()) {
+       return ResultBuilder.createGemFireErrorResult(CliStrings.IMPORT_SHARED_CONFIG__CANNOT__IMPORT__MSG);
+     }
+ 
+     Set<DistributedMember> locators = new HashSet<DistributedMember>(cache.getDistributionManager().getAllHostedLocatorsWithSharedConfiguration().keySet());
+ 
+     if (locators.isEmpty()) {
+       return ResultBuilder.createGemFireErrorResult(CliStrings.NO_LOCATORS_WITH_SHARED_CONFIG);
+     }
+ 
+     Result result;
+     byte[][] shellBytesData = CommandExecutionContext.getBytesFromShell();
+     String[] names = CliUtil.bytesToNames(shellBytesData);
+     byte[][] bytes = CliUtil.bytesToData(shellBytesData);
+ 
+     String zipFileName = names[0];
+     byte[] zipBytes = bytes[0];
+ 
+     Object [] args = new Object[] {zipFileName, zipBytes};
+ 
+     InfoResultData infoData = ResultBuilder.createInfoResultData();
+     TabularResultData errorTable = ResultBuilder.createTabularResultData();
+ 
+     boolean success = false;
+     boolean copySuccess = false;
+ 
+     ResultCollector<?, ?> rc =  CliUtil.executeFunction(importSharedConfigurationFunction, args, locators);
+     List<CliFunctionResult> functionResults =  CliFunctionResult.cleanResults((List<CliFunctionResult>) rc.getResult());
+ 
+     for (CliFunctionResult functionResult : functionResults) {
+       if (!functionResult.isSuccessful()) {
+         errorTable.accumulate(CliStrings.LOCATOR_HEADER, functionResult.getMemberIdOrName());
+         errorTable.accumulate(CliStrings.ERROR__MSG__HEADER, functionResult.getMessage());
+       } else {
+         copySuccess = true;
+       }
+     }
+ 
+     if (!copySuccess ) {
+       errorTable.setStatus(Result.Status.ERROR);
+       return ResultBuilder.buildResult(errorTable);
+     }
+     
+     errorTable = ResultBuilder.createTabularResultData();
+ 
+     for (DistributedMember locator : locators) {
+       rc = CliUtil.executeFunction(loadSharedConfiguration, args, locator);
+       functionResults = (List<CliFunctionResult>) rc.getResult();
+       CliFunctionResult functionResult = functionResults.get(0);
+       if (functionResult.isSuccessful()) {
+         success = true;
+         infoData.addLine(functionResult.getMessage());
+         break; 
+       } else {
+         errorTable.accumulate(CliStrings.LOCATOR_HEADER, functionResult.getMemberIdOrName());
+         errorTable.accumulate(CliStrings.ERROR__MSG__HEADER, functionResult.getMessage());
+       }
+     }
+ 
+     if (success) {
+       result = ResultBuilder.buildResult(infoData);
+     } else {
+       errorTable.setStatus(Result.Status.ERROR);
+       result = ResultBuilder.buildResult(errorTable);
+     }
+     return result;
+   }
+ 
+ 
+   @CliAvailabilityIndicator({CliStrings.EXPORT_SHARED_CONFIG, CliStrings.IMPORT_SHARED_CONFIG})
+   public boolean sharedConfigCommandsAvailable() {
+     boolean isAvailable = true; // always available on server
+     if (CliUtil.isGfshVM()) { // in gfsh check if connected
+       isAvailable = getGfsh() != null && getGfsh().isConnectedAndReady();
+     }
+     return isAvailable;
+   }
+ 
+   /**
+    * Interceptor used by gfsh to intercept execution of export shared config command at "shell".
+    */
+   public static class ExportInterceptor extends AbstractCliAroundInterceptor {
+     private String saveDirString;
+ 
+     @Override
+     public Result preExecution(GfshParseResult parseResult) {
+       Map<String, String> paramValueMap = parseResult.getParamValueStrings();
+       String zip = paramValueMap.get(CliStrings.EXPORT_SHARED_CONFIG__FILE);
+       
+       if (!zip.endsWith(".zip")) {
+         return ResultBuilder.createUserErrorResult(CliStrings.format(CliStrings.INVALID_FILE_EXTENTION, ".zip"));
+       }
+       return ResultBuilder.createInfoResult("OK");
+     }
+ 
+     @Override
+     public Result postExecution(GfshParseResult parseResult, Result commandResult) {
+       if (commandResult.hasIncomingFiles()) {
+         try {
+           Map<String, String> paramValueMap = parseResult.getParamValueStrings();
+           String dir = paramValueMap.get(CliStrings.EXPORT_SHARED_CONFIG__DIR);
+           dir = (dir == null) ? null : dir.trim();
+ 
+           File saveDirFile = new File(".");
+           
+           if (dir != null && !dir.isEmpty()) {
+             saveDirFile = new File(dir);
+             if (saveDirFile.exists()) {
+               if (!saveDirFile.isDirectory())
+                 return ResultBuilder.createGemFireErrorResult(CliStrings.format(CliStrings.EXPORT_SHARED_CONFIG__MSG__NOT_A_DIRECTORY, dir));
+             } else if (!saveDirFile.mkdirs()) {
+               return ResultBuilder.createGemFireErrorResult(CliStrings.format(CliStrings.EXPORT_SHARED_CONFIG__MSG__CANNOT_CREATE_DIR, dir));
+             }
+           }
+           try {
+             if (!saveDirFile.canWrite()) {
+               return ResultBuilder.createGemFireErrorResult(CliStrings.format(CliStrings.EXPORT_SHARED_CONFIG__MSG__NOT_WRITEABLE, saveDirFile
+                   .getCanonicalPath()));
+             }
+           } catch (IOException ioex) {
+           }
+           saveDirString = saveDirFile.getAbsolutePath();
+           commandResult.saveIncomingFiles(saveDirString);
+           return commandResult;
+         } catch (IOException ioex) {
+           return ResultBuilder.createShellClientErrorResult(CliStrings.EXPORT_SHARED_CONFIG__UNABLE__TO__EXPORT__CONFIG);
+         }
+       }
+       return null;
+     }
+   }
+ 
+ 
+   public static class ImportInterceptor extends AbstractCliAroundInterceptor {
+ 
+     public Result preExecution(GfshParseResult parseResult) {
+       Map<String, String> paramValueMap = parseResult.getParamValueStrings();
+ 
+       String zip = paramValueMap.get(CliStrings.IMPORT_SHARED_CONFIG__ZIP);
+ 
+       zip = StringUtils.trim(zip);
+ 
+       if (zip == null) {
+         return ResultBuilder.createUserErrorResult(CliStrings.format(CliStrings.IMPORT_SHARED_CONFIG__PROVIDE__ZIP, CliStrings.IMPORT_SHARED_CONFIG__ZIP));
+       } 
+       if (!zip.endsWith(CliStrings.ZIP_FILE_EXTENSION)) {
+         return ResultBuilder.createUserErrorResult(CliStrings.format(CliStrings.INVALID_FILE_EXTENTION, CliStrings.ZIP_FILE_EXTENSION));
+       }
+ 
+       FileResult fileResult;
+ 
+       try {
+         fileResult = new FileResult(new String[] { zip });
+       } catch (FileNotFoundException fnfex) {
+         return ResultBuilder.createUserErrorResult("'" + zip + "' not found.");
+       } catch (IOException ioex) {
+         return ResultBuilder.createGemFireErrorResult(ioex.getClass().getName() + ": "
+             + ioex.getMessage());
+       }
+ 
+       return fileResult;
+     }
+     @Override
+     public Result postExecution(GfshParseResult parseResult, Result commandResult) {
+       return null;
+     }
+   }
+   
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/FunctionCommands.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/FunctionCommands.java
index 0000000,7930e1e..7e9a128
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/FunctionCommands.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/FunctionCommands.java
@@@ -1,0 -1,642 +1,648 @@@
+ /*
+  * 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.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 org.springframework.shell.core.CommandMarker;
+ import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+ import org.springframework.shell.core.annotation.CliCommand;
+ import org.springframework.shell.core.annotation.CliOption;
+ 
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.execute.Execution;
+ import com.gemstone.gemfire.cache.execute.Function;
+ import com.gemstone.gemfire.cache.execute.FunctionException;
+ import com.gemstone.gemfire.cache.execute.FunctionService;
+ import com.gemstone.gemfire.cache.execute.ResultCollector;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.internal.ClassPathLoader;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.management.DistributedRegionMXBean;
+ import com.gemstone.gemfire.management.ManagementService;
+ 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.cli.Result.Status;
+ import com.gemstone.gemfire.management.internal.MBeanJMXAdapter;
+ import com.gemstone.gemfire.management.internal.cli.AbstractCliAroundInterceptor;
+ import com.gemstone.gemfire.management.internal.cli.CliUtil;
+ import com.gemstone.gemfire.management.internal.cli.GfshParseResult;
+ import com.gemstone.gemfire.management.internal.cli.LogWrapper;
+ import com.gemstone.gemfire.management.internal.cli.functions.CliFunctionResult;
+ import com.gemstone.gemfire.management.internal.cli.functions.ListFunctionFunction;
+ import com.gemstone.gemfire.management.internal.cli.functions.UnregisterFunction;
+ import com.gemstone.gemfire.management.internal.cli.functions.UserFunctionExecution;
+ import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
+ import com.gemstone.gemfire.management.internal.cli.result.CommandResultException;
+ import com.gemstone.gemfire.management.internal.cli.result.CompositeResultData;
+ import com.gemstone.gemfire.management.internal.cli.result.ErrorResultData;
+ import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
+ import com.gemstone.gemfire.management.internal.cli.result.TabularResultData;
+ import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
++import com.gemstone.gemfire.management.internal.security.Resource;
++import com.gemstone.gemfire.management.internal.security.ResourceConstants;
++import com.gemstone.gemfire.management.internal.security.ResourceOperation;
+ 
+ /**
+  * @author David Hoots
+  * 
+  * @since 7.0
+  */
+ @SuppressWarnings("unused")
+ public class FunctionCommands implements CommandMarker {
+   private final ListFunctionFunction listFunctionFunction = new ListFunctionFunction();
+   
+   private Gfsh getGfsh() {
+     return Gfsh.getCurrentInstance();
+   }
+   
+   @CliCommand(value = CliStrings.EXECUTE_FUNCTION, help = CliStrings.EXECUTE_FUNCTION__HELP)
+   @CliMetaData(relatedTopic = { CliStrings.TOPIC_GEMFIRE_FUNCTION })
++  @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.EXECUTE_FUNCTION)
+   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.EXECUTE_FUNCTION__ONGROUPS, 
+           unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, 
+           optionContext = ConverterHint.MEMBERGROUP,
+           help = CliStrings.EXECUTE_FUNCTION__ONGROUPS__HELP) String[] onGroups,
+       @CliOption(key = CliStrings.EXECUTE_FUNCTION__ONMEMBER, 
+           unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, 
+           optionContext = ConverterHint.MEMBERIDNAME,
+           help = CliStrings.EXECUTE_FUNCTION__ONMEMBER__HELP) String onMember,
+       @CliOption(key = CliStrings.EXECUTE_FUNCTION__ONREGION, 
+           unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, 
+           optionContext = ConverterHint.REGIONPATH,
+           help = CliStrings.EXECUTE_FUNCTION__ONREGION__HELP) String onRegion,
+       @CliOption(key = CliStrings.EXECUTE_FUNCTION__ARGUMENTS, 
+           unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, 
+           help = CliStrings.EXECUTE_FUNCTION__ARGUMENTS__HELP) String[] arguments,
+       @CliOption(key = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR, 
+           unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, 
+           help = CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR__HELP) String resultCollector,
+       @CliOption(key = CliStrings.EXECUTE_FUNCTION__FILTER, 
+           unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, 
+           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<String>();
+     Execution execution = null;
+     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 (onRegion != null && onMember != null && onGroups != null) {
+         ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+             .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(
+                 CliStrings.EXECUTE_FUNCTION__MSG__OPTIONS);
+         result = ResultBuilder.buildResult(errorResultData);
+         return result;
+       } else if (onRegion != null && onMember != null) {
+         ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+             .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(
+                 CliStrings.EXECUTE_FUNCTION__MSG__OPTIONS);
+         result = ResultBuilder.buildResult(errorResultData);
+         return result;
+       } else if (onMember != null && onGroups != null) {
+         ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+             .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(
+                 CliStrings.EXECUTE_FUNCTION__MSG__OPTIONS);
+         result = ResultBuilder.buildResult(errorResultData);
+         return result;
+       } else if (onRegion != null && onGroups != null) {
+         ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+             .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT).addLine(
+                 CliStrings.EXECUTE_FUNCTION__MSG__OPTIONS);
+         result = ResultBuilder.buildResult(errorResultData);
+         return result;
+       } else if (onRegion != null && onMember != null && onGroups != null) {
+         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;
+       }
+       
+       Cache cache = CacheFactory.getAnyInstance();   
+      
+ 
+       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(GemFireCacheImpl.getInstance())
+               .getDistributedRegionMXBean(onRegion);
+           if (bean == null) {
+             bean = ManagementService.getManagementService(
+                 GemFireCacheImpl.getInstance()).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 == false) {
+               DistributedMember dsmember = (DistributedMember) it.next();
+               for (String memberName : membersName) {
+                 if (MBeanJMXAdapter.getMemberNameOrId(dsmember).equals(
+                     memberName)) {
+                   member = dsmember;
+                   matchFound = true;
+                   break;
+                 }
+               }
+             }
+           }
+           if (matchFound == true) {
+             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.withArgs(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<DistributedMember>();
+         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 (InstantiationException e) {
+       ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+           .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+           .addLine(e.getMessage());
+       result = ResultBuilder.buildResult(errorResultData);
+       return result;
+     } catch (IllegalAccessException e) {
+       ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+           .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+           .addLine(e.getMessage());
+       result = ResultBuilder.buildResult(errorResultData);
+       return result;
+     } catch (IllegalArgumentException e) {
+       ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+           .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+           .addLine(e.getMessage());
+       result = ResultBuilder.buildResult(errorResultData);
+       return result;
+     } catch (SecurityException e) {
+       ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+           .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+           .addLine(e.getMessage());
+       result = ResultBuilder.buildResult(errorResultData);
+       return result;
+     } catch (Exception e) {
+       ErrorResultData errorResultData = ResultBuilder.createErrorResultData()
+       .setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
+       .addLine(e.getMessage());
+       result = ResultBuilder.buildResult(errorResultData);
+       return result;
+     }
+ 
+     return result;
+   }
+ 
+   DistributedMember getMember(Cache cache, String memberNameOrId) {
+     DistributedMember member = null;
+     Set<DistributedMember> dsMembers = CliUtil.getAllMembers(cache) ;
+     Iterator<DistributedMember> it = dsMembers.iterator();
+     while (it.hasNext()) {
+       DistributedMember tempMember = (DistributedMember) it.next();
+       if (memberNameOrId.equals(tempMember.getId())
+           || memberNameOrId.equals(tempMember.getName())) {
+         return tempMember;
+       }
+     }
+     return member;
+   }
+ 
+   void executeAndGetResults(String functionId, String filterString,
+       String resultCollector, String[] arguments, Cache cache,
+       DistributedMember member, TabularResultData resultTable, String onRegion) {
+     StringBuilder resultMessege = 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] = new String();
+         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).withArgs(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) {
+                 resultMessege.append(((String) resultObj));
+               } else if (resultObj instanceof Exception) {
+                 resultMessege.append(((Exception)resultObj).getMessage());
+               } else {
+                 resultMessege.append(resultObj);
+               }
+             }
+           }
+         }
+         toTabularResultData(resultTable, member.getId(), resultMessege
+             .toString());
+       }else{
+         toTabularResultData(resultTable, member.getId(), CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR);        
+       }
+     } catch (FunctionException e) {
+       resultMessege.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(), resultMessege
+           .toString());
+     } catch (Exception e) {
+       resultMessege.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(), resultMessege
+           .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_GEMFIRE_FUNCTION } ,
 -      interceptor = "com.gemstone.gemfire.management.internal.cli.commands.FunctionCommands$Interceptor")  
++      interceptor = "com.gemstone.gemfire.management.internal.cli.commands.FunctionCommands$Interceptor")
++  @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.DESTROY_FUNCTION)
+   //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.DESTROY_FUNCTION__ONGROUPS, 
+                  unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+                  optionContext = ConverterHint.MEMBERGROUP,
+                  help = CliStrings.DESTROY_FUNCTION__ONGROUPS__HELP) String[] groups,
+       @CliOption(key = CliStrings.DESTROY_FUNCTION__ONMEMBER, 
+                  unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
+                  optionContext = ConverterHint.MEMBERIDNAME,
+                  help = CliStrings.DESTROY_FUNCTION__ONMEMBER__HELP) String memberId) {
+     Result result = null;
+     try {    
+       Cache cache = CacheFactory.getAnyInstance();
+       Set<DistributedMember> dsMembers = new HashSet<DistributedMember>();
+       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.DESTROY_FUNCTION__ONGROUPS);
+       String onMember = paramValueMap.get(CliStrings.DESTROY_FUNCTION__ONMEMBER);
+       
+       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) );
+       }     
+     }
+ 
+     @Override
+     public Result postExecution(GfshParseResult parseResult, Result commandResult) {     
+       return commandResult;
+     }
+   }
+   
+   Result executeFunction(Cache cache, Set<DistributedMember> DsMembers, String functionId){
+     //unregister on a set of of members
+     Function unregisterFunction = new UnregisterFunction();
+     FunctionService.registerFunction(unregisterFunction);
+     List resultList = null;
+     
+     if(DsMembers.isEmpty()){      
+      return  ResultBuilder.createInfoResult("No members for execution");
+     }
+     Object[] obj = new Object[1];
+     obj[0] = functionId;
+     
+     Execution execution = FunctionService.onMembers(DsMembers).withArgs(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_GEMFIRE_FUNCTION })
++  @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+   public Result listFunction(
+       @CliOption(key = CliStrings.LIST_FUNCTION__MATCHES, 
+                  help = CliStrings.LIST_FUNCTION__MATCHES__HELP)String matches,
+       @CliOption(key = CliStrings.LIST_FUNCTION__GROUP, 
+                  optionContext = ConverterHint.MEMBERGROUP,
+                  help = CliStrings.LIST_FUNCTION__GROUP__HELP)
+       @CliMetaData (valueSeparator = ",") String groups,
+       @CliOption(key = CliStrings.LIST_FUNCTION__MEMBER, 
+                  optionContext = ConverterHint.MEMBERIDNAME,
+                  help = CliStrings.LIST_FUNCTION__MEMBER__HELP)
+       @CliMetaData (valueSeparator = ",") String members) {
+     TabularResultData tabularData = ResultBuilder.createTabularResultData();
+     boolean accumulatedData = false;
+ 
+     Cache cache = CacheFactory.getAnyInstance();
+ 
+     Set<DistributedMember> targetMembers;
+     try {
+       targetMembers = CliUtil.findAllMatchingMembers(groups, members);
+     } catch (CommandResultException crex) {
+       return crex.getResult();
+     }
+     
+     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 (int i = 0; i < strings.length; i++) {
+             tabularData.accumulate("Member", result.getMemberIdOrName());
+             tabularData.accumulate("Function", strings[i]);
+             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());
+     }
+   }
+   
+   @CliAvailabilityIndicator({CliStrings.EXECUTE_FUNCTION, CliStrings.DESTROY_FUNCTION, CliStrings.LIST_FUNCTION})  
+   public boolean functionCommandsAvailable() {
+     boolean isAvailable = true; //always available on server
+     if (CliUtil.isGfshVM()) { //in gfsh check if connected
+       isAvailable = getGfsh() != null && getGfsh().isConnectedAndReady();
+     }
+     return isAvailable;  
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/GfshHelpCommands.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/GfshHelpCommands.java
index 0000000,24fd117..d946ffb
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/GfshHelpCommands.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/GfshHelpCommands.java
@@@ -1,0 -1,106 +1,111 @@@
+ /*
+  * 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.util.Map;
+ import java.util.Map.Entry;
+ import java.util.Set;
+ 
+ import org.springframework.shell.core.CommandMarker;
+ import org.springframework.shell.core.annotation.CliCommand;
+ 
+ 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.cli.CommandManager;
+ import com.gemstone.gemfire.management.internal.cli.GfshParser;
+ import com.gemstone.gemfire.management.internal.cli.annotation.CliArgument;
+ import com.gemstone.gemfire.management.internal.cli.help.CliTopic;
+ import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
+ import com.gemstone.gemfire.management.internal.cli.result.CompositeResultData;
+ import com.gemstone.gemfire.management.internal.cli.result.CompositeResultData.SectionResultData;
+ import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
+ import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
++import com.gemstone.gemfire.management.internal.security.Resource;
++import com.gemstone.gemfire.management.internal.security.ResourceConstants;
++import com.gemstone.gemfire.management.internal.security.ResourceOperation;
+ 
+ /**
+  * 
+  * @author Nikhil Jadhav
+  * @author Abhishek Chaudhari
+  * 
+  * @since 7.0
+  */
+ public class GfshHelpCommands implements CommandMarker{
+ 
+   private Gfsh getGfsh() {
+     return Gfsh.getCurrentInstance();
+   }
+   
+   @CliCommand(value = CliStrings.HELP, help = CliStrings.HELP__HELP)
+   @CliMetaData(shellOnly=true, relatedTopic = {CliStrings.TOPIC_GEMFIRE_HELP})
++  @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+   public Result obtainHelp(
+       @CliArgument(name = CliStrings.HELP__COMMAND, 
+                  argumentContext = CliStrings.PARAM_CONTEXT_HELP, 
+                  help = CliStrings.HELP__COMMAND__HELP) 
+                  String commandString) {
+     return ResultBuilder.createInfoResult(getGfsh().obtainHelp(commandString, null));
+   }
+   
+   
+   
+   @CliCommand(value = CliStrings.HINT, help = CliStrings.HINT__HELP)
+   @CliMetaData(shellOnly=true, relatedTopic = {CliStrings.TOPIC_GEMFIRE_HELP})
++  @ResourceOperation(resource = Resource.DISTRIBUTED_SYSTEM, operation= ResourceConstants.LIST_DS)
+   public Result hint(
+       @CliArgument(name = CliStrings.HINT__TOPICNAME, 
+                 argumentContext = ConverterHint.HINTTOPIC, 
+                 help = CliStrings.HINT__TOPICNAME) 
+                 String topicName) {
+     Result result = null;
+     CommandManager commandManager = CommandManager.getExisting();
+     if (commandManager == null) {
+       result= ResultBuilder.createShellClientErrorResult(CliStrings.HINT__MSG__SHELL_NOT_INITIALIZED);
+     } else { 
+       StringBuilder builder = new StringBuilder();
+       if (topicName == null) {
+         builder.append(CliStrings.HINT__MSG__TOPICS_AVAILABLE).append(GfshParser.LINE_SEPARATOR);
+         Set<String> topicNameSet = commandManager.getTopicNames();
+         for (String topic : topicNameSet) {
+           builder.append(topic).append(GfshParser.LINE_SEPARATOR);
+         }
+         result = ResultBuilder.createInfoResult(builder.toString());
+       } else {
+         CliTopic topic = commandManager.getTopic(topicName);
+         if (topic == null) {
+           result = ResultBuilder.createInfoResult(CliStrings.format(CliStrings.HINT__MSG__UNKNOWN_TOPIC, topicName));
+         } else {
+           CompositeResultData compositeResultData = ResultBuilder.createCompositeResultData();
+           SectionResultData commandHelpSection = compositeResultData.addSection("Commands And Help");
+           compositeResultData.setHeader(topic.getOneLinerDescription());
+           Map<String, String> commandsNameHelp = topic.getCommandsNameHelp();
+           Set<Entry<String, String>> entries = commandsNameHelp.entrySet();
+           
+           for (Entry<String, String> entry : entries) {
+             commandHelpSection.addData(entry.getKey(), entry.getValue());
+           }
+ 
+           result = ResultBuilder.buildResult(compositeResultData);
+         }
+       }
+     }
+     
+     return result;
+   }
+ }