Search in sources :

Example 21 with TimeSpan

use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.

the class SubprocessBPMNEEPlugin method eventRoutine.

@Override
public void eventRoutine(BPMNEndEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    ProcessModel processModel = processInstance.getProcessModel();
    if (processModel.getParent() != null && processInstanceIsCompleted(processInstance)) {
        // works
        try {
            ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
            ProcessSimulationComponents parentDesmojObjects = desmojObjects.getParent();
            ProcessModel parentModel = processModel.getParent();
            int nodeIdInParent = processModel.getNodeIdInParent();
            ProcessInstance parentProcessInstance = processInstance.getParent();
            // behavior when sub-process sends events:
            // none -> back to normal flow
            // message -> "send it"
            // error -> to parent
            // escalation -> to parent
            // cancel -> nonono!
            // compensation -> ... not now
            // signal -> ... not now
            // terminate -> terminate sub-process (kill all events of sub-process instance (MI sub-process
            // not affected))
            // ...
            // timer -> special treatment
            Set<Integer> idsOfNextNodes = parentModel.getIdsOfNextNodes(nodeIdInParent);
            // normal flow: must not have more than one successor
            if (idsOfNextNodes.size() != 1) {
                int nodeId = desmojEvent.getNodeId();
                throw new ScyllaValidationException("Subprocess " + nodeId + " does not have 1 successor, but " + idsOfNextNodes.size() + ".");
            }
            Integer nextNodeId = idsOfNextNodes.iterator().next();
            // TODO let the parent create the next node, so remove the lines below
            List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(desmojEvent, parentDesmojObjects, parentProcessInstance, nextNodeId);
            // next event occurs immediately after start event
            TimeSpan timeSpan = new TimeSpan(0);
            String parentProcessInstanceName = parentProcessInstance.getName();
            SubprocessPluginUtils pluginInstance = SubprocessPluginUtils.getInstance();
            TaskTerminateEvent eventOfParent = pluginInstance.getEventsOnHold().get(parentProcessInstanceName).get(nodeIdInParent);
            if (eventOfParent != null) {
                events.add(eventOfParent);
                pluginInstance.getEventsOnHold().get(parentProcessInstanceName).remove(nodeIdInParent);
                pluginInstance.getNameOfEventsThatWereOnHold().add(eventOfParent.getName());
            }
            for (ScyllaEvent event : events) {
                int index = desmojEvent.getNewEventIndex();
                desmojEvent.getNextEventMap().put(index, event);
                desmojEvent.getTimeSpanToNextEventMap().put(index, timeSpan);
            }
        } catch (NodeNotFoundException | ScyllaValidationException | ScyllaRuntimeException e) {
            SimulationModel model = (SimulationModel) desmojEvent.getModel();
            int nodeId = desmojEvent.getNodeId();
            boolean showInTrace = model.traceIsOn();
            DebugLogger.error(e.getMessage());
            e.printStackTrace();
            SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
        }
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) TaskTerminateEvent(de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent) TimeSpan(desmoj.core.simulator.TimeSpan) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 22 with TimeSpan

use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.

the class SubprocessTBPlugin method eventRoutine.

@Override
public void eventRoutine(TaskBeginEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    ProcessModel processModel = processInstance.getProcessModel();
    int nodeId = desmojEvent.getNodeId();
    ProcessModel subProcess = processModel.getSubProcesses().get(nodeId);
    if (subProcess != null) {
        int indexOfTaskTerminateEvent = 0;
        desmojEvent.getTimeSpanToNextEventMap().remove(indexOfTaskTerminateEvent);
        TaskTerminateEvent event = (TaskTerminateEvent) desmojEvent.getNextEventMap().get(indexOfTaskTerminateEvent);
        String name = processInstance.getName();
        SubprocessPluginUtils pluginInstance = SubprocessPluginUtils.getInstance();
        Map<Integer, TaskTerminateEvent> eventsOnHoldMap = pluginInstance.getEventsOnHold().get(name);
        if (eventsOnHoldMap == null) {
            pluginInstance.getEventsOnHold().put(name, new HashMap<Integer, TaskTerminateEvent>());
        }
        pluginInstance.getEventsOnHold().get(name).put(nodeId, event);
        desmojEvent.getNextEventMap().remove(indexOfTaskTerminateEvent);
        String source = desmojEvent.getSource();
        ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
        SimulationModel model = (SimulationModel) desmojEvent.getModel();
        TimeInstant currentSimulationTime = model.presentTime();
        boolean showInTrace = model.traceIsOn();
        int processInstanceId = processInstance.getId();
        try {
            ProcessSimulationComponents desmojObjectsOfSubProcess = desmojObjects.getChildren().get(nodeId);
            Integer startNodeId = subProcess.getStartNode();
            ProcessInstance subProcessInstance = new ProcessInstance(model, subProcess, processInstanceId, showInTrace);
            subProcessInstance.setParent(processInstance);
            ScyllaEvent subProcessEvent = new BPMNStartEvent(model, source, currentSimulationTime, desmojObjectsOfSubProcess, subProcessInstance, startNodeId);
            TimeSpan timeSpan = new TimeSpan(0);
            int index = desmojEvent.getNewEventIndex();
            desmojEvent.getNextEventMap().put(index, subProcessEvent);
            desmojEvent.getTimeSpanToNextEventMap().put(index, timeSpan);
        } catch (NodeNotFoundException | MultipleStartNodesException | NoStartNodeException e) {
            DebugLogger.error(e.getMessage());
            DebugLogger.log("Start node of process model " + subProcess.getId() + " not found.");
            throw new ScyllaRuntimeException("Start node of process model " + subProcess.getId() + " not found.");
        }
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) TaskTerminateEvent(de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent) MultipleStartNodesException(de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException) TimeSpan(desmoj.core.simulator.TimeSpan) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) BPMNStartEvent(de.hpi.bpt.scylla.simulation.event.BPMNStartEvent) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel) TimeInstant(desmoj.core.simulator.TimeInstant) NoStartNodeException(de.hpi.bpt.scylla.model.process.graph.exception.NoStartNodeException)

Example 23 with TimeSpan

use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.

the class SubprocessTCPlugin method eventRoutine.

@Override
public void eventRoutine(TaskCancelEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    ProcessModel processModel = processInstance.getProcessModel();
    if (processModel.getParent() != null) {
        int nodeIdInParent = processModel.getNodeIdInParent();
        ProcessInstance parentProcessInstance = processInstance.getParent();
        String parentProcessInstanceName = parentProcessInstance.getName();
        SubprocessPluginUtils pluginInstance = SubprocessPluginUtils.getInstance();
        Map<Integer, TaskTerminateEvent> eventsOnHoldMap = pluginInstance.getEventsOnHold().get(parentProcessInstanceName);
        TaskTerminateEvent event = eventsOnHoldMap.get(nodeIdInParent);
        if (event != null) {
            SimulationModel model = (SimulationModel) event.getModel();
            String source = event.getSource();
            TaskCancelEvent cancelEvent = new TaskCancelEvent(model, source, event.getSimulationTimeOfSource(), event.getDesmojObjects(), event.getProcessInstance(), event.getNodeId());
            cancelEvent.schedule(parentProcessInstance, new TimeSpan(0));
            eventsOnHoldMap.remove(nodeIdInParent);
        }
    }
}
Also used : TimeSpan(desmoj.core.simulator.TimeSpan) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) TaskCancelEvent(de.hpi.bpt.scylla.simulation.event.TaskCancelEvent) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) TaskTerminateEvent(de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 24 with TimeSpan

use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.

the class QueueManager method releaseResourcesAndScheduleQueuedEvents.

/**
 * Releases the resource instances assigned to the given event, selects event(s) from the event queues which are due
 * next and schedules them immediately.
 *
 * @param model
 *            the simulation model
 * @param releasingEvent
 *            the DesmoJ event whose resource instances may be released
 * @throws ScyllaRuntimeException
 */
public static void releaseResourcesAndScheduleQueuedEvents(SimulationModel model, ScyllaEvent releasingEvent) throws ScyllaRuntimeException {
    ProcessInstance processInstance = releasingEvent.getProcessInstance();
    int nodeId = releasingEvent.getNodeId();
    String nameOfResponsibleEvent = releasingEvent.getSource();
    // release resources
    Set<String> resourceQueuesUpdated = new HashSet<String>();
    Set<ResourceObject> assignedResources = new HashSet<ResourceObject>();
    if (nameOfResponsibleEvent == null) {
        // release all resources of process instance
        for (ResourceObjectTuple tuple : processInstance.getAssignedResources().values()) {
            assignedResources.addAll(tuple.getResourceObjects());
        }
    } else {
        assignedResources.addAll(processInstance.getAssignedResources().get(nameOfResponsibleEvent).getResourceObjects());
    }
    Map<String, ResourceQueue> resourceObjects = model.getResourceObjects();
    TimeInstant presentTime = model.presentTime();
    for (ResourceObject resourceObject : assignedResources) {
        String resourceId = resourceObject.getResourceType();
        resourceObjects.get(resourceId).offer(presentTime, resourceObject, processInstance, nodeId);
        String traceNote = "Dissociate resource " + resourceId + " (" + resourceObject.getId() + ") from process instance " + processInstance.getName();
        if (nameOfResponsibleEvent != null) {
            traceNote += ", source: " + nameOfResponsibleEvent;
        }
        model.sendTraceNote(traceNote);
        resourceQueuesUpdated.add(resourceId);
    }
    if (nameOfResponsibleEvent == null) {
        processInstance.getAssignedResources().clear();
    } else {
        processInstance.getAssignedResources().remove(nameOfResponsibleEvent);
    }
    // ... and schedule next task if there are any in the queue
    /**
     * there may be no event ready for schedule, especially if they rely on resources that are together not
     * available at the moment, so we have to check "later" again ? (whatever later means)
     *
     * --> solved by introduction of ResourceAvailableEvent
     */
    ScyllaEvent eventFromQueue = getEventFromQueueReadyForSchedule(model, resourceQueuesUpdated);
    while (eventFromQueue != null) {
        SimulationUtils.scheduleEvent(eventFromQueue, new TimeSpan(0));
        eventFromQueue = getEventFromQueueReadyForSchedule(model, resourceQueuesUpdated);
    }
}
Also used : ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) TimeSpan(desmoj.core.simulator.TimeSpan) TimeInstant(desmoj.core.simulator.TimeInstant) HashSet(java.util.HashSet)

Example 25 with TimeSpan

use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.

the class BPMNIntermediateEvent method eventRoutine.

@Override
public void eventRoutine(ProcessInstance processInstance) throws SuspendExecution {
    super.eventRoutine(processInstance);
    SimulationModel model = (SimulationModel) getModel();
    ProcessModel processModel = processInstance.getProcessModel();
    try {
        EventType type = processModel.getEventTypes().get(nodeId);
        // Long duration = null;
        // TimeUnit timeUnit = null;
        Map<EventDefinitionType, Map<String, String>> definitions = processModel.getEventDefinitions().get(nodeId);
        Set<String> messages = new HashSet<String>();
        for (EventDefinitionType definition : definitions.keySet()) {
            // TODO what about implicit throw events?
            if (definition == EventDefinitionType.CANCEL) {
                // TODO: cancel event only in transaction sub-process
                // isInterrupting?
                boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                if (type == EventType.BOUNDARY && cancelActivity) {
                    String message = "Boundary Cancel Event: " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else if (definition == EventDefinitionType.COMPENSATION) {
                // isInterrupting?
                boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                if (type == EventType.BOUNDARY && cancelActivity) {
                    String message = "Boundary Compensation Event: " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else if (definition == EventDefinitionType.CONDITIONAL) {
                if (type == EventType.BOUNDARY) {
                    // isInterrupting?
                    boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                    if (cancelActivity) {
                        String message = "Boundary Conditional Event (Interrupting): " + displayName;
                        messages.add(message);
                    } else {
                        String message = "Boundary Conditional Event (Non-Interrupting): " + displayName;
                        messages.add(message);
                    }
                } else if (type == EventType.INTERMEDIATE_CATCH) {
                    String message = "Intermediate Conditional Event (Catching): " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else if (definition == EventDefinitionType.ERROR) {
                // isInterrupting?
                boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                if (type == EventType.BOUNDARY && cancelActivity) {
                    String message = "Boundary Error Event: " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else if (definition == EventDefinitionType.ESCALATION) {
                if (type == EventType.BOUNDARY) {
                    // isInterrupting?
                    boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                    if (cancelActivity) {
                        String message = "Boundary Escalation Event (Interrupting): " + displayName;
                        messages.add(message);
                    } else {
                        String message = "Boundary Escalation Event (Non-Interrupting): " + displayName;
                        messages.add(message);
                    }
                } else if (type == EventType.INTERMEDIATE_THROW) {
                    String message = "Intermediate Escalation Event (Throwing): " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else if (definition == EventDefinitionType.LINK) {
                if (type == EventType.INTERMEDIATE_CATCH) {
                    String message = "Intermediate Link Event (Catching): " + displayName;
                    messages.add(message);
                } else if (type == EventType.INTERMEDIATE_THROW) {
                    String message = "Intermediate Link Event (Throwing): " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else if (definition == EventDefinitionType.MESSAGE) {
                if (type == EventType.BOUNDARY) {
                    // isInterrupting?
                    boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                    if (cancelActivity) {
                        String message = "Boundary Message Event (Interrupting): " + displayName;
                        messages.add(message);
                    } else {
                        String message = "Boundary Message Event (Non-Interrupting): " + displayName;
                        messages.add(message);
                    }
                } else if (type == EventType.INTERMEDIATE_CATCH) {
                    String message = "Intermediate Message Event (Catching): " + displayName;
                    messages.add(message);
                } else if (type == EventType.INTERMEDIATE_THROW) {
                    String message = "Intermediate Message Event (Throwing): " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else if (definition == EventDefinitionType.SIGNAL) {
                if (type == EventType.BOUNDARY) {
                    // isInterrupting?
                    boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                    if (cancelActivity) {
                        String message = "Boundary Signal Event (Interrupting): " + displayName;
                        messages.add(message);
                    } else {
                        String message = "Boundary Signal Event (Non-Interrupting): " + displayName;
                        messages.add(message);
                    }
                } else if (type == EventType.INTERMEDIATE_CATCH) {
                    String message = "Intermediate Signal Event (Catching): " + displayName;
                    messages.add(message);
                } else if (type == EventType.INTERMEDIATE_THROW) {
                    String message = "Intermediate Signal Event (Throwing): " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else if (definition == EventDefinitionType.TIMER) {
                if (type == EventType.BOUNDARY) {
                    // isInterrupting?
                    boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                    if (cancelActivity) {
                        String message = "Boundary Timer Event (Interrupting): " + displayName;
                        messages.add(message);
                    } else {
                        String message = "Boundary Timer Event (Non-Interrupting): " + displayName;
                        messages.add(message);
                    }
                } else if (type == EventType.INTERMEDIATE_CATCH) {
                    String message = "Intermediate Timer Event (Catching): " + displayName;
                    messages.add(message);
                } else {
                    SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                    SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    return;
                }
            } else {
                // None Event
                if (messages.isEmpty()) {
                    if (type == EventType.INTERMEDIATE_THROW) {
                        String message = "Intermediate None Event (Throwing): " + displayName;
                        messages.add(message);
                    } else {
                        SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
                        SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
                    }
                }
            }
        }
        for (String message : messages) {
            sendTraceNote(message);
        }
        // get next node(s)
        Set<Integer> idsOfNextNodes = processModel.getIdsOfNextNodes(nodeId);
        // BPMN intermediate event must not have more than successor
        if (idsOfNextNodes.size() != 1) {
            throw new ScyllaValidationException("Event " + nodeId + " does not have 1 successor, but " + idsOfNextNodes.size() + ".");
        }
        Integer nextNodeId = idsOfNextNodes.iterator().next();
        // schedule event for next node
        List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(this, pSimComponents, processInstance, nextNodeId);
        // next event occurs immediately after start event
        TimeSpan timeSpan = new TimeSpan(0);
        for (ScyllaEvent event : events) {
            int index = getNewEventIndex();
            nextEventMap.put(index, event);
            timeSpanToNextEventMap.put(index, timeSpan);
        }
        // unless current one is BPMN timer event with timerDuration
        BPMNIntermediateEventPluggable.runPlugins(this, processInstance);
        scheduleNextEvents();
    } catch (NodeNotFoundException | ScyllaValidationException | ScyllaRuntimeException e) {
        System.err.println(e.getMessage());
        e.printStackTrace();
        SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
        return;
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) EventType(de.hpi.bpt.scylla.model.process.node.EventType) EventDefinitionType(de.hpi.bpt.scylla.model.process.node.EventDefinitionType) TimeSpan(desmoj.core.simulator.TimeSpan) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) Map(java.util.Map) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel) HashSet(java.util.HashSet)

Aggregations

TimeSpan (desmoj.core.simulator.TimeSpan)34 ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)25 SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)17 ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)15 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)12 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)11 ProcessInstance (de.hpi.bpt.scylla.simulation.ProcessInstance)11 TimeUnit (java.util.concurrent.TimeUnit)11 ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)10 TimeInstant (desmoj.core.simulator.TimeInstant)9 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)8 Map (java.util.Map)7 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)6 TaskTerminateEvent (de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent)5 HashSet (java.util.HashSet)5 ArrayList (java.util.ArrayList)4 MultipleStartNodesException (de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException)3 NoStartNodeException (de.hpi.bpt.scylla.model.process.graph.exception.NoStartNodeException)3 TaskType (de.hpi.bpt.scylla.model.process.node.TaskType)3 Duration (java.time.Duration)3