Search in sources :

Example 1 with ProcessValidationError

use of org.jbpm.process.core.validation.ProcessValidationError in project kie-wb-common by kiegroup.

the class BpmnFileIndexer method fillIndexBuilder.

/* (non-Javadoc)
     * @see org.kie.workbench.common.services.refactoring.backend.server.indexing.AbstractFileIndexer#fillIndexBuilder(org.uberfire.java.nio.file.Path)
     */
@Override
protected DefaultIndexBuilder fillIndexBuilder(Path path) throws Exception {
    final KieModule module = moduleService.resolveModule(Paths.convert(path));
    if (module == null) {
        logger.error("Unable to index " + path.toUri().toString() + ": module could not be resolved.");
        return null;
    }
    // responsible for basic index info: module name, branch, etc
    final DefaultIndexBuilder builder = getIndexBuilder(path, module);
    String bpmnStr = ioService.readAllString(path);
    ClassLoader moduleClassLoader = getModuleClassLoader(module);
    try {
        List<BpmnProcessDataEventListener> processDataList = buildProcessDefinition(bpmnStr, moduleClassLoader);
        if (processDataList != null) {
            for (BpmnProcessDataEventListener processData : processDataList) {
                addReferencedResourcesToIndexBuilder(builder, processData);
                builder.setPackageName(processData.getProcess().getPackageName());
            }
        }
    } catch (Exception e) {
        // log and ignore
        logger.info("Indexing hampered because BPMN2 compilation failed [" + path.toString() + "]: " + e.getMessage());
    }
    /**
     * IMPORTANT: sometimes the build of the BPMN2 might fail for minor reasons, including things like
     * a bad script in a script task
     *
     * When this happens, we (re)parse the process definition, but do not completely "build" it
     * (as in, what org.jbpm.compiler.ProcessBuilderImpl.buildProcess(Process, Resource) does).
     *
     * It *would* be more efficient to basically copy/paste the
     * jbpm-flow-builder org.jbpm.compiler.ProcessBuilderImpl.addProcessFromXml(Resource) logic here,
     * so that we do something like:
     *
     * 1. Use the XmlProcessReader to create a process
     * 2. *try* to build the rest of the process (and fail safely if not)
     * 3. do XmlProcessReader.getProcessBuildData().onBuildComplete(process)
     *    to complete collecting the information
     *
     * But... that's a high maintenance cost for this piece of software
     *
     * So until we can refactor the ProcessBuilderImpl logic (using functional logic for conditional handling?)
     * to be used here, let's keep it simple (as in, parsing the BPMN2 a second time when the build fails..)
     */
    // parse process definitions
    XmlProcessReader processReader = new XmlProcessReader(modules, moduleClassLoader);
    List<Process> processes = Collections.emptyList();
    try {
        processes = processReader.read(new StringReader(bpmnStr));
    } catch (Exception e) {
        logger.info("Unable to index because BPMN2 parsing failed [" + path.toString() + "]: " + e.getMessage());
    }
    // complete process definition processing
    if (processes != null) {
        for (Process process : processes) {
            Resource resource = new ReaderResource(new StringReader(bpmnStr));
            ProcessValidationError[] errors;
            ProcessValidator validator = ProcessValidatorRegistry.getInstance().getValidator(process, resource);
            errors = validator.validateProcess(process);
            if (errors.length > 0) {
                logger.error("Trying to finish indexing process '" + process.getId() + "/" + process.getName() + "' despite " + errors.length + " validation errors.");
            }
            processReader.getProcessBuildData().onBuildComplete(process);
            BpmnProcessDataEventListener helper = (BpmnProcessDataEventListener) process.getMetaData().get(BpmnProcessDataEventListener.NAME);
            addReferencedResourcesToIndexBuilder(builder, helper);
        }
    } else {
        logger.warn("No process was found in file: " + path.toUri());
    }
    return builder;
}
Also used : XmlProcessReader(org.jbpm.compiler.xml.XmlProcessReader) ReaderResource(org.drools.core.io.impl.ReaderResource) ByteArrayResource(org.drools.core.io.impl.ByteArrayResource) Resource(org.kie.api.io.Resource) Process(org.kie.api.definition.process.Process) DefaultIndexBuilder(org.kie.workbench.common.services.refactoring.backend.server.indexing.DefaultIndexBuilder) ReaderResource(org.drools.core.io.impl.ReaderResource) ProcessValidationError(org.jbpm.process.core.validation.ProcessValidationError) StringReader(java.io.StringReader) KieModule(org.kie.workbench.common.services.shared.project.KieModule) ProcessValidator(org.jbpm.process.core.validation.ProcessValidator)

Example 2 with ProcessValidationError

use of org.jbpm.process.core.validation.ProcessValidationError in project jbpm by kiegroup.

the class ProcessBuilderImpl method buildProcess.

public void buildProcess(final Process process, Resource resource) {
    if (resource != null) {
        ((org.jbpm.process.core.Process) process).setResource(resource);
    }
    boolean hasErrors = false;
    ProcessValidator validator = ProcessValidatorRegistry.getInstance().getValidator(process, resource);
    if (validator == null) {
        logger.warn("Could not find validator for process {}.", ((Process) process).getType());
        logger.warn("Continuing without validation of the process {} [{}]", process.getName(), process.getId());
    } else {
        ProcessValidationError[] errors = validator.validateProcess((WorkflowProcess) process);
        if (errors.length != 0) {
            hasErrors = true;
            for (int i = 0; i < errors.length; i++) {
                this.errors.add(new ParserError(resource, errors[i].toString(), -1, -1));
            }
        }
    }
    if (!hasErrors) {
        // generate and add rule for process
        String rules = "package " + process.getPackageName() + "\n";
        // NPE for validator
        if (validator != null && validator.compilationSupported()) {
            rules = generateRules(process);
        }
        try {
            knowledgeBuilder.addPackageFromDrl(new StringReader(rules), resource);
        } catch (IOException e) {
            // should never occur
            logger.error("IOException during addPackageFromDRL", e);
        } catch (DroolsParserException e) {
            // should never occur
            logger.error("DroolsParserException during addPackageFromDRL", e);
        }
        PackageRegistry pkgRegistry = this.knowledgeBuilder.getPackageRegistry(process.getPackageName());
        if (pkgRegistry != null) {
            InternalKnowledgePackage p = pkgRegistry.getPackage();
            if (p != null) {
                if (validator != null) {
                    // NPE for validator
                    if (validator.compilationSupported()) {
                        ProcessDescr processDescr = new ProcessDescr();
                        processDescr.setName(process.getPackageName() + "." + process.getName());
                        processDescr.setResource(resource);
                        processDescr.setProcessId(process.getId());
                        DialectCompiletimeRegistry dialectRegistry = pkgRegistry.getDialectCompiletimeRegistry();
                        Dialect dialect = dialectRegistry.getDialect("java");
                        dialect.init(processDescr);
                        ProcessBuildContext buildContext = new ProcessBuildContext(this.knowledgeBuilder, p, process, processDescr, dialectRegistry, dialect);
                        buildContexts((ContextContainer) process, buildContext);
                        if (process instanceof WorkflowProcess) {
                            buildNodes((WorkflowProcess) process, buildContext);
                        }
                    }
                    Process duplicateProcess = p.getRuleFlows().get(process.getId());
                    if (duplicateProcess != null) {
                        Resource duplicatedResource = duplicateProcess.getResource();
                        if (resource == null || duplicatedResource == null || duplicatedResource.getSourcePath() == null || duplicatedResource.getSourcePath().equals(resource.getSourcePath())) {
                            this.errors.add(new DuplicateProcess(process, this.knowledgeBuilder.getBuilderConfiguration()));
                        } else {
                            this.errors.add(new ParserError(resource, "Process with same id already exists: " + process.getId(), -1, -1));
                        }
                    }
                    p.addProcess(process);
                    // NPE for validator
                    if (validator.compilationSupported()) {
                        pkgRegistry.compileAll();
                        pkgRegistry.getDialectRuntimeRegistry().onBeforeExecute();
                    }
                }
            }
        } else {
            // name of the process
            throw new RuntimeException("invalid package name");
        }
    }
}
Also used : ParserError(org.drools.compiler.compiler.ParserError) DialectCompiletimeRegistry(org.drools.compiler.compiler.DialectCompiletimeRegistry) Resource(org.kie.api.io.Resource) DuplicateProcess(org.drools.compiler.compiler.DuplicateProcess) Process(org.kie.api.definition.process.Process) WorkflowProcess(org.kie.api.definition.process.WorkflowProcess) ProcessDescr(org.drools.compiler.lang.descr.ProcessDescr) IOException(java.io.IOException) DroolsParserException(org.drools.compiler.compiler.DroolsParserException) Constraint(org.jbpm.workflow.core.Constraint) ProcessValidationError(org.jbpm.process.core.validation.ProcessValidationError) DuplicateProcess(org.drools.compiler.compiler.DuplicateProcess) PackageRegistry(org.drools.compiler.compiler.PackageRegistry) StringReader(java.io.StringReader) ProcessDialect(org.jbpm.process.builder.dialect.ProcessDialect) JavaDialect(org.drools.compiler.rule.builder.dialect.java.JavaDialect) Dialect(org.drools.compiler.compiler.Dialect) ProcessBuildContext(org.jbpm.process.builder.ProcessBuildContext) WorkflowProcess(org.kie.api.definition.process.WorkflowProcess) ProcessValidator(org.jbpm.process.core.validation.ProcessValidator) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage)

Example 3 with ProcessValidationError

use of org.jbpm.process.core.validation.ProcessValidationError in project jbpm by kiegroup.

the class RuleFlowProcessValidatorTest method testDynamicNodeValidationInNotDynamicProcess.

@Test
public void testDynamicNodeValidationInNotDynamicProcess() throws Exception {
    RuleFlowProcess process = new RuleFlowProcess();
    process.setId("org.drools.core.process");
    process.setName("Dynamic Node Process");
    process.setPackageName("org.mycomp.myprocess");
    process.setDynamic(false);
    DynamicNode dynamicNode = new DynamicNode();
    dynamicNode.setName("MyDynamicNode");
    dynamicNode.setId(1);
    dynamicNode.setAutoComplete(false);
    // empty completion expression to trigger validation error
    dynamicNode.setCompletionExpression("");
    process.addNode(dynamicNode);
    ProcessValidationError[] errors = validator.validateProcess(process);
    assertNotNull(errors);
    // in non-dynamic processes all check should be triggered
    // they should also include process level checks (start node, end node etc)
    assertEquals(6, errors.length);
    assertEquals("Process has no start node.", errors[0].getMessage());
    assertEquals("Process has no end node.", errors[1].getMessage());
    assertEquals("Node 'MyDynamicNode' [1] Dynamic has no incoming connection", errors[2].getMessage());
    assertEquals("Node 'MyDynamicNode' [1] Dynamic has no outgoing connection", errors[3].getMessage());
    assertEquals("Node 'MyDynamicNode' [1] Dynamic has no completion condition set", errors[4].getMessage());
    assertEquals("Node 'MyDynamicNode' [1] Has no connection to the start node.", errors[5].getMessage());
}
Also used : RuleFlowProcess(org.jbpm.ruleflow.core.RuleFlowProcess) DynamicNode(org.jbpm.workflow.core.node.DynamicNode) ProcessValidationError(org.jbpm.process.core.validation.ProcessValidationError) Test(org.junit.Test)

Example 4 with ProcessValidationError

use of org.jbpm.process.core.validation.ProcessValidationError in project jbpm by kiegroup.

the class RuleFlowProcessValidatorTest method testDynamicNodeValidationInDynamicProcess.

@Test
public void testDynamicNodeValidationInDynamicProcess() throws Exception {
    RuleFlowProcess process = new RuleFlowProcess();
    process.setId("org.drools.core.process");
    process.setName("Dynamic Node Process");
    process.setPackageName("org.mycomp.myprocess");
    process.setDynamic(true);
    DynamicNode dynamicNode = new DynamicNode();
    dynamicNode.setName("MyDynamicNode");
    dynamicNode.setId(1);
    dynamicNode.setAutoComplete(false);
    dynamicNode.setCompletionExpression("completion-expression");
    process.addNode(dynamicNode);
    ProcessValidationError[] errors = validator.validateProcess(process);
    assertNotNull(errors);
    // if dynamic process no longer triggering incoming / outgoing connection errors for dynamic nodes
    assertEquals(0, errors.length);
    // empty completion expression to trigger validation error
    process.removeNode(dynamicNode);
    DynamicNode dynamicNode2 = new DynamicNode();
    dynamicNode2.setName("MyDynamicNode");
    dynamicNode2.setId(1);
    dynamicNode2.setAutoComplete(false);
    dynamicNode2.setCompletionExpression("");
    process.addNode(dynamicNode2);
    ProcessValidationError[] errors2 = validator.validateProcess(process);
    assertNotNull(errors2);
    // autocomplete set to false and empty completion condition triggers error
    assertEquals(1, errors2.length);
    assertEquals("Node 'MyDynamicNode' [1] Dynamic has no completion condition set", errors2[0].getMessage());
}
Also used : RuleFlowProcess(org.jbpm.ruleflow.core.RuleFlowProcess) DynamicNode(org.jbpm.workflow.core.node.DynamicNode) ProcessValidationError(org.jbpm.process.core.validation.ProcessValidationError) Test(org.junit.Test)

Example 5 with ProcessValidationError

use of org.jbpm.process.core.validation.ProcessValidationError in project jbpm by kiegroup.

the class RuleFlowProcessValidatorTest method testNoPackageName.

@Test
public void testNoPackageName() throws Exception {
    RuleFlowProcess process = new RuleFlowProcess();
    process.setId("org.drools.core.process");
    process.setName("No Package Name Process");
    process.setDynamic(true);
    ProcessValidationError[] errors = validator.validateProcess(process);
    assertNotNull(errors);
    assertEquals(0, errors.length);
}
Also used : RuleFlowProcess(org.jbpm.ruleflow.core.RuleFlowProcess) ProcessValidationError(org.jbpm.process.core.validation.ProcessValidationError) Test(org.junit.Test)

Aggregations

ProcessValidationError (org.jbpm.process.core.validation.ProcessValidationError)8 RuleFlowProcess (org.jbpm.ruleflow.core.RuleFlowProcess)4 Test (org.junit.Test)4 StringReader (java.io.StringReader)3 ProcessValidator (org.jbpm.process.core.validation.ProcessValidator)3 Process (org.kie.api.definition.process.Process)3 Resource (org.kie.api.io.Resource)3 ByteArrayResource (org.drools.core.io.impl.ByteArrayResource)2 ReaderResource (org.drools.core.io.impl.ReaderResource)2 XmlProcessReader (org.jbpm.compiler.xml.XmlProcessReader)2 DynamicNode (org.jbpm.workflow.core.node.DynamicNode)2 DefaultIndexBuilder (org.kie.workbench.common.services.refactoring.backend.server.indexing.DefaultIndexBuilder)2 KieModule (org.kie.workbench.common.services.shared.project.KieModule)2 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Dialect (org.drools.compiler.compiler.Dialect)1 DialectCompiletimeRegistry (org.drools.compiler.compiler.DialectCompiletimeRegistry)1 DroolsParserException (org.drools.compiler.compiler.DroolsParserException)1 DuplicateProcess (org.drools.compiler.compiler.DuplicateProcess)1 PackageRegistry (org.drools.compiler.compiler.PackageRegistry)1