Search in sources :

Example 26 with ScyllaValidationException

use of de.hpi.bpt.scylla.exception.ScyllaValidationException in project scylla by bptlab.

the class BoundarySCParserPlugin method parse.

// Therefore this method should be called just once for a sim.xml file
@Override
public Map<String, Object> parse(SimulationConfiguration simulationInput, Element sim) throws ScyllaValidationException {
    Map<Integer, BranchingBehavior> branchingBehaviors = new HashMap<Integer, BranchingBehavior>();
    Namespace simNamespace = sim.getNamespace();
    ProcessModel processModel = simulationInput.getProcessModel();
    for (Element element : sim.getChildren()) {
        String elementName = element.getName();
        if (elementName.equals("task") || elementName.endsWith("Task") || elementName.equals("subProcess")) {
            String identifier = element.getAttributeValue("id");
            if (identifier == null) {
                DebugLogger.log("Warning: Simulation configuration definition element '" + elementName + "' does not have an identifier, skip.");
                // No matching element in process, so skip definition.
                continue;
            }
            Integer nodeId = processModel.getIdentifiersToNodeIds().get(identifier);
            if (nodeId == null) {
                DebugLogger.log("Simulation configuration definition for process element '" + identifier + "', but not available in process, skip.");
                // No matching element in process, so skip definition
                continue;
            }
            // Get the list of all corresponding boundary events.
            Element boundaryEventsElem = element.getChild("boundaryEvents", simNamespace);
            if (boundaryEventsElem != null) {
                List<Element> boundaryEventElements = boundaryEventsElem.getChildren("boundaryEvent", simNamespace);
                if (boundaryEventElements.size() > 0) {
                    Map<Integer, Double> probabilities = new HashMap<Integer, Double>();
                    double probabilityOfStandardFlow = 1;
                    for (Element elem : boundaryEventElements) {
                        // Collect probabilities of boundary event occurrence...
                        String id = elem.getAttributeValue("id");
                        Integer nodeIdOfBoundaryEvent = processModel.getIdentifiersToNodeIds().get(id);
                        if (nodeIdOfBoundaryEvent == null) {
                            throw new ScyllaValidationException("Simulation configuration refers to unknown boundary event: " + id);
                        }
                        // ... and subtract them from the default path behavior. The percentage of the default path is just
                        // relevant for interrupting events because its implicit 1 at tasks with only nn-interrupting events.
                        Element eventProbabilityElement = elem.getChild("eventProbability", simNamespace);
                        Double probabilityOfBoundaryEvent = Double.parseDouble(eventProbabilityElement.getText());
                        probabilityOfStandardFlow -= probabilityOfBoundaryEvent;
                        probabilities.put(nodeIdOfBoundaryEvent, probabilityOfBoundaryEvent);
                        // Add the arrival rate (= which is here the time at which the boundary event shall occur) relatively to the start of its task.
                        Element arrivalRateElement = elem.getChild("arrivalRate", simNamespace);
                        if (arrivalRateElement != null) {
                            TimeDistributionWrapper distribution = SimulationConfigurationParser.getTimeDistributionWrapper(arrivalRateElement, simNamespace);
                            // TODO: should be put into an extension attribute
                            simulationInput.getArrivalRates().put(nodeIdOfBoundaryEvent, distribution);
                        }
                    }
                    if (probabilityOfStandardFlow < 0) {
                        // The probability values of boundary events are added why they should not exceed 1 in total.
                        throw new ScyllaValidationException("Simulation configuration defines probabilities for boundary events of task " + identifier + ", exceeding 1 in total.");
                    }
                    /*else if (probabilityOfStandardFlow == 0) { // Does not happen anymore and should not happen semantically correct.
                            DebugLogger
                                    .log("Warning: Simulation configuration defines probabilities for boundary events of task "
                                            + identifier + ", but does not allow the normal flow to fire. \n"
                                            + "This may result in an infinite number of firings of boundary events "
                                            + "if none of them is interrupting.");
                        }*/
                    // XXX timer events do not have probabilities
                    // XXX probability of normal flow is stored under nodeId of task
                    // And save them for now.
                    probabilities.put(nodeId, probabilityOfStandardFlow);
                    BranchingBehavior branchingBehavior = new BranchingBehavior(probabilities);
                    branchingBehaviors.put(nodeId, branchingBehavior);
                }
            }
        }
    }
    // Store all branching behaviors collected for that task.
    HashMap<String, Object> extensionAttributes = new HashMap<String, Object>();
    extensionAttributes.put("branchingBehaviors", branchingBehaviors);
    return extensionAttributes;
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) HashMap(java.util.HashMap) BranchingBehavior(de.hpi.bpt.scylla.model.configuration.BranchingBehavior) Element(org.jdom2.Element) Namespace(org.jdom2.Namespace) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) TimeDistributionWrapper(de.hpi.bpt.scylla.model.configuration.distribution.TimeDistributionWrapper)

Example 27 with ScyllaValidationException

use of de.hpi.bpt.scylla.exception.ScyllaValidationException in project scylla by bptlab.

the class BPMNErrorBPMNEEPlugin method eventRoutine.

@Override
public void eventRoutine(BPMNEndEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    SimulationModel model = (SimulationModel) desmojEvent.getModel();
    ProcessModel processModel = processInstance.getProcessModel();
    int nodeId = desmojEvent.getNodeId();
    Map<EventDefinitionType, Map<String, String>> definitions = processModel.getEventDefinitions().get(nodeId);
    ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
    boolean showInTrace = model.traceIsOn();
    try {
        for (EventDefinitionType definition : definitions.keySet()) {
            if (definition == EventDefinitionType.ERROR) {
                if (processModel.getParent() != null) {
                    Map<String, String> eventAttributes = processModel.getEventDefinitions().get(nodeId).get(definition);
                    String errorRef = eventAttributes.get("errorRef");
                    // Map<String, Map<String, String>> errors = model.getCommonProcessElements().getErrors();
                    // Map<String, String> error = errors.get("errorRef");
                    ProcessSimulationComponents parentDesmojObjects = desmojObjects.getParent();
                    ProcessModel parentModel = processModel.getParent();
                    int nodeIdInParent = processModel.getNodeIdInParent();
                    Integer nextNodeId = null;
                    // find boundary event of parentModel which has the same errorRef
                    List<Integer> referencesToBoundaryEvents = parentModel.getReferencesToBoundaryEvents().get(nodeIdInParent);
                    for (int nId : referencesToBoundaryEvents) {
                        Map<EventDefinitionType, Map<String, String>> boundaryEventDefinitions = parentModel.getEventDefinitions().get(nId);
                        Map<String, String> boundaryErrorEventDefinition = boundaryEventDefinitions.get(EventDefinitionType.ERROR);
                        if (boundaryErrorEventDefinition != null) {
                            if (errorRef.equals(boundaryErrorEventDefinition.get("errorRef"))) {
                                nextNodeId = nId;
                                break;
                            }
                        }
                    }
                    if (nextNodeId == null) {
                        DebugLogger.error("Could not find referenced error " + errorRef + ".");
                        SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
                        return;
                    }
                    ProcessInstance parentProcessInstance = processInstance.getParent();
                    List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(desmojEvent, parentDesmojObjects, parentProcessInstance, nextNodeId);
                    TimeSpan timeSpan = new TimeSpan(0);
                    /**
                     * first event in the map is the node that comes after the subprocess when normal behavior
                     * applies, so remove it;
                     */
                    int indexOfTaskTerminateEvent = 0;
                    desmojEvent.getNextEventMap().remove(indexOfTaskTerminateEvent);
                    desmojEvent.getTimeSpanToNextEventMap().remove(indexOfTaskTerminateEvent);
                    for (ScyllaEvent event : events) {
                        int index = desmojEvent.getNewEventIndex();
                        desmojEvent.getNextEventMap().put(index, event);
                        desmojEvent.getTimeSpanToNextEventMap().put(index, timeSpan);
                    }
                    processInstance.cancel();
                }
            }
        }
    } catch (NodeNotFoundException | ScyllaValidationException e) {
        DebugLogger.error(e.getMessage());
        e.printStackTrace();
        SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
    }
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) EventDefinitionType(de.hpi.bpt.scylla.model.process.node.EventDefinitionType) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) 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) Map(java.util.Map) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Aggregations

ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)27 ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)23 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)17 SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)15 Element (org.jdom2.Element)11 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)10 TimeSpan (desmoj.core.simulator.TimeSpan)8 Map (java.util.Map)8 HashMap (java.util.HashMap)7 Namespace (org.jdom2.Namespace)7 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)6 GatewayType (de.hpi.bpt.scylla.model.process.node.GatewayType)6 ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)5 ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)5 ArrayList (java.util.ArrayList)4 List (java.util.List)4 ProcessNodeInfo (de.hpi.bpt.scylla.logger.ProcessNodeInfo)3 BranchingBehavior (de.hpi.bpt.scylla.model.configuration.BranchingBehavior)3 SimulationConfiguration (de.hpi.bpt.scylla.model.configuration.SimulationConfiguration)3 TaskType (de.hpi.bpt.scylla.model.process.node.TaskType)3