Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1746,6 +1746,20 @@ public void flowCallOutExpressionCompat() throws Exception {
assertLog(runtime.allLogs(), ".*" + Pattern.quote("out as map with loop: [abc_0, abc_1]") + ".*");
}

@Test
public void prefixedFunctionsInExpressions() throws Exception {
deploy("prefixedFunctions");

save(ProcessConfiguration.builder()
.putArguments("name", "world")
.build());

run();

assertLog(runtime.allLogs(), ".*Hi, world!.*");
assertLog(runtime.allLogs(), ".*Hello, world!.*");
}

private void deploy(String name) throws URISyntaxException, IOException {
runtime.deploy(name);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.walmartlabs.concord.runtime.v2.runner.functions;

import com.walmartlabs.concord.runtime.v2.sdk.ELFunction;

import javax.inject.Named;

@Named
public class TestFunction {

@ELFunction("testGreet")
public static String regularGreet(String name) {
return "Hi, " + name + "!";
}

@ELFunction("testFunction:greet")
public static String prefixedGreet(String name) {
return "Hello, " + name + "!";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
flows:
default:
- log: "${testGreet(name)}"
- log: "${testFunction:greet(name)}"
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ public class DefaultExpressionEvaluator implements ExpressionEvaluator {

@Inject
public DefaultExpressionEvaluator(TaskProviders taskProviders,
FunctionHolder functionHolder,
List<CustomTaskMethodResolver> taskMethodResolvers,
List<CustomBeanMethodResolver> beanMethodResolvers,
SensitiveDataProcessor sensitiveDataProcessor) {
this.delegate = new LazyExpressionEvaluator(taskProviders, taskMethodResolvers, beanMethodResolvers, sensitiveDataProcessor);
this.delegate = new LazyExpressionEvaluator(taskProviders, functionHolder, taskMethodResolvers, beanMethodResolvers, sensitiveDataProcessor);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,23 @@

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class FunctionMapper extends javax.el.FunctionMapper {
public class FunctionHolder {

private final Map<String, Method> functions;
private final Map<String, Method> functions = new ConcurrentHashMap<>();

public FunctionMapper(Map<String, Method> functions) {
this.functions = functions;
public FunctionHolder register(String name, Method method) {
functions.put(name, method);
return this;
}

@Override
public Method resolveFunction(String prefix, String localName) {
if (prefix == null || prefix.trim().isEmpty()) {
return functions.get(localName);
}
public Method resolve(String name) {
return functions.get(name);
}

return functions.get(prefix + ":" + localName);
public Set<String> names() {
return Set.copyOf(functions.keySet());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@

import com.walmartlabs.concord.common.ConfigurationUtils;
import com.walmartlabs.concord.common.ExceptionUtils;
import com.walmartlabs.concord.runtime.v2.runner.el.functions.*;
import com.walmartlabs.concord.runtime.v2.runner.el.resolvers.MapELResolver;
import com.walmartlabs.concord.runtime.v2.runner.el.resolvers.*;
import com.walmartlabs.concord.runtime.v2.runner.el.resolvers.MapELResolver;
import com.walmartlabs.concord.runtime.v2.runner.tasks.TaskProviders;
import com.walmartlabs.concord.runtime.v2.runner.vm.WrappedException;
import com.walmartlabs.concord.runtime.v2.sdk.*;
Expand All @@ -50,12 +49,13 @@ public class LazyExpressionEvaluator implements ExpressionEvaluator {
private final SensitiveDataProcessor sensitiveDataProcessor;

public LazyExpressionEvaluator(TaskProviders taskProviders,
FunctionHolder functionHolder,
List<CustomTaskMethodResolver> taskMethodResolvers,
List<CustomBeanMethodResolver> beanMethodResolvers,
SensitiveDataProcessor sensitiveDataProcessor) {
this.taskProviders = taskProviders;
this.sensitiveDataProcessor = sensitiveDataProcessor;
this.functionMapper = createFunctionMapper();
this.functionMapper = new DelegatingFunctionMapper(functionHolder);
this.taskMethodResolvers = taskMethodResolvers;
this.beanMethodResolvers = beanMethodResolvers;
}
Expand Down Expand Up @@ -203,22 +203,6 @@ private ELResolver createResolver(LazyEvalContext evalContext,
return r;
}

private static FunctionMapper createFunctionMapper() {
var functions = new HashMap<String, Method>();
functions.put("hasVariable", HasVariableFunction.getMethod());
functions.put("hasNonNullVariable", HasNonNullVariableFunction.getMethod());
functions.put("orDefault", OrDefaultFunction.getMethod());
functions.put("allVariables", AllVariablesFunction.getMethod());
functions.put("currentFlowName", CurrentFlowNameFunction.getMethod());
functions.put("evalAsMap", EvalAsMapFunction.getMethod());
functions.put("isDebug", IsDebugFunction.getMethod());
functions.put("throw", ThrowFunction.getMethod());
functions.put("hasFlow", HasFlowFunction.getMethod());
functions.put("uuid", UuidFunction.getMethod());
functions.put("isDryRun", IsDryRunFunction.getMethod());
return new FunctionMapper(functions);
}

private static boolean hasExpression(String s) {
return s.contains("${");
}
Expand Down Expand Up @@ -272,4 +256,20 @@ private static Optional<String> propertyNameFromException(PropertyNotFoundExcept

return Optional.empty();
}

private static class DelegatingFunctionMapper extends FunctionMapper {
final FunctionHolder functionHolder;

DelegatingFunctionMapper(FunctionHolder functionHolder) {
this.functionHolder = functionHolder;
}

@Override
public Method resolveFunction(String prefix, String localName) {
if (prefix != null && !prefix.isBlank()) {
return functionHolder.resolve(prefix + ":" + localName);
}
return functionHolder.resolve(localName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* *****
* Concord
* -----
* Copyright (C) 2017 - 2020 Walmart Inc.
* Copyright (C) 2017 - 2025 Walmart Inc.
* -----
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,21 +20,14 @@
* =====
*/

import com.walmartlabs.concord.runtime.v2.sdk.ELFunction;
import com.walmartlabs.concord.runtime.v2.runner.el.ThreadLocalEvalContext;

import java.lang.reflect.Method;
import java.util.Map;

public final class AllVariablesFunction {

public static Method getMethod() {
try {
return AllVariablesFunction.class.getMethod("allVariables");
} catch (Exception e) {
throw new RuntimeException("Method not found");
}
}

@ELFunction
public static Map<String, Object> allVariables() {
return ThreadLocalEvalContext.get()
.variables()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* *****
* Concord
* -----
* Copyright (C) 2017 - 2020 Walmart Inc.
* Copyright (C) 2017 - 2025 Walmart Inc.
* -----
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,21 +20,13 @@
* =====
*/

import com.walmartlabs.concord.runtime.v2.sdk.ELFunction;
import com.walmartlabs.concord.runtime.v2.runner.el.ThreadLocalEvalContext;
import com.walmartlabs.concord.runtime.v2.sdk.Context;

import java.lang.reflect.Method;

public final class CurrentFlowNameFunction {

public static Method getMethod() {
try {
return CurrentFlowNameFunction.class.getMethod("currentFlowName");
} catch (Exception e) {
throw new RuntimeException("Method not found");
}
}

@ELFunction
public static String currentFlowName() {
Context ctx = ThreadLocalEvalContext.get().context();
if (ctx == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* *****
* Concord
* -----
* Copyright (C) 2017 - 2020 Walmart Inc.
* Copyright (C) 2017 - 2025 Walmart Inc.
* -----
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,28 +20,21 @@
* =====
*/

import com.walmartlabs.concord.runtime.v2.sdk.EvalContextFactory;
import com.walmartlabs.concord.runtime.v2.sdk.ExpressionEvaluator;
import com.walmartlabs.concord.runtime.v2.sdk.ELFunction;
import com.walmartlabs.concord.runtime.v2.runner.el.ThreadLocalEvalContext;
import com.walmartlabs.concord.runtime.v2.sdk.Context;
import com.walmartlabs.concord.runtime.v2.sdk.EvalContextFactory;
import com.walmartlabs.concord.runtime.v2.sdk.ExpressionEvaluator;
import com.walmartlabs.concord.svm.Runtime;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import static com.walmartlabs.concord.common.ConfigurationUtils.deepMerge;

public final class EvalAsMapFunction {

public static Method getMethod() {
try {
return EvalAsMapFunction.class.getMethod("evalAsMap", Object.class);
} catch (Exception e) {
throw new RuntimeException("Method not found");
}
}

@ELFunction
@SuppressWarnings("unchecked")
public static Map<String, Object> evalAsMap(Object value) {
Context ctx = ThreadLocalEvalContext.get().context();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,13 @@

import com.walmartlabs.concord.runtime.v2.model.ProcessDefinition;
import com.walmartlabs.concord.runtime.v2.model.Profile;
import com.walmartlabs.concord.runtime.v2.sdk.ELFunction;
import com.walmartlabs.concord.runtime.v2.runner.el.ThreadLocalEvalContext;
import com.walmartlabs.concord.runtime.v2.sdk.Context;

import java.lang.reflect.Method;

public final class HasFlowFunction {

public static Method getMethod() {
try {
return HasFlowFunction.class.getMethod("hasFlow", String.class);
} catch (Exception e) {
throw new RuntimeException("Method not found");
}
}

@ELFunction
public static boolean hasFlow(String name) {
if (name == null || name.trim().isEmpty()) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* *****
* Concord
* -----
* Copyright (C) 2017 - 2020 Walmart Inc.
* Copyright (C) 2017 - 2025 Walmart Inc.
* -----
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,25 +21,18 @@
*/

import com.walmartlabs.concord.common.ConfigurationUtils;
import com.walmartlabs.concord.runtime.v2.sdk.ELFunction;
import com.walmartlabs.concord.runtime.v2.runner.el.ThreadLocalEvalContext;
import com.walmartlabs.concord.runtime.v2.sdk.Variables;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;

public final class HasNonNullVariableFunction {

public static Method getMethod() {
try {
return HasNonNullVariableFunction.class.getMethod("hasVariable", String.class);
} catch (Exception e) {
throw new RuntimeException("Method not found");
}
}

@ELFunction
@SuppressWarnings("unchecked")
public static boolean hasVariable(String name) {
public static boolean hasNonNullVariable(String name) {
if (name == null || name.trim().isEmpty()) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* *****
* Concord
* -----
* Copyright (C) 2017 - 2020 Walmart Inc.
* Copyright (C) 2017 - 2025 Walmart Inc.
* -----
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,23 +21,16 @@
*/

import com.walmartlabs.concord.common.ConfigurationUtils;
import com.walmartlabs.concord.runtime.v2.sdk.ELFunction;
import com.walmartlabs.concord.runtime.v2.runner.el.ThreadLocalEvalContext;
import com.walmartlabs.concord.runtime.v2.sdk.Variables;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;

public final class HasVariableFunction {

public static Method getMethod() {
try {
return HasVariableFunction.class.getMethod("hasVariable", String.class);
} catch (Exception e) {
throw new RuntimeException("Method not found");
}
}

@ELFunction
@SuppressWarnings("unchecked")
public static boolean hasVariable(String name) {
if (name == null || name.trim().isEmpty()) {
Expand Down
Loading