Skip to content

Commit 9ac80d0

Browse files
committed
Merge branch '71-from-poc' into 71-poc
2 parents caf6088 + 67853b6 commit 9ac80d0

File tree

12 files changed

+293
-192
lines changed

12 files changed

+293
-192
lines changed

api-check-ignore.xml

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@
1111
<!-- num method params -->
1212
<differenceType>7004</differenceType>
1313
<method>*$anonfun*</method>
14-
<from>*</from>
1514
<to>*</to>
1615
</difference>
1716
<difference>
1817
<className>org/camunda/dmn/**</className>
1918
<!-- method param type -->
2019
<differenceType>7005</differenceType>
2120
<method>*$anonfun*</method>
22-
<!--don't care what the type has changed to-->
23-
<from>*</from>
2421
<to>*</to>
2522
</difference>
2623
<difference>
@@ -43,4 +40,39 @@
4340
<differenceType>7002</differenceType>
4441
<method>*</method>
4542
</difference>
43+
<!-- changes from 1.8.1 to 1.9 -->
44+
<difference>
45+
<className>org/camunda/dmn/DmnEngine</className>
46+
<differenceType>7004</differenceType>
47+
<method>DmnEngine(*</method>
48+
</difference>
49+
<difference>
50+
<className>org/camunda/dmn/parser/DmnParser</className>
51+
<differenceType>7004</differenceType>
52+
<method>DmnParser(*</method>
53+
</difference>
54+
<difference>
55+
<className>org/camunda/dmn/parser/ParsedDmn</className>
56+
<differenceType>7004</differenceType>
57+
<method>*</method>
58+
</difference>
59+
<difference>
60+
<className>org/camunda/dmn/parser/ParsedBusinessKnowledgeModel</className>
61+
<differenceType>2000</differenceType>
62+
</difference>
63+
<difference>
64+
<className>org/camunda/dmn/parser/ParsedBusinessKnowledgeModel</className>
65+
<differenceType>4001</differenceType>
66+
<to>**</to>
67+
</difference>
68+
<difference>
69+
<className>org/camunda/dmn/parser/ParsedDecision</className>
70+
<differenceType>2000</differenceType>
71+
</difference>
72+
<difference>
73+
<className>org/camunda/dmn/parser/ParsedDecision</className>
74+
<differenceType>4001</differenceType>
75+
<to>**</to>
76+
</difference>
77+
<!-- END changes from 1.8.1 to 1.9 -->
4678
</differences>

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<groupId>org.camunda.bpm.extension.dmn.scala</groupId>
66
<artifactId>dmn-engine</artifactId>
77
<name>DMN Scala Engine</name>
8-
<version>1.8.2-SNAPSHOT</version>
8+
<version>1.9.0-SNAPSHOT</version>
99

1010
<parent>
1111
<groupId>org.camunda</groupId>
@@ -15,7 +15,7 @@
1515
</parent>
1616

1717
<properties>
18-
<feel.version>1.16.0</feel.version>
18+
<feel.version>1.16.1</feel.version>
1919
<camunda-model-api.version>7.19.0</camunda-model-api.version>
2020
<version.java>11</version.java>
2121
<scala.version>2.13.11</scala.version>

src/main/scala/org/camunda/dmn/DmnEngine.scala

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,19 +156,20 @@ class DmnEngine(configuration: DmnEngine.Configuration =
156156
val parser = new DmnParser(
157157
configuration = configuration,
158158
feelParser = feelEngine.parseExpression(_).left.map(_.message),
159-
feelUnaryTestsParser = feelEngine.parseUnaryTests(_).left.map(_.message),
160-
dmnRepository = dmnRepository
161-
)
159+
feelUnaryTestsParser = feelEngine.parseUnaryTests(_).left.map(_.message))
162160

163-
val decisionEval = new DecisionEvaluator(eval = this.evalExpression,
164-
evalBkm = bkmEval.createFunction)
161+
val decisionEval = new DecisionEvaluator(
162+
eval = this.evalExpression,
163+
evalBkm = bkmEval.createFunction,
164+
repository = dmnRepository
165+
)
165166

166167
val literalExpressionEval = new LiteralExpressionEvaluator(feelEngine)
167168

168169
val decisionTableEval = new DecisionTableEvaluator(
169170
literalExpressionEval.evalExpression)
170171

171-
val bkmEval = new BusinessKnowledgeEvaluator(this.evalExpression, valueMapper)
172+
val bkmEval = new BusinessKnowledgeEvaluator(this.evalExpression, valueMapper, dmnRepository)
172173

173174
val contextEval = new ContextEvaluator(this.evalExpression)
174175

@@ -178,7 +179,9 @@ class DmnEngine(configuration: DmnEngine.Configuration =
178179

179180
val invocationEval = new InvocationEvaluator(
180181
eval = literalExpressionEval.evalExpression,
181-
evalBkm = bkmEval.eval)
182+
evalBkm = bkmEval.eval,
183+
repository = dmnRepository
184+
)
182185

183186
val functionDefinitionEval = new FunctionDefinitionEvaluator(
184187
literalExpressionEval.evalExpression)

src/main/scala/org/camunda/dmn/evaluation/BusinessKnowledgeEvaluator.scala

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,20 @@ package org.camunda.dmn.evaluation
1717

1818
import org.camunda.dmn.DmnEngine._
1919
import org.camunda.dmn.FunctionalHelper._
20-
import org.camunda.dmn.parser.{
21-
ParsedBusinessKnowledgeModel,
22-
ParsedDecisionLogic
23-
}
20+
import org.camunda.dmn.parser.{DmnRepository, EmbeddedBusinessKnowledgeModel, ExpressionFailure, ImportedBusinessKnowledgeModel, ParsedBusinessKnowledgeModel, ParsedBusinessKnowledgeModelFailure, ParsedBusinessKnowledgeModelReference, ParsedDecisionLogic}
2421
import org.camunda.feel.syntaxtree.{Val, ValError, ValFunction}
2522
import org.camunda.feel.valuemapper.ValueMapper
2623

2724
class BusinessKnowledgeEvaluator(
2825
eval: (ParsedDecisionLogic, EvalContext) => Either[Failure, Val],
29-
valueMapper: ValueMapper) {
26+
valueMapper: ValueMapper,
27+
repository: DmnRepository) {
3028

3129
def eval(bkm: ParsedBusinessKnowledgeModel,
3230
context: EvalContext): Either[Failure, Val] = {
3331

34-
evalRequiredKnowledge(bkm.requiredBkms, context)
32+
resolveRequiredBkms(bkm)
33+
.flatMap(evalRequiredKnowledge(_, context))
3534
.flatMap(functions => {
3635

3736
val evalContext =
@@ -43,11 +42,21 @@ class BusinessKnowledgeEvaluator(
4342
})
4443
}
4544

45+
private def resolveRequiredBkms(bkm: ParsedBusinessKnowledgeModel): Either[Failure, Iterable[ParsedBusinessKnowledgeModel]] = {
46+
mapEither[ParsedBusinessKnowledgeModelReference, ParsedBusinessKnowledgeModel](bkm.requiredBkms, {
47+
case ImportedBusinessKnowledgeModel(namespace, id, _) => repository.getBusinessKnowledgeModel(namespace = namespace, bkmId = id)
48+
case ParsedBusinessKnowledgeModelFailure(_, _, failureMessage) => Left(Failure(failureMessage))
49+
case bkm: EmbeddedBusinessKnowledgeModel => Right(bkm)
50+
})
51+
}
52+
4653
def createFunction(
4754
bkm: ParsedBusinessKnowledgeModel,
4855
context: EvalContext): Either[Failure, (String, ValFunction)] = {
4956

50-
evalRequiredKnowledge(bkm.requiredBkms, context).map(functions => {
57+
resolveRequiredBkms(bkm)
58+
.flatMap(evalRequiredKnowledge(_, context))
59+
.map(functions => {
5160

5261
val evalContext = context.copy(variables = context.variables ++ functions,
5362
currentElement = bkm)

src/main/scala/org/camunda/dmn/evaluation/DecisionEvaluator.scala

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ package org.camunda.dmn.evaluation
1818
import org.camunda.dmn.DmnEngine._
1919
import org.camunda.dmn.FunctionalHelper._
2020
import org.camunda.feel.syntaxtree.{Val, ValContext, ValFunction}
21-
import org.camunda.dmn.parser.{ParsedBusinessKnowledgeModel, ParsedDecision, ParsedDecisionLogic}
21+
import org.camunda.dmn.parser.{DmnRepository, EmbeddedBusinessKnowledgeModel, EmbeddedDecision, ImportedBusinessKnowledgeModel, ImportedDecision, ParsedBusinessKnowledgeModel, ParsedBusinessKnowledgeModelFailure, ParsedBusinessKnowledgeModelReference, ParsedDecision, ParsedDecisionFailure, ParsedDecisionLogic, ParsedDecisionReference}
2222
import org.camunda.feel.context.Context.StaticContext
2323

2424
class DecisionEvaluator(
2525
eval: (ParsedDecisionLogic, EvalContext) => Either[Failure, Val],
2626
evalBkm: (ParsedBusinessKnowledgeModel,
27-
EvalContext) => Either[Failure, (String, ValFunction)]) {
27+
EvalContext) => Either[Failure, (String, ValFunction)],
28+
repository: DmnRepository) {
2829

2930
def eval(decision: ParsedDecision,
3031
context: EvalContext): Either[Failure, Val] = {
@@ -42,38 +43,10 @@ class DecisionEvaluator(
4243
evalRequiredKnowledge(decision.requiredBkms, context)
4344
.flatMap(functions => {
4445

45-
val isImported: ((String, Val)) => Boolean = {
46-
case (name, _) => name.contains(".")
47-
}
48-
49-
// todo: replace the hack to wrap the imported BKMs and decisions into a context, maybe move to the BKM evaluation logic
50-
val importedFunctions = functions
51-
.filter(isImported)
52-
.map { case (name, function) =>
53-
val Array(prefix: String, functionName: String) = name.split('.')
54-
prefix -> ValContext(StaticContext(
55-
variables = Map.empty,
56-
functions = Map(functionName -> List(function))
57-
))
58-
}
59-
val embeddedFunctions = functions.filterNot(isImported)
60-
61-
val importedDecisions = decisionResults
62-
.filter(isImported)
63-
.map { case (name, decisionResult) =>
64-
val Array(prefix: String, decisionName: String) = name.split('.')
65-
prefix -> ValContext(StaticContext(
66-
variables = Map(decisionName -> decisionResult),
67-
functions = Map.empty
68-
))
69-
}
70-
val embeddedDecisions = decisionResults.filterNot(isImported)
71-
7246
val decisionEvaluationContext = context.copy(
7347
variables = context.variables
74-
++ embeddedDecisions ++ importedDecisions
75-
++ embeddedFunctions ++ importedFunctions,
76-
currentElement = decision)
48+
++ decisionResults ++ functions,
49+
currentElement = decision)
7750

7851
eval(decision.logic, decisionEvaluationContext)
7952
.flatMap(
@@ -87,17 +60,45 @@ class DecisionEvaluator(
8760
}
8861

8962
private def evalRequiredDecisions(
90-
requiredDecisions: Iterable[ParsedDecision],
91-
context: EvalContext): Either[Failure, List[(String, Val)]] = {
92-
mapEither(requiredDecisions,
93-
(d: ParsedDecision) => evalDecision(d, context))
63+
requiredDecisions: Iterable[ParsedDecisionReference],
64+
context: EvalContext): Either[Failure, List[(String, Val)]] = {
65+
mapEither[ParsedDecisionReference, (String, Val)](requiredDecisions, {
66+
case ImportedDecision(namespace, decisionId, importName) =>
67+
repository.getDecision(namespace = namespace, decisionId = decisionId)
68+
.flatMap(evalDecision(_, context))
69+
.map { case (name, result) =>
70+
importName -> ValContext(StaticContext(
71+
variables = Map(name -> result),
72+
functions = Map.empty
73+
))
74+
}
75+
76+
case ParsedDecisionFailure(_, _, failureMessage) => Left(Failure(failureMessage))
77+
case decision: EmbeddedDecision => evalDecision(decision, context)
78+
}
79+
)
9480
}
9581

9682
private def evalRequiredKnowledge(
97-
requiredBkms: Iterable[ParsedBusinessKnowledgeModel],
98-
context: EvalContext): Either[Failure, List[(String, ValFunction)]] = {
99-
mapEither(requiredBkms,
100-
(bkm: ParsedBusinessKnowledgeModel) => evalBkm(bkm, context))
83+
requiredBkms: Iterable[ParsedBusinessKnowledgeModelReference],
84+
context: EvalContext): Either[Failure, List[(String, Val)]] = {
85+
mapEither[ParsedBusinessKnowledgeModelReference, (String, Val)](requiredBkms, {
86+
case ImportedBusinessKnowledgeModel(namespace, id, importName) =>
87+
repository.getBusinessKnowledgeModel(namespace = namespace, bkmId = id)
88+
.flatMap(evalBkm(_, context))
89+
.map { case (name, resultFunction) =>
90+
importName -> ValContext(
91+
StaticContext(
92+
variables = Map.empty,
93+
functions = Map(name -> List(resultFunction))
94+
)
95+
)
96+
}
97+
98+
case ParsedBusinessKnowledgeModelFailure(_, _, failureMessage) => Left(Failure(failureMessage))
99+
case bkm: EmbeddedBusinessKnowledgeModel => evalBkm(bkm, context)
100+
}
101+
)
101102
}
102103

103104
}

src/main/scala/org/camunda/dmn/evaluation/InvocationEvaluator.scala

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,35 @@ package org.camunda.dmn.evaluation
1717

1818
import org.camunda.dmn.DmnEngine._
1919
import org.camunda.dmn.FunctionalHelper._
20-
import org.camunda.dmn.parser.{
21-
ParsedBusinessKnowledgeModel,
22-
ParsedExpression,
23-
ParsedInvocation
24-
}
20+
import org.camunda.dmn.parser.{DmnRepository, EmbeddedBusinessKnowledgeModel, ImportedBusinessKnowledgeModel, ParsedBusinessKnowledgeModel, ParsedBusinessKnowledgeModelFailure, ParsedBusinessKnowledgeModelReference, ParsedExpression, ParsedInvocation}
2521
import org.camunda.feel.syntaxtree.Val
2622

2723
class InvocationEvaluator(
2824
eval: (ParsedExpression, EvalContext) => Either[Failure, Val],
29-
evalBkm: (ParsedBusinessKnowledgeModel, EvalContext) => Either[Failure, Val]) {
25+
evalBkm: (ParsedBusinessKnowledgeModel, EvalContext) => Either[Failure, Val],
26+
repository: DmnRepository) {
3027

3128
def eval(invocation: ParsedInvocation,
3229
context: EvalContext): Either[Failure, Val] = {
3330

3431
val result = evalParameters(invocation.bindings, context).flatMap { p =>
3532
val ctx = context.copy(variables = context.variables ++ p.toMap)
36-
evalBkm(invocation.invocation, ctx)
33+
34+
resolveBkm(invocation.invocation).flatMap(evalBkm(_, ctx))
3735
}
3836

3937
context.audit(invocation, result)
4038
result
4139
}
4240

41+
private def resolveBkm(bkmRef: ParsedBusinessKnowledgeModelReference): Either[Failure, ParsedBusinessKnowledgeModel] = {
42+
bkmRef match {
43+
case ImportedBusinessKnowledgeModel(namespace, id, _) => repository.getBusinessKnowledgeModel(namespace = namespace, bkmId = id)
44+
case ParsedBusinessKnowledgeModelFailure(_, _, failureMessage) => Left(Failure(failureMessage))
45+
case bkm: EmbeddedBusinessKnowledgeModel => Right(bkm)
46+
}
47+
}
48+
4349
private def evalParameters(
4450
bindings: Iterable[(String, ParsedExpression)],
4551
context: EvalContext): Either[Failure, List[(String, Any)]] = {

0 commit comments

Comments
 (0)