UserFunctionExecution implements InternalFunction<Object[]> { @Override public void execute(FunctionContext<Object[]> context) { Cache cache = ((InternalCache) context.getCache()).getCacheForProcessingClientRequests(); DistributedMember member = cache.getDistributedSystem().getDistributedMember(); Object[] args = context.getArguments(); if (args == null) { context.getResultSender().lastResult(new CliFunctionResult(context.getMemberName(), ERROR, CliStrings.EXECUTE_FUNCTION__MSG__COULD_NOT_RETRIEVE_ARGUMENTS)); return; } String functionId = ((String) args[0]); String filterString = ((String) args[1]); String resultCollectorName = ((String) args[2]); String argumentsString = ((String) args[3]); String onRegion = ((String) args[4]); Properties credentials = (Properties) args[5]; SecurityService securityService = ((InternalCache) context.getCache()).getSecurityService(); boolean loginSuccessful = false; try { if (loginRequired(securityService)) { securityService.login(credentials); loginSuccessful = true; } Function<?> function = loadFunction(functionId); if (function == null) { context.getResultSender() .lastResult(new CliFunctionResult(context.getMemberName(), ERROR, (CliStrings.format( CliStrings.EXECUTE_FUNCTION__MSG__DOES_NOT_HAVE_FUNCTION_0_REGISTERED, functionId)))); return; } Set<String> filters = parseFilters(filterString); String[] functionArgs = parseArguments(argumentsString); ResultCollector<Object, List<Object>> resultCollectorInstance = parseResultCollector(resultCollectorName); function.getRequiredPermissions(onRegion, functionArgs).forEach(securityService::authorize); Execution<Object, Object, List<Object>> execution = buildExecution(cache, onRegion); if (execution == null) { context.getResultSender() .lastResult(new CliFunctionResult(context.getMemberName(), ERROR, CliStrings.format( CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_EXECUTING_0_ON_MEMBER_1_ON_REGION_2_DETAILS_3, functionId, member.getId(), onRegion, CliStrings.EXECUTE_FUNCTION__MSG__ERROR_IN_RETRIEVING_EXECUTOR))); return; } if (resultCollectorInstance != null) { execution = execution.withCollector(resultCollectorInstance); } if (functionArgs != null && functionArgs.length > 0) { execution = execution.setArguments(functionArgs); } if (filters.size() > 0) { execution = execution.withFilter(filters); } List<Object> results = null; boolean functionSuccess = true; List<String> resultMessage = new ArrayList<>(); ResultCollector<Object, List<Object>> rc = execution.execute(function.getId()); if (function.hasResult()) { results = rc.getResult(); } if (results != null) { for (Object resultObj : results) { if (resultObj != null) { if (resultObj instanceof Exception) { resultMessage.add(((Exception) resultObj).getMessage()); functionSuccess = false; } else { resultMessage.add(resultObj.toString()); } } } } context.getResultSender().lastResult(new CliFunctionResult(context.getMemberName(), functionSuccess ? OK : ERROR, resultMessage.toString())); } catch (RegionNotFoundException regionNotFoundException) { context.getResultSender().lastResult( new CliFunctionResult(context.getMemberName(), ERROR, onRegion + " does not exist")); } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { context.getResultSender() .lastResult(new CliFunctionResult(context.getMemberName(), ERROR, CliStrings.format( CliStrings.EXECUTE_FUNCTION__MSG__RESULT_COLLECTOR_0_NOT_FOUND_ERROR_1, resultCollectorName, e.getMessage()))); } catch (Exception e) { logger.error("error executing function " + functionId, e); context.getResultSender().lastResult( new CliFunctionResult(context.getMemberName(), ERROR, "Exception: " + e.getMessage())); } finally { if (loginSuccessful) { securityService.logout(); } } }  @Override boolean isHA(); @Override String getId(); @Override Collection<ResourcePermission> getRequiredPermissions(String regionName); @Override void execute(FunctionContext<Object[]> context); static final String ID; }
@Test public void executeShouldFailWhenNoArgumentsAreProvided() { when(context.getArguments()).thenReturn(null); function.execute(context); verify(resultSender, times(1)).lastResult(resultCaptor.capture()); CliFunctionResult result = resultCaptor.getValue(); assertThat(result.isSuccessful()).isFalse(); assertThat(result.getStatusMessage()).isEqualTo("Could not retrieve arguments"); }
@Test @SuppressWarnings("unchecked") public void executeShouldProperlyConfigureExecutionContext() { Set<String> filter = new HashSet<>(); filter.add("key1"); filter.add("key2"); arguments = new Object[] {"TestFunction", "key1,key2", "TestResultCollector", "arg1,arg2", SEPARATOR + "TestRegion", new Properties()}; when(context.getArguments()).thenReturn(arguments); function.execute(context); verify(execution, times(1)).withFilter(filter); verify(execution, times(1)).withCollector(resultCollector); verify(execution, times(1)).setArguments(new String[] {"arg1", "arg2"}); verify(resultSender, times(1)).lastResult(resultCaptor.capture()); CliFunctionResult resultFullArguments = resultCaptor.getValue(); assertThat(resultFullArguments.isSuccessful()).isTrue(); reset(resultSender); reset(execution); arguments = new Object[] {"TestFunction", "", "", "", "", new Properties()}; when(context.getArguments()).thenReturn(arguments); function.execute(context); verify(execution, never()).withFilter(any()); verify(execution, never()).setArguments(any()); verify(execution, never()).withCollector(any()); verify(resultSender, times(1)).lastResult(resultCaptor.capture()); CliFunctionResult resultNoArguments = resultCaptor.getValue(); assertThat(resultNoArguments.isSuccessful()).isTrue(); }