Run time input variables type casting

My situation:
I have a form from which I capture a set of values in String format and call my Rest service with values as String data type in JSON.
I have multiple DMN decision tables that take the form input and give back the evaluation result. Which DMN table is to be called is decided based on the input values from the form. Java Class creates the Decision object accordingly by passing the value to the engine for Parse Decisions.
Peculiarity is that while all the input variables are captured as string from the form, some of them could contain integer values or boolean values etc. based on user entry. Each DMN decision table knows what data type each input parameter should come in but needs to evaluate/typecast it at run time. How can we do this

example: Le’s consider there are two DMN tables D1 and D2 called based on some condition

Input Form Variables: “QID” = “1”, “QID”= “Name”

D1 Treats QID1 as String so if I set the variables in object as is it works

D2 Treats QID1 as Integer and so if i set the variables in object as is, it throws the exception (Caused by: org.camunda.bpm.dmn.feel.impl.juel.FeelConvertException: FEEL-01015 Unable to convert value ‘10’ of type ‘class java.lang.String’ to type ’
class java.lang.Long’ in expression ‘[1…QID1]’)

Would like if somehow we can specify in DMN D2 to typecast the incoming value to Integer before using it for any evaluation.

Calling Java class has no way to know which DMN it’s going to call at runtime and what data types for what variables is the DMN table expecting. Calling Java class just takes all the input parameters and based on runtime input DMN table value calls it. DMN picks and uses the input parameters it needs for evaluation.

QID value is being used in a rule for evaluation at runtime in the DMN table

Hi @jagatramkhanna,

this is an uncommon use case. One way is to provide conversion functions like string() or number(). In the expression, you could write [1..number(QID1)].

Alternatively, you can use the built-in functions of the FEEL extension.

Does this help you?

Best regards,
Philipp

Hello Philipp,

I tired using the option you provided as I expected this would help. But on doing so it gives me an exception for not being able to resolve and find function “number”. Stack trace below

I am using this deployed on a Camunda EE Platform (trial version). Calling the DMNs using Rest call interface provided by camunda EE platform

t.exception.RestExceptionHandler from Application class org.camunda.bpm.engine.rest.impl.application.DefaultApplication
05-Oct-2018 10:31:04.320 SEVERE [http-nio-8080-exec-6] org.camunda.commons.logging.BaseLogger.logError ENGINE-16004 Exception while closing command co
ntext: Exception while evaluating decision with key ‘null’
org.camunda.bpm.engine.ProcessEngineException: Exception while evaluating decision with key ‘null’
at org.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionCmd.doEvaluateDecision(EvaluateDecisionCmd.java:73)
at org.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionCmd.execute(EvaluateDecisionCmd.java:64)
at org.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionCmd.execute(EvaluateDecisionCmd.java:36)
at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:104)
at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:66)
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.camunda.bpm.engine.impl.dmn.DecisionEvaluationBuilderImpl.evaluate(DecisionEvaluationBuilderImpl.java:79)
at org.camunda.bpm.engine.rest.sub.repository.impl.DecisionDefinitionResourceImpl.evaluateDecision(DecisionDefinitionResourceImpl.java:134)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:140)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:103)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:377)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:200)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.camunda.bpm.engine.rest.filter.CacheControlFilter.doFilter(CacheControlFilter.java:41)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.camunda.bpm.engine.rest.filter.EmptyBodyFilter.doFilter(EmptyBodyFilter.java:95)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:409)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: org.camunda.bpm.dmn.feel.impl.juel.FeelMissingFunctionException: FEEL-01007 Unable to resolve function ‘number’ in expression ‘[1…number(Q
ID001)]’
at org.camunda.bpm.dmn.feel.impl.juel.FeelEngineLogger.unknownFunction(FeelEngineLogger.java:86)
at org.camunda.bpm.dmn.feel.impl.juel.FeelEngineImpl.evaluateSimpleUnaryTests(FeelEngineImpl.java:55)
at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateFeelSimpleUnaryTests(DecisionTableEvaluationHandler.java:
242)
at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateInputEntry(DecisionTableEvaluationHandler.java:199)
at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.isConditionApplicable(DecisionTableEvaluationHandler.java:141)
at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateInputForAvailableRules(DecisionTableEvaluationHandler.jav
a:133)
at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateDecisionTable(DecisionTableEvaluationHandler.java:107)
at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluate(DecisionTableEvaluationHandler.java:77)
at org.camunda.bpm.dmn.engine.impl.DefaultDmnDecisionContext.evaluateDecision(DefaultDmnDecisionContext.java:82)
at org.camunda.bpm.dmn.engine.impl.DefaultDmnEngine.evaluateDecision(DefaultDmnEngine.java:164)
at org.camunda.bpm.engine.impl.dmn.invocation.DecisionInvocation.invoke(DecisionInvocation.java:53)
at org.camunda.bpm.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:54)
at org.camunda.bpm.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocationInContext(DefaultDelegateInterceptor.java:87)
at org.camunda.bpm.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:59)
at org.camunda.bpm.engine.impl.util.DecisionEvaluationUtil.invoke(DecisionEvaluationUtil.java:94)
at org.camunda.bpm.engine.impl.util.DecisionEvaluationUtil.evaluateDecision(DecisionEvaluationUtil.java:83)
at org.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionCmd.doEvaluateDecision(EvaluateDecisionCmd.java:70)
… 52 more

I figured it out. I was missing a plugin in entry in the bpm-platform.xml

org.camunda.feel.CamundaFeelEnginePlugin

needed to be added and jar file added to server lib folder to make this work

1 Like