diff --git a/imixs-workflow-core/src/main/java/org/imixs/workflow/WorkflowKernel.java b/imixs-workflow-core/src/main/java/org/imixs/workflow/WorkflowKernel.java index a82901a00..7199027bd 100644 --- a/imixs-workflow-core/src/main/java/org/imixs/workflow/WorkflowKernel.java +++ b/imixs-workflow-core/src/main/java/org/imixs/workflow/WorkflowKernel.java @@ -427,7 +427,11 @@ public ItemCollection process(ItemCollection workitem) throws PluginException, M */ private ItemCollection processEvent(ItemCollection workitem, ItemCollection event) throws ModelException, PluginException { + BPMNModel model = this.ctx.getModelManager().getModel(workitem.getModelVersion()); + + // Update the intermediate processing status + updateIntermediateEvent(workitem, event); // set $lastEventDate workitem.replaceItemValue(LASTEVENTDATE, new Date()); // Execute Plugins and Adapters.... @@ -460,7 +464,7 @@ private ItemCollection processEvent(ItemCollection workitem, ItemCollection even logEvent(workitem.getTaskID(), workitem.getEventID(), workitem.getTaskID(), workitem); event = nextElement; workitem.event(event.getItemValueInteger(BPMNUtil.EVENT_ITEM_EVENTID)); - updateIntermediateEvent(workitem, event); + // return the next event element to be processed.... return event; } @@ -614,12 +618,8 @@ public ItemCollection eval(final ItemCollection _workitem) throws PluginExceptio int intermediateEvent = workitem.getItemValueInteger(WorkflowKernel.INTERMEDIATE_EVENTID); if (intermediateEvent > 0) { BPMNModel model = this.ctx.getModelManager().findModelByWorkitem(workitem); - BPMNElementNode inteEventElement = model.findElementNodeById(intermediateEventElementID); - // ItemCollection intermediateEventItemCol = - // BPMNEntityBuilder.build(inteEventElement); - // event = this.ctx.getModelManager().nextModelElement(intermediateEventItemCol, - // workitem); - event = BPMNEntityBuilder.build(inteEventElement); + BPMNElementNode intermediateEventElement = model.findElementNodeById(intermediateEventElementID); + event = BPMNEntityBuilder.build(intermediateEventElement); } else { event = this.ctx.getModelManager().loadEvent(workitem); } @@ -828,23 +828,25 @@ private void updateWorkflowStatus(ItemCollection workitem, ItemCollection itemCo } /** - * Helper method to update the item $intermediateEventID. + * Helper method to update the item $intermediateEvent and + * $intermediateEvent.elementId. * The given Element must be a Event. Otherwise the method throws a * ModelException. + *

+ * This method is called by the method processEvent() and indicates that we are + * currently in an active processing life cycle. This status is evaluated by the + * eval() method to avoid invalid calls of loadEvent(). * * @throws ModelException */ private void updateIntermediateEvent(ItemCollection workitem, ItemCollection itemColNextEvent) throws ModelException { - boolean debug = logger.isLoggable(Level.FINE); if (!ModelManager.EVENT_ELEMENT.equals(itemColNextEvent.getType())) { throw new ModelException(ModelException.INVALID_MODEL, "Invalid Model Element - BPMN Event Element was expected to update the intermediate event status."); } - workitem.setItemValue(INTERMEDIATE_EVENTID, itemColNextEvent.getItemValueInteger(BPMNUtil.EVENT_ITEM_EVENTID)); workitem.setItemValue(INTERMEDIATE_EVENT_ELEMENTID, itemColNextEvent.getItemValueString("id")); - } /** diff --git a/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/AbstractWorkflowServiceTest.java b/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/AbstractWorkflowServiceTest.java deleted file mode 100644 index 4c4b3b049..000000000 --- a/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/AbstractWorkflowServiceTest.java +++ /dev/null @@ -1,149 +0,0 @@ -package org.imixs.workflow.engine; - -import static org.mockito.Mockito.when; - -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; - -import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.WorkflowKernel; -import org.imixs.workflow.exceptions.ModelException; -import org.imixs.workflow.exceptions.PluginException; -import org.junit.Assert; -import org.junit.jupiter.api.BeforeEach; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; -import org.mockito.stubbing.Answer; -import org.openbpmn.bpmn.BPMNModel; -import org.openbpmn.bpmn.exceptions.BPMNModelException; -import org.openbpmn.bpmn.util.BPMNModelFactory; - -/** - * The {@code AbstractWorkflowServiceTest} can be used as a base class for junit - * tests to mock the Imixs WorkflowService. The class mocks the WorkflowService - * and a workflow environment including the ModelService. - * - * Junit tests can extend the AbstractWorkflowServiceTest to verify specific - * method implementations of the workflowService, Plugin classes or Adapters in - * a easy way. - *

- * Because this is a abstract base test class we annotate the MockitoSettings - * {@link Strictness} to avoid - * org.mockito.exceptions.misusing.UnnecessaryStubbingException. - * - * @author rsoika - */ -// @ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.WARN) -public abstract class AbstractWorkflowServiceTest { - protected final static Logger logger = Logger.getLogger(AbstractWorkflowServiceTest.class.getName()); - - protected Map database = null; - - @Mock - protected DocumentService documentService; // Mock instance - - @InjectMocks - protected ModelService modelService; // Injects mocks into ModelService - - @InjectMocks - protected WorkflowService workflowServiceMock; // Injects mocks into WorkflowService - - protected WorkflowContextMock workflowContext = null; - - /** - * The Setup method initializes a mock environment to test the imixs workflow - * service. It initializes a in-memory database and a model Service as also a - * Session context object. - *

- * You can overwrite this method in a junit test to add additional test - * settings. - * - * @throws PluginException - */ - @BeforeEach - public void setUp() throws PluginException { - // Ensures that @Mock and @InjectMocks annotations are processed - MockitoAnnotations.openMocks(this); - - // Set up test environment - createTestDatabase(); - loadBPMNModel("/bpmn/plugin-test.bpmn"); - - // Link modelService to workflowServiceMock - workflowServiceMock.modelService = modelService; - - workflowContext = new WorkflowContextMock(); - workflowServiceMock.ctx = workflowContext.getSessionContext(); - - // Mock Database Service... - when(documentService.load(Mockito.anyString())).thenAnswer(new Answer() { - @Override - public ItemCollection answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - String id = (String) args[0]; - ItemCollection result = database.get(id); - if (result != null) { - // set author access=true - result.replaceItemValue(DocumentService.ISAUTHOR, true); - } - return result; - } - }); - when(documentService.save(Mockito.any())).thenAnswer(new Answer() { - @Override - public ItemCollection answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - ItemCollection data = (ItemCollection) args[0]; - if (data != null) { - database.put(data.getUniqueID(), data); - } - return data; - } - }); - - } - - /** - * Create a test database with some workItems and a simple model - */ - protected void createTestDatabase() { - - database = new HashMap(); - ItemCollection entity = null; - logger.info("createSimpleDatabase...."); - // create workitems - for (int i = 1; i < 6; i++) { - entity = new ItemCollection(); - entity.replaceItemValue("type", "workitem"); - entity.replaceItemValue(WorkflowKernel.UNIQUEID, "W0000-0000" + i); - entity.replaceItemValue("txtName", "Workitem " + i); - entity.setModelVersion("1.0.0"); - entity.setTaskID(100); - entity.setEventID(10); - entity.replaceItemValue(DocumentService.ISAUTHOR, true); - database.put(entity.getItemValueString(WorkflowKernel.UNIQUEID), entity); - } - } - - /** - * Helper method that loads a new model into the ModelService - * - * @param modelPath - */ - public void loadBPMNModel(String modelPath) { - try { - BPMNModel model = BPMNModelFactory.read(modelPath); - modelService.getModelManager().addModel(model); - } catch (BPMNModelException | ModelException e) { - e.printStackTrace(); - Assert.fail(); - } - } -} diff --git a/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/TestAdaptText.java b/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/TestAdaptText.java index 40a87fad7..2ce12a1a9 100644 --- a/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/TestAdaptText.java +++ b/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/TestAdaptText.java @@ -1,21 +1,19 @@ package org.imixs.workflow.engine; -import static org.mockito.Mockito.when; - import java.util.Calendar; -import java.util.List; import java.util.Vector; +import java.util.logging.Logger; import org.imixs.workflow.ItemCollection; +import org.imixs.workflow.exceptions.ModelException; import org.imixs.workflow.exceptions.PluginException; import org.junit.Assert; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.Answer; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; /** * Test the WorkflowService method 'adaptText' @@ -26,56 +24,20 @@ * */ @ExtendWith(MockitoExtension.class) -public class TestAdaptText extends AbstractWorkflowServiceTest { - - @Mock - private WorkflowService workflowService; - - @Override - public void setUp() throws PluginException { - super.setUp(); - // AdaptText - when(workflowService.adaptText(Mockito.anyString(), Mockito.any(ItemCollection.class))) - .thenAnswer(new Answer() { - @Override - public String answer(InvocationOnMock invocation) throws Throwable { - - Object[] args = invocation.getArguments(); - String text = (String) args[0]; - ItemCollection document = (ItemCollection) args[1]; - - TextEvent textEvent = new TextEvent(text, document); - - // for-each adapter - TextForEachAdapter tfea = new TextForEachAdapter(); - tfea.onEvent(textEvent); - - // ItemValue adapter - TextItemValueAdapter tiva = new TextItemValueAdapter(); - tiva.onEvent(textEvent); - - return textEvent.getText(); - } - }); - - when(workflowService.adaptTextList(Mockito.anyString(), Mockito.any(ItemCollection.class))) - .thenAnswer(new Answer>() { - @Override - public List answer(InvocationOnMock invocation) throws Throwable, PluginException { - - Object[] args = invocation.getArguments(); - String text = (String) args[0]; - ItemCollection document = (ItemCollection) args[1]; - - TextEvent textEvent = new TextEvent(text, document); - - TextItemValueAdapter tiva = new TextItemValueAdapter(); - tiva.onEvent(textEvent); - - return textEvent.getTextList(); - } - }); - +@MockitoSettings(strictness = Strictness.WARN) +public class TestAdaptText { + private final static Logger logger = Logger.getLogger(TestAdaptText.class.getName()); + + protected WorkflowMockEnvironment workflowEngine; + ItemCollection workitem; + + @BeforeEach + public void setUp() throws PluginException, ModelException { + workflowEngine = new WorkflowMockEnvironment(); + workflowEngine.setUp(); + workflowEngine.loadBPMNModel("/bpmn/TestWorkflowService.bpmn"); + workitem = workflowEngine.getDocumentService().load("W0000-00001"); + workitem.model("1.0.0").task(100); } /** @@ -99,12 +61,11 @@ public void testReplaceDynamicValues() { String resultString; try { - resultString = this.workflowService.adaptText(testString, documentContext); + resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedString, resultString); } catch (PluginException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Assert.fail(e.getMessage()); } } @@ -127,7 +88,7 @@ public void testReplaceDynamicValuesFormatError() { String resultString = null; try { - resultString = this.workflowService.adaptText(testString, documentContext); + resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertNotNull(resultString); Assert.assertEquals(testString, resultString); } catch (PluginException e) { @@ -165,7 +126,7 @@ public void testDateFormat() throws PluginException { documentContext.replaceItemValue("datDate", cal.getTime()); - String resultString = this.workflowService.adaptText(testString, documentContext); + String resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedString, resultString); @@ -188,7 +149,7 @@ public void testDateFormatEN() throws PluginException { documentContext.replaceItemValue("datDate", cal.getTime()); - String resultString = this.workflowService.adaptText(testString, documentContext); + String resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedString, resultString); @@ -222,7 +183,7 @@ public void testMultiValueFormat() throws PluginException { value.add(300); documentContext.replaceItemValue("_numbers", value); - String resultString = this.workflowService.adaptText(testString, documentContext); + String resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedString, resultString); @@ -251,7 +212,7 @@ public void testNumberFormat() throws PluginException { documentContext.replaceItemValue("price", Float.valueOf((float) 1199.99)); - String resultString = this.workflowService.adaptText(testString, documentContext); + String resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedString, resultString); @@ -285,7 +246,7 @@ public void testMultiValueWithNoSeparator() throws PluginException { value.add(300); documentContext.replaceItemValue("_numbers", value); - String resultString = this.workflowService.adaptText(testString, documentContext); + String resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); // we expect that only the first value is given, because no separator was // defined. @@ -321,7 +282,7 @@ public void testMultiValuePosition() throws PluginException { values.add(300); documentContext.replaceItemValue("_numbers", values); - String resultString = this.workflowService.adaptText(testString, documentContext); + String resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedStringLast, resultString); @@ -335,7 +296,7 @@ public void testMultiValuePosition() throws PluginException { documentContext.replaceItemValue("_numbers", values); - resultString = this.workflowService.adaptText(testString, documentContext); + resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedStringFirst, resultString); @@ -367,7 +328,7 @@ public void testForEachSimpleValueList() throws PluginException { documentContext.appendItemValue("_partid", "A123"); documentContext.appendItemValue("_partid", "B456"); - String resultString = workflowService.adaptText(testString, documentContext); + String resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedStringLast, resultString); @@ -408,7 +369,7 @@ public void testForEachEmbeddedChildItemValue() throws PluginException { // create a fake value which should be ignored documentContext.replaceItemValue("_orderid", "not used"); - String resultString = workflowService.adaptText(testString, documentContext); + String resultString = this.workflowEngine.workflowService.adaptText(testString, documentContext); Assert.assertEquals(expectedStringLast, resultString); diff --git a/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/WorkflowMockEnvironment.java b/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/WorkflowMockEnvironment.java index 39208e501..8d2676c42 100644 --- a/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/WorkflowMockEnvironment.java +++ b/imixs-workflow-engine/src/test/java/org/imixs/workflow/engine/WorkflowMockEnvironment.java @@ -32,11 +32,11 @@ import jakarta.enterprise.inject.Instance; /** - * The {@code AbstractWorkflowServiceTest} can be used as a base class for junit + * The {@code WorkflowMockEnvironment} can be used as a base class for junit * tests to mock the Imixs WorkflowService. The class mocks the WorkflowService * and a workflow environment including the ModelService. * - * Junit tests can extend the AbstractWorkflowServiceTest to verify specific + * Junit tests can instantiate this class to verify specific * method implementations of the workflowService, Plugin classes or Adapters in * a easy way. *