Search in sources :

Example 1 with DecisionServiceNodeImpl

use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.

the class DMNRuntimeImpl method evaluateDecisionService.

@Override
public DMNResult evaluateDecisionService(DMNModel model, DMNContext context, String decisionServiceName) {
    Objects.requireNonNull(model, () -> MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "model"));
    Objects.requireNonNull(context, () -> MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "context"));
    Objects.requireNonNull(decisionServiceName, () -> MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "decisionServiceName"));
    boolean typeCheck = performRuntimeTypeCheck(model);
    DMNResultImpl result = createResultImpl(model, context);
    // the engine should evaluate all belonging to the "local" model namespace, not imported nodes explicitly.
    Optional<DecisionServiceNode> lookupDS = ((DMNModelImpl) model).getDecisionServices().stream().filter(d -> d.getModelNamespace().equals(model.getNamespace())).filter(ds -> ds.getName().equals(decisionServiceName)).findFirst();
    if (lookupDS.isPresent()) {
        DecisionServiceNodeImpl decisionService = (DecisionServiceNodeImpl) lookupDS.get();
        for (DMNNode dep : decisionService.getInputParameters().values()) {
            if (!isNodeValueDefined(result, decisionService, dep)) {
                DMNMessage message = MsgUtil.reportMessage(logger, DMNMessage.Severity.WARN, decisionService.getSource(), result, null, null, Msg.REQ_INPUT_NOT_FOUND_FOR_DS, getDependencyIdentifier(decisionService, dep), getIdentifier(decisionService));
                final boolean walkingIntoScope = walkIntoImportScope(result, decisionService, dep);
                result.getContext().set(dep.getName(), null);
                if (walkingIntoScope) {
                    result.getContext().popScope();
                }
            } else {
                final boolean walkingIntoScope = walkIntoImportScope(result, decisionService, dep);
                final Object originalValue = result.getContext().get(dep.getName());
                DMNType depType = ((DMNModelImpl) model).getTypeRegistry().unknown();
                if (dep instanceof InputDataNode) {
                    depType = ((InputDataNode) dep).getType();
                } else if (dep instanceof DecisionNode) {
                    depType = ((DecisionNode) dep).getResultType();
                }
                Object c = coerceUsingType(originalValue, depType, typeCheck, (r, t) -> MsgUtil.reportMessage(logger, DMNMessage.Severity.WARN, decisionService.getDecisionService(), result, null, null, Msg.PARAMETER_TYPE_MISMATCH_DS, dep.getName(), t, MsgUtil.clipString(r.toString(), 50)));
                if (c != originalValue) {
                    // intentional by-reference
                    result.getContext().set(dep.getName(), c);
                }
                if (walkingIntoScope) {
                    result.getContext().popScope();
                }
            }
        }
        // please note singleton output coercion does not influence anyway when invoked DS on a model.
        EvaluatorResult evaluate = new DMNDecisionServiceEvaluator(decisionService, true, false).evaluate(this, result);
    } else {
        MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, null, result, null, null, Msg.DECISION_SERVICE_NOT_FOUND_FOR_NAME, decisionServiceName);
    }
    return result;
}
Also used : MsgUtil(org.kie.dmn.core.util.MsgUtil) DMNType(org.kie.dmn.api.core.DMNType) DMNMessage(org.kie.dmn.api.core.DMNMessage) DMNResult(org.kie.dmn.api.core.DMNResult) LoggerFactory(org.slf4j.LoggerFactory) DMNDecisionServiceEvaluator(org.kie.dmn.core.ast.DMNDecisionServiceEvaluator) DMNOption(org.kie.dmn.core.compiler.DMNOption) EVALUATING(org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.EVALUATING) DecisionServiceNodeImpl(org.kie.dmn.core.ast.DecisionServiceNodeImpl) KieRuntimeFactory(org.kie.api.runtime.KieRuntimeFactory) DMNModel(org.kie.dmn.api.core.DMNModel) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) FEELFunction(org.kie.dmn.feel.runtime.FEELFunction) DMNBaseNode(org.kie.dmn.core.ast.DMNBaseNode) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) EvaluatorResult(org.kie.dmn.core.api.EvaluatorResult) DMNRuntime(org.kie.dmn.api.core.DMNRuntime) InputDataNodeImpl(org.kie.dmn.core.ast.InputDataNodeImpl) DMNProfile(org.kie.dmn.core.compiler.DMNProfile) InternalKnowledgeBase(org.drools.kiesession.rulebase.InternalKnowledgeBase) BeforeEvaluateDecisionEvent(org.kie.dmn.api.core.event.BeforeEvaluateDecisionEvent) DMNRuntimeEventListener(org.kie.dmn.api.core.event.DMNRuntimeEventListener) DMNFactory(org.kie.dmn.core.api.DMNFactory) Logger(org.slf4j.Logger) DMNNode(org.kie.dmn.api.core.ast.DMNNode) BusinessKnowledgeModelNodeImpl(org.kie.dmn.core.ast.BusinessKnowledgeModelNodeImpl) DMNFunctionWithReturnType(org.kie.dmn.core.ast.DMNFunctionWithReturnType) SKIPPED(org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.SKIPPED) Collection(java.util.Collection) Set(java.util.Set) FAILED(org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.FAILED) Collectors(java.util.stream.Collectors) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) RuntimeTypeCheckOption(org.kie.dmn.core.compiler.RuntimeTypeCheckOption) Objects(java.util.Objects) List(java.util.List) DMNContext(org.kie.dmn.api.core.DMNContext) Optional(java.util.Optional) DecisionServiceNode(org.kie.dmn.api.core.ast.DecisionServiceNode) InputDataNode(org.kie.dmn.api.core.ast.InputDataNode) QName(javax.xml.namespace.QName) Msg(org.kie.dmn.core.util.Msg) DMNDecisionResult(org.kie.dmn.api.core.DMNDecisionResult) DecisionNodeImpl(org.kie.dmn.core.ast.DecisionNodeImpl) EvaluatorResult(org.kie.dmn.core.api.EvaluatorResult) DecisionServiceNode(org.kie.dmn.api.core.ast.DecisionServiceNode) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) DMNDecisionServiceEvaluator(org.kie.dmn.core.ast.DMNDecisionServiceEvaluator) DMNMessage(org.kie.dmn.api.core.DMNMessage) DMNNode(org.kie.dmn.api.core.ast.DMNNode) InputDataNode(org.kie.dmn.api.core.ast.InputDataNode) DecisionServiceNodeImpl(org.kie.dmn.core.ast.DecisionServiceNodeImpl) DMNType(org.kie.dmn.api.core.DMNType)

Example 2 with DecisionServiceNodeImpl

use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.

the class DynamicDMNContextBuilder method populateContextForDecisionServiceWith.

public DMNContext populateContextForDecisionServiceWith(String decisionServiceName, Map<String, Object> json) {
    DecisionServiceNode dsNode = model.getDecisionServices().stream().filter(ds -> ds.getName().equals(decisionServiceName)).findFirst().orElseThrow(IllegalArgumentException::new);
    for (Entry<String, Object> kv : json.entrySet()) {
        DecisionServiceNodeImpl dsNodeImpl = (DecisionServiceNodeImpl) dsNode;
        DMNNode node = dsNodeImpl.getInputParameters().get(kv.getKey());
        if (node instanceof InputDataNode) {
            processInputDataNode(kv, (InputDataNode) node);
        } else if (node instanceof DecisionNode) {
            processDecisionNode(kv, (DecisionNode) node);
        } else {
            LOG.debug("The key {} was not a RequiredInput nor a RequiredDecision for the DecisionService, setting it as-is.", kv.getKey());
            context.set(kv.getKey(), kv.getValue());
        }
    }
    return context;
}
Also used : DecisionServiceNode(org.kie.dmn.api.core.ast.DecisionServiceNode) DMNNode(org.kie.dmn.api.core.ast.DMNNode) InputDataNode(org.kie.dmn.api.core.ast.InputDataNode) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) DecisionServiceNodeImpl(org.kie.dmn.core.ast.DecisionServiceNodeImpl)

Example 3 with DecisionServiceNodeImpl

use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.

the class DecisionServiceCompiler method compileEvaluator.

@Override
public void compileEvaluator(DMNNode node, DMNCompilerImpl compiler, DMNCompilerContext ctx, DMNModelImpl model) {
    DecisionServiceNodeImpl ni = (DecisionServiceNodeImpl) node;
    List<DSFormalParameter> parameters = new ArrayList<>();
    for (DMNElementReference er : ni.getDecisionService().getInputData()) {
        String id = DMNCompilerImpl.getId(er);
        InputDataNode input = model.getInputById(id);
        String inputNamePrefix = inputQualifiedNamePrefix(input, model);
        if (input != null) {
            ni.addInputParameter(inputNamePrefix != null ? inputNamePrefix + "." + input.getName() : input.getName(), input);
            parameters.add(new DSFormalParameter(inputNamePrefix, input.getName(), input.getType()));
        } else {
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.REFERENCE_NOT_FOUND_FOR_DS, id, node.getName());
        }
    }
    for (DMNElementReference er : ni.getDecisionService().getInputDecision()) {
        String id = DMNCompilerImpl.getId(er);
        DecisionNode input = model.getDecisionById(id);
        String inputNamePrefix = inputQualifiedNamePrefix(input, model);
        if (input != null) {
            ni.addInputParameter(inputNamePrefix != null ? inputNamePrefix + "." + input.getName() : input.getName(), input);
            parameters.add(new DSFormalParameter(inputNamePrefix, input.getName(), input.getResultType()));
        } else {
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.REFERENCE_NOT_FOUND_FOR_DS, id, node.getName());
        }
    }
    for (DMNElementReference er : ni.getDecisionService().getEncapsulatedDecision()) {
        String id = DMNCompilerImpl.getId(er);
        DecisionNode input = model.getDecisionById(id);
        if (input != null) {
        // nothing to do.
        } else {
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.REFERENCE_NOT_FOUND_FOR_DS, id, node.getName());
        }
    }
    List<DecisionNode> outputDecisions = new ArrayList<>();
    for (DMNElementReference er : ni.getDecisionService().getOutputDecision()) {
        String id = DMNCompilerImpl.getId(er);
        DecisionNode outDecision = model.getDecisionById(id);
        if (outDecision != null) {
            outputDecisions.add(outDecision);
        } else {
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.REFERENCE_NOT_FOUND_FOR_DS, id, node.getName());
        }
    }
    boolean coerceSingleton = ((DMNCompilerConfigurationImpl) compiler.getDmnCompilerConfig()).getOption(CoerceDecisionServiceSingletonOutputOption.class).isCoerceSingleton();
    DMNDecisionServiceFunctionDefinitionEvaluator exprEvaluator = new DMNDecisionServiceFunctionDefinitionEvaluator(ni, parameters, coerceSingleton);
    ni.setEvaluator(exprEvaluator);
    if (ni.getType() != null) {
        checkFnConsistency(model, ni, ni.getType(), outputDecisions);
    }
}
Also used : DMNElementReference(org.kie.dmn.model.api.DMNElementReference) DSFormalParameter(org.kie.dmn.core.ast.DMNDecisionServiceFunctionDefinitionEvaluator.DSFormalParameter) ArrayList(java.util.ArrayList) InputDataNode(org.kie.dmn.api.core.ast.InputDataNode) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) DMNDecisionServiceFunctionDefinitionEvaluator(org.kie.dmn.core.ast.DMNDecisionServiceFunctionDefinitionEvaluator) DecisionServiceNodeImpl(org.kie.dmn.core.ast.DecisionServiceNodeImpl)

Example 4 with DecisionServiceNodeImpl

use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.

the class DecisionServiceCompiler method checkFnConsistency.

private void checkFnConsistency(DMNModelImpl model, DecisionServiceNodeImpl ni, DMNType type, List<DecisionNode> outputDecisions) {
    SimpleFnTypeImpl fnType = ((SimpleFnTypeImpl) type);
    FunctionItem fi = fnType.getFunctionItem();
    if (fi.getParameters().size() != ni.getInputParameters().size()) {
        MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.PARAMETER_COUNT_MISMATCH_COMPILING, ni.getName(), fi.getParameters().size(), ni.getInputParameters().size());
        return;
    }
    for (int i = 0; i < fi.getParameters().size(); i++) {
        InformationItem fiII = fi.getParameters().get(i);
        String fpName = ni.getInputParameters().keySet().stream().skip(i).findFirst().orElse(null);
        if (!fiII.getName().equals(fpName)) {
            List<String> fiParamNames = fi.getParameters().stream().map(InformationItem::getName).collect(Collectors.toList());
            List<String> funcDefParamNames = ni.getInputParameters().keySet().stream().collect(Collectors.toList());
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.PARAMETER_NAMES_MISMATCH_COMPILING, ni.getName(), fiParamNames, funcDefParamNames);
            return;
        }
        QName fiQname = fiII.getTypeRef();
        QName fdQname = null;
        DMNNode fpDMNNode = ni.getInputParameters().get(fpName);
        if (fpDMNNode instanceof InputDataNodeImpl) {
            fdQname = ((InputDataNodeImpl) fpDMNNode).getInputData().getVariable().getTypeRef();
        } else if (fpDMNNode instanceof DecisionNodeImpl) {
            fdQname = ((DecisionNodeImpl) fpDMNNode).getDecision().getVariable().getTypeRef();
        }
        if (fiQname != null && fdQname != null && !fiQname.equals(fdQname)) {
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.PARAMETER_TYPEREF_MISMATCH_COMPILING, ni.getName(), fiII.getName(), fiQname, fdQname);
        }
    }
    QName fiReturnType = fi.getOutputTypeRef();
    if (ni.getDecisionService().getOutputDecision().size() == 1) {
        QName fdReturnType = outputDecisions.get(0).getDecision().getVariable().getTypeRef();
        if (fiReturnType != null && fdReturnType != null && !fiReturnType.equals(fdReturnType)) {
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING, ni.getName(), fiReturnType, fdReturnType);
        }
    } else if (ni.getDecisionService().getOutputDecision().size() > 1) {
        final Function<QName, QName> lookupFn = (in) -> DMNCompilerImpl.getNamespaceAndName(ni.getDecisionService(), model.getImportAliasesForNS(), in, model.getNamespace());
        LinkedHashMap<String, QName> fdComposite = new LinkedHashMap<>();
        for (DecisionNode dn : outputDecisions) {
            fdComposite.put(dn.getName(), lookupFn.apply(dn.getDecision().getVariable().getTypeRef()));
        }
        final QName lookup = lookupFn.apply(fiReturnType);
        Optional<ItemDefNodeImpl> composite = model.getItemDefinitions().stream().filter(id -> id.getModelNamespace().equals(lookup.getNamespaceURI()) && id.getName().equals(lookup.getLocalPart())).map(ItemDefNodeImpl.class::cast).findFirst();
        if (!composite.isPresent()) {
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING, ni.getName(), lookup, fdComposite);
            return;
        }
        LinkedHashMap<String, QName> fiComposite = new LinkedHashMap<>();
        for (ItemDefinition ic : composite.get().getItemDef().getItemComponent()) {
            fiComposite.put(ic.getName(), lookupFn.apply(ic.getTypeRef()));
        }
        if (!fiComposite.equals(fdComposite)) {
            MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING, ni.getName(), fiComposite, fdComposite);
        }
    }
}
Also used : MsgUtil(org.kie.dmn.core.util.MsgUtil) DMNType(org.kie.dmn.api.core.DMNType) DMNElementReference(org.kie.dmn.model.api.DMNElementReference) DMNMessage(org.kie.dmn.api.core.DMNMessage) SimpleFnTypeImpl(org.kie.dmn.core.impl.SimpleFnTypeImpl) LoggerFactory(org.slf4j.LoggerFactory) ItemDefNodeImpl(org.kie.dmn.core.ast.ItemDefNodeImpl) Function(java.util.function.Function) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) DecisionServiceNodeImpl(org.kie.dmn.core.ast.DecisionServiceNodeImpl) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) DMNDecisionServiceFunctionDefinitionEvaluator(org.kie.dmn.core.ast.DMNDecisionServiceFunctionDefinitionEvaluator) DMNBaseNode(org.kie.dmn.core.ast.DMNBaseNode) InputDataNodeImpl(org.kie.dmn.core.ast.InputDataNodeImpl) Logger(org.slf4j.Logger) DMNNode(org.kie.dmn.api.core.ast.DMNNode) DMNModelImpl(org.kie.dmn.core.impl.DMNModelImpl) Collectors(java.util.stream.Collectors) FunctionItem(org.kie.dmn.model.api.FunctionItem) List(java.util.List) DSFormalParameter(org.kie.dmn.core.ast.DMNDecisionServiceFunctionDefinitionEvaluator.DSFormalParameter) ItemDefinition(org.kie.dmn.model.api.ItemDefinition) Optional(java.util.Optional) InputDataNode(org.kie.dmn.api.core.ast.InputDataNode) QName(javax.xml.namespace.QName) DRGElement(org.kie.dmn.model.api.DRGElement) InformationItem(org.kie.dmn.model.api.InformationItem) Msg(org.kie.dmn.core.util.Msg) DecisionService(org.kie.dmn.model.api.DecisionService) DecisionNodeImpl(org.kie.dmn.core.ast.DecisionNodeImpl) Optional(java.util.Optional) QName(javax.xml.namespace.QName) ItemDefinition(org.kie.dmn.model.api.ItemDefinition) InformationItem(org.kie.dmn.model.api.InformationItem) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) DecisionNodeImpl(org.kie.dmn.core.ast.DecisionNodeImpl) SimpleFnTypeImpl(org.kie.dmn.core.impl.SimpleFnTypeImpl) LinkedHashMap(java.util.LinkedHashMap) Function(java.util.function.Function) DMNNode(org.kie.dmn.api.core.ast.DMNNode) FunctionItem(org.kie.dmn.model.api.FunctionItem) InputDataNodeImpl(org.kie.dmn.core.ast.InputDataNodeImpl) ItemDefNodeImpl(org.kie.dmn.core.ast.ItemDefNodeImpl)

Example 5 with DecisionServiceNodeImpl

use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.

the class DecisionServiceCompiler method compileNode.

/**
 * backport of DMN v1.1
 */
public void compileNode(DecisionService ds, DMNCompilerImpl compiler, DMNModelImpl model) {
    DMNType type = null;
    DMNType fnType = null;
    if (ds.getVariable() == null) {
        // even for the v1.1 backport, variable creation is taken care in DMNCompiler.
        DMNCompilerHelper.reportMissingVariable(model, ds, ds, Msg.MISSING_VARIABLE_FOR_DS);
        return;
    }
    DMNCompilerHelper.checkVariableName(model, ds, ds.getName());
    if (ds.getVariable() != null && ds.getVariable().getTypeRef() != null) {
        type = compiler.resolveTypeRef(model, ds, ds.getVariable(), ds.getVariable().getTypeRef());
        if (type instanceof SimpleFnTypeImpl) {
            fnType = type;
            type = ((SimpleFnTypeImpl) type).getReturnType();
        }
    } else {
        // for now the call bellow will return type UNKNOWN
        type = compiler.resolveTypeRef(model, ds, ds, null);
    }
    DecisionServiceNodeImpl bkmn = new DecisionServiceNodeImpl(ds, fnType, type);
    model.addDecisionService(bkmn);
}
Also used : SimpleFnTypeImpl(org.kie.dmn.core.impl.SimpleFnTypeImpl) DMNType(org.kie.dmn.api.core.DMNType) DecisionServiceNodeImpl(org.kie.dmn.core.ast.DecisionServiceNodeImpl)

Aggregations

DecisionServiceNodeImpl (org.kie.dmn.core.ast.DecisionServiceNodeImpl)8 DecisionNode (org.kie.dmn.api.core.ast.DecisionNode)5 DMNNode (org.kie.dmn.api.core.ast.DMNNode)4 InputDataNode (org.kie.dmn.api.core.ast.InputDataNode)4 DMNType (org.kie.dmn.api.core.DMNType)3 DecisionServiceNode (org.kie.dmn.api.core.ast.DecisionServiceNode)3 DecisionNodeImpl (org.kie.dmn.core.ast.DecisionNodeImpl)3 ArrayList (java.util.ArrayList)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 Optional (java.util.Optional)2 Collectors (java.util.stream.Collectors)2 QName (javax.xml.namespace.QName)2 DMNMessage (org.kie.dmn.api.core.DMNMessage)2 BusinessKnowledgeModelNode (org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode)2 BusinessKnowledgeModelNodeImpl (org.kie.dmn.core.ast.BusinessKnowledgeModelNodeImpl)2 DMNBaseNode (org.kie.dmn.core.ast.DMNBaseNode)2 DMNDecisionServiceFunctionDefinitionEvaluator (org.kie.dmn.core.ast.DMNDecisionServiceFunctionDefinitionEvaluator)2 DSFormalParameter (org.kie.dmn.core.ast.DMNDecisionServiceFunctionDefinitionEvaluator.DSFormalParameter)2 InputDataNodeImpl (org.kie.dmn.core.ast.InputDataNodeImpl)2