Search in sources :

Example 1 with SimulationModel

use of de.hpi.bpt.scylla.simulation.SimulationModel in project scylla by bptlab.

the class BatchClusterStartEvent method eventRoutine.

@Override
public void eventRoutine(BatchCluster cluster) throws SuspendExecution {
    BatchActivity activity = cluster.getBatchActivity();
    int nodeId = activity.getNodeId();
    List<TaskBeginEvent> parentalStartEvents = cluster.getParentalStartEvents();
    // Schedule all task begin events of the process instance
    for (TaskBeginEvent pse : parentalStartEvents) {
        ProcessInstance pi = pse.getProcessInstance();
        pse.schedule(pi);
    }
    // schedule subprocess start events for all process instances in parent
    // processInstances and parentalStartEvents are ordered the same way
    // Set the responsible process instance in the batch cluster, first one by default
    cluster.setResponsibleProcessInstance(parentalStartEvents.get(0).getProcessInstance());
    // Go through all process instances. If it's the first one, schedule it. If not, save it to be scheduled later on
    for (int j = 0; j < parentalStartEvents.size(); j++) {
        TaskBeginEvent startEvent = parentalStartEvents.get(j);
        ProcessInstance responsibleProcessInstance = startEvent.getProcessInstance();
        int processInstanceId = responsibleProcessInstance.getId();
        boolean showInTrace = responsibleProcessInstance.traceIsOn();
        SimulationModel model = (SimulationModel) responsibleProcessInstance.getModel();
        String source = startEvent.getSource();
        TimeInstant currentSimulationTime = cluster.presentTime();
        ProcessSimulationComponents pSimComponentsOfSubprocess = cluster.getProcessSimulationComponents().getChildren().get(nodeId);
        ProcessModel subprocess = pSimComponentsOfSubprocess.getProcessModel();
        try {
            Integer startNodeId = subprocess.getStartNode();
            ProcessInstance subprocessInstance = new ProcessInstance(model, subprocess, processInstanceId, showInTrace);
            subprocessInstance.setParent(responsibleProcessInstance);
            ScyllaEvent subprocessEvent = new BPMNStartEvent(model, source, currentSimulationTime, pSimComponentsOfSubprocess, subprocessInstance, startNodeId);
            System.out.println("Created BPMNStartEvent for PI " + subprocessInstance.getId() + " / " + responsibleProcessInstance.getId() + " in Batch Cluster");
            if (j == 0) {
                // If it is the first process instance, schedule it...
                subprocessEvent.schedule(subprocessInstance);
                cluster.setStartNodeId(startNodeId);
            } else {
                // ...if not, save them for later
                cluster.addPIEvent(startNodeId, subprocessEvent, subprocessInstance);
            }
        } catch (NodeNotFoundException | MultipleStartNodesException | NoStartNodeException e) {
            DebugLogger.log("Start node of process model " + subprocess.getId() + " not found.");
            System.err.println(e.getMessage());
            e.printStackTrace();
            SimulationUtils.abort(model, responsibleProcessInstance, nodeId, traceIsOn());
            return;
        }
    }
    // move batch cluster from list of not started ones to running ones
    BatchPluginUtils pluginInstance = BatchPluginUtils.getInstance();
    pluginInstance.setClusterToRunning(cluster);
// next node and timespan to next event determined by responsible process instance
// tasks resources only assigned to responsible subprocess instance
// only responsible subprocess instance is simulated
// other subprocess instances of batch are covered in process logs
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) TaskBeginEvent(de.hpi.bpt.scylla.simulation.event.TaskBeginEvent) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) MultipleStartNodesException(de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException) 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 2 with SimulationModel

use of de.hpi.bpt.scylla.simulation.SimulationModel in project scylla by bptlab.

the class BatchPluginUtils method getDataViewOfInstance.

private Map<String, Object> getDataViewOfInstance(TaskBeginEvent desmojEvent, ProcessInstance processInstance, BatchActivity batchActivity) {
    if (batchActivity.getGroupingCharacteristic().isEmpty()) {
        return null;
    } else {
        // ***********
        // get the value of the dataObject
        // ***********
        ProcessModel processModel = processInstance.getProcessModel();
        ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
        int nodeId = desmojEvent.getNodeId();
        boolean showInTrace = desmojEvent.traceIsOn();
        SimulationModel model = (SimulationModel) desmojEvent.getModel();
        try {
            // ***************************
            // GET INPUT
            // ***************************
            // fetch all available data objects
            Map<Integer, Object> dataObjects = (Map<Integer, Object>) desmojObjects.getExtensionDistributions().get(DataObjectPluginUtils.PLUGIN_NAME);
            Map<String, Object> simulationInput = new HashMap<String, Object>();
            // iterate over all available data objects
            for (int dataObjectId : dataObjects.keySet()) {
                // fetch all data fields
                Map<String, DataObjectField> dataObjectFields = (Map<String, DataObjectField>) dataObjects.get(dataObjectId);
                String dataObjectName = processModel.getDisplayNames().get(dataObjectId);
                for (String fieldName : dataObjectFields.keySet()) {
                    // create the key by concatenating dataObjectName + fieldName and assure that the first letter is lower case
                    String key = dataObjectName + "." + fieldName;
                    // handle the distribution of every data field
                    DataObjectField dataObjectField = dataObjectFields.get(fieldName);
                    DataDistributionWrapper distWrapper = dataObjectField.getDataDistributionWrapper();
                    try {
                        simulationInput.put(key, distWrapper.getSample());
                    } catch (ScyllaRuntimeException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            Map<String, Object> dataView = new HashMap<String, Object>();
            for (String dataViewElement : batchActivity.getGroupingCharacteristic()) {
                dataView.put(dataViewElement, simulationInput.get(dataViewElement));
            }
            return dataView;
        } catch (ScyllaValidationException e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
            SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
            return null;
        }
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) HashMap(java.util.HashMap) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) DataObjectField(de.hpi.bpt.scylla.plugin.dataobject.DataObjectField) ResourceObject(de.hpi.bpt.scylla.simulation.ResourceObject) DataDistributionWrapper(de.hpi.bpt.scylla.plugin.dataobject.DataDistributionWrapper) HashMap(java.util.HashMap) Map(java.util.Map) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 3 with SimulationModel

use of de.hpi.bpt.scylla.simulation.SimulationModel in project scylla by bptlab.

the class BoundaryEventPluginUtils method createTimerBoundaryEvents.

// I did not touch this for now. Hopefully could be deleted in future.
private void createTimerBoundaryEvents(SimulationModel model, BoundaryObject bo, double startOfInterval, double endOfInterval) throws ScyllaRuntimeException {
    double beginTimeOfTask = bo.getBeginTimeOfTask();
    ProcessSimulationComponents desmojObjects = bo.getDesmojObjects();
    ProcessModel processModel = desmojObjects.getProcessModel();
    Map<Integer, EventType> eventTypes = processModel.getEventTypes();
    Map<Integer, Boolean> cancelActivities = processModel.getCancelActivities();
    List<Integer> referenceToBoundaryEvents = bo.getReferenceToBoundaryEvents();
    for (Integer nId : referenceToBoundaryEvents) {
        boolean timerEventIsInterrupting = false;
        EventType eventType = eventTypes.get(nId);
        if (eventType == EventType.BOUNDARY) {
            Map<EventDefinitionType, Map<String, String>> eventDefinitions = processModel.getEventDefinitions().get(nId);
            Map<String, String> definitionAttributes = eventDefinitions.get(EventDefinitionType.TIMER);
            if (definitionAttributes != null) {
                // if boundary event is timer event
                double timeUntilWhenTimerEventsAreCreated = bo.getTimeUntilWhenTimerEventsAreCreated();
                if (definitionAttributes.get("timeDuration") != null) {
                    // ISO 8601 duration
                    String timeDuration = definitionAttributes.get("timeDuration");
                    if (beginTimeOfTask != timeUntilWhenTimerEventsAreCreated) {
                        // timer event has already been created once, skip
                        continue;
                    }
                    Duration javaDuration = Duration.parse(timeDuration);
                    double duration = javaDuration.get(ChronoUnit.SECONDS);
                    if (duration == 0) {
                        continue;
                    }
                    double timeToSchedule = beginTimeOfTask + duration;
                    if (timeToSchedule < endOfInterval) {
                        String displayName = processModel.getDisplayNames().get(nId);
                        if (displayName == null) {
                            displayName = processModel.getIdentifiers().get(nId);
                        }
                        String source = bo.getSource();
                        ProcessInstance processInstance = bo.getProcessInstance();
                        TimeInstant timeInstant = new TimeInstant(startOfInterval, TimeUnit.SECONDS);
                        BPMNIntermediateEvent event = new BPMNIntermediateEvent(model, source, timeInstant, desmojObjects, processInstance, nId);
                        bo.getBoundaryEventsToSchedule().computeIfAbsent(timeToSchedule, k -> new ArrayList<BPMNIntermediateEvent>());
                        bo.getBoundaryEventsToSchedule().get(timeToSchedule).add(event);
                        String message = "Schedule boundary timer event: " + displayName;
                        bo.getMessagesOfBoundaryEventsToSchedule().computeIfAbsent(timeToSchedule, k -> new ArrayList<String>());
                        bo.getMessagesOfBoundaryEventsToSchedule().get(timeToSchedule).add(message);
                    // timeUntilWhenTimerEventsAreCreated = timeToSchedule;
                    }
                    // TODO fix boundary
                    timeUntilWhenTimerEventsAreCreated = timeToSchedule;
                } else if (definitionAttributes.get("timeCycle") != null) {
                    // ISO 8601 repeating time interval:
                    String timeCycle = definitionAttributes.get("timeCycle");
                    // Rn/[ISO 8601 duration] where n
                    // (optional) for number of
                    // recurrences
                    // ["Rn"], "[ISO 8601 duration]"]
                    String[] recurrencesAndDuration = timeCycle.split("/");
                    String recurrencesString = recurrencesAndDuration[0];
                    String timeDurationString = recurrencesAndDuration[1];
                    Integer recurrencesMax = null;
                    if (recurrencesString.length() > 1) {
                        recurrencesMax = Integer.parseInt(recurrencesString.substring(1, recurrencesString.length()));
                        timerEventIsInterrupting = cancelActivities.get(nId);
                        if (timerEventIsInterrupting) {
                            recurrencesMax = 1;
                        }
                    }
                    Duration javaDuration = Duration.parse(timeDurationString);
                    double duration = javaDuration.get(ChronoUnit.SECONDS);
                    if (duration == 0 || recurrencesMax != null && recurrencesMax == 0) {
                        continue;
                    }
                    double timeToSchedule = beginTimeOfTask;
                    int actualNumberOfOccurrences = 0;
                    boolean recurrencesMaxExceeded = false;
                    while (timeToSchedule <= timeUntilWhenTimerEventsAreCreated) {
                        timeToSchedule += duration;
                        actualNumberOfOccurrences++;
                        if (recurrencesMax != null && actualNumberOfOccurrences > recurrencesMax) {
                            recurrencesMaxExceeded = true;
                            break;
                        }
                    }
                    if (recurrencesMaxExceeded) {
                        continue;
                    }
                    while (timeToSchedule <= endOfInterval) {
                        // add as many timer events for scheduling as possible (lots of them if timer event is
                        // non-interrupting,
                        // only one if it is interrupting
                        String displayName = processModel.getDisplayNames().get(nId);
                        if (displayName == null) {
                            displayName = processModel.getIdentifiers().get(nId);
                        }
                        String source = bo.getSource();
                        ProcessInstance processInstance = bo.getProcessInstance();
                        TimeInstant timeInstant = new TimeInstant(startOfInterval, TimeUnit.SECONDS);
                        BPMNIntermediateEvent event = new BPMNIntermediateEvent(model, source, timeInstant, desmojObjects, processInstance, nId);
                        bo.getBoundaryEventsToSchedule().computeIfAbsent(timeToSchedule, k -> new ArrayList<BPMNIntermediateEvent>());
                        bo.getBoundaryEventsToSchedule().get(timeToSchedule).add(event);
                        String message = "Schedule boundary timer event: " + displayName;
                        bo.getMessagesOfBoundaryEventsToSchedule().computeIfAbsent(timeToSchedule, k -> new ArrayList<String>());
                        bo.getMessagesOfBoundaryEventsToSchedule().get(timeToSchedule).add(message);
                        actualNumberOfOccurrences++;
                        if (recurrencesMax != null && actualNumberOfOccurrences == recurrencesMax) {
                            // recurrencesMaxExceeded = true;
                            break;
                        }
                        timeToSchedule += duration;
                    }
                    timeUntilWhenTimerEventsAreCreated = timeToSchedule;
                } else {
                    // TODO support timeDate attributes?
                    String identifier = processModel.getIdentifiers().get(nId);
                    DebugLogger.log("Timer event " + identifier + " has no timer definition, skip.");
                    continue;
                }
                bo.setTimeUntilWhenTimerEventsAreCreated(timeUntilWhenTimerEventsAreCreated);
            }
        }
    }
}
Also used : SimulationUtils(de.hpi.bpt.scylla.simulation.utils.SimulationUtils) Entity(desmoj.core.simulator.Entity) HashMap(java.util.HashMap) DiscreteDistEmpirical(desmoj.core.dist.DiscreteDistEmpirical) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) BPMNIntermediateEvent(de.hpi.bpt.scylla.simulation.event.BPMNIntermediateEvent) EventType(de.hpi.bpt.scylla.model.process.node.EventType) Duration(java.time.Duration) Map(java.util.Map) DebugLogger(de.hpi.bpt.scylla.logger.DebugLogger) EventDefinitionType(de.hpi.bpt.scylla.model.process.node.EventDefinitionType) TimeSpan(desmoj.core.simulator.TimeSpan) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) TimeInstant(desmoj.core.simulator.TimeInstant) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel) Iterator(java.util.Iterator) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) Set(java.util.Set) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ChronoUnit(java.time.temporal.ChronoUnit) TreeMap(java.util.TreeMap) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) 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) ArrayList(java.util.ArrayList) Duration(java.time.Duration) BPMNIntermediateEvent(de.hpi.bpt.scylla.simulation.event.BPMNIntermediateEvent) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) TimeInstant(desmoj.core.simulator.TimeInstant)

Example 4 with SimulationModel

use of de.hpi.bpt.scylla.simulation.SimulationModel in project scylla by bptlab.

the class BoundaryEventPluginUtils method createAndScheduleBoundaryEvents.

void createAndScheduleBoundaryEvents(ScyllaEvent event, TimeSpan timeSpan) throws ScyllaRuntimeException {
    double startOfInterval = event.presentTime().getTimeAsDouble(TimeUnit.SECONDS);
    double endOfInterval = startOfInterval + timeSpan.getTimeAsDouble(TimeUnit.SECONDS);
    SimulationModel model = (SimulationModel) event.getModel();
    // First create all the corresponding boundary events and then schedule them.
    if (startOfInterval < endOfInterval) {
        createBoundaryEvents(model, startOfInterval, endOfInterval, event);
        scheduleBoundaryEvents(model, startOfInterval, endOfInterval);
    } else {
        // ==
        // double nextEventTime = getNextEventTime(event); //Why would you take this, better take getTimeSpanToNextEventMap()
        double nextEventTime = startOfInterval + event.getTimeSpanToNextEventMap().get(0).getTimeAsDouble(TimeUnit.SECONDS);
        createBoundaryEvents(model, startOfInterval, nextEventTime, event);
        scheduleBoundaryEvents(model, startOfInterval, nextEventTime);
    }
// Moved to BoundaryIntermediateEventPlugin, events determinate if the should be cancelled
// int nodeId = event.getNodeId();
// ProcessInstance processInstance = event.getProcessInstance();
// ProcessModel processModel = processInstance.getProcessModel();
// Boolean isCancelActivity = processModel.getCancelActivities().get(nodeId);
// if (isCancelActivity != null && isCancelActivity) {
// event.getProcessInstance().cancel();
// }
}
Also used : SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 5 with SimulationModel

use of de.hpi.bpt.scylla.simulation.SimulationModel in project scylla by bptlab.

the class DataObjectTaskTerminate method eventRoutine.

@SuppressWarnings("unchecked")
@Override
public /* collect all fields of all dataobjects and simulate them with the given desmoj distribution. After that, pass them to the XES Logger */
void eventRoutine(TaskTerminateEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    ProcessModel processModel = processInstance.getProcessModel();
    // int processInstanceId = processInstance.getId();
    try {
        if (processModel.getDataObjectsGraph().getNodes().containsKey(desmojEvent.getNodeId())) {
            Set<Integer> refferingObjects = processModel.getDataObjectsGraph().getTargetObjects(desmojEvent.getNodeId());
            Collection<Object> allFields = desmojEvent.getDesmojObjects().getExtensionDistributions().get("dataobject").values();
            for (Object fields : allFields) {
                Integer i = 0;
                while (((Map<String, Map<Integer, DataObjectField>>) fields).values().toArray().length - i != 0) {
                    DataObjectField field = (DataObjectField) ((Map<String, Map<Integer, DataObjectField>>) fields).values().toArray()[i];
                    if (refferingObjects.contains(field.getNodeId())) {
                        // System.out.println(processInstance.getId() + " " + desmojEvent.getDisplayName() + " " + processModel.getDisplayNames().get(field.getNodeId()) + " " + field.getDataDistributionWrapper().getSample());
                        SimulationModel model = (SimulationModel) desmojEvent.getModel();
                        Collection<Map<Integer, java.util.List<ProcessNodeInfo>>> allProcesses = model.getProcessNodeInfos().values();
                        for (Map<Integer, java.util.List<ProcessNodeInfo>> process : allProcesses) {
                            List<ProcessNodeInfo> currentProcess = process.get(processInstance.getId());
                            for (ProcessNodeInfo task : currentProcess) {
                                // System.out.println(processModel.getDisplayNames().get(processModel.getDataObjectsGraph().getSourceObjects(field.getNodeId()).toArray()[0]) + " " + task.getTaskName());
                                for (Integer j = 0; j < processModel.getDataObjectsGraph().getSourceObjects(field.getNodeId()).toArray().length; j++) {
                                    if (task.getId().equals(processModel.getDataObjectsGraph().getSourceObjects(field.getNodeId()).toArray()[j]) && task.getTransition() == ProcessNodeTransitionType.TERMINATE) {
                                        // check all tasks and find the ones that may be looged; already logged ones will get ignored next line
                                        if (!task.getDataObjectField().containsKey(processModel.getDisplayNames().get(field.getNodeId()) + "." + field.getFieldName())) {
                                            // don't log if task already has this field logged
                                            Map<String, Object> fieldSample = new HashMap<String, Object>();
                                            Object currentSample = field.getDataDistributionWrapper().getSample();
                                            // log Value at TaskTerminate
                                            fieldSample.put(processModel.getDisplayNames().get(field.getNodeId()) + "." + field.getFieldName(), currentSample);
                                            task.SetDataObjectField(fieldSample);
                                            // set current DataObjectFieldValue
                                            DataObjectField.addDataObjectValue(processInstance.getId(), fieldSample.keySet().toArray()[0].toString(), currentSample);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    i++;
                }
            }
        } else {
        // do nothing and continue with the next task because Node has no dataobejcts
        }
    } catch (ScyllaRuntimeException | ScyllaValidationException | NodeNotFoundException e) {
        e.printStackTrace();
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) HashMap(java.util.HashMap) ProcessNodeInfo(de.hpi.bpt.scylla.logger.ProcessNodeInfo) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Aggregations

SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)48 ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)41 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)21 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)17 TimeSpan (desmoj.core.simulator.TimeSpan)17 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)15 Map (java.util.Map)15 ProcessNodeInfo (de.hpi.bpt.scylla.logger.ProcessNodeInfo)13 ProcessInstance (de.hpi.bpt.scylla.simulation.ProcessInstance)12 HashSet (java.util.HashSet)12 TimeInstant (desmoj.core.simulator.TimeInstant)11 ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)10 ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)8 HashMap (java.util.HashMap)8 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)7 ProcessNodeTransitionType (de.hpi.bpt.scylla.logger.ProcessNodeTransitionType)6 SimulationConfiguration (de.hpi.bpt.scylla.model.configuration.SimulationConfiguration)6 ResourceObject (de.hpi.bpt.scylla.simulation.ResourceObject)6 GatewayType (de.hpi.bpt.scylla.model.process.node.GatewayType)5 TimeUnit (java.util.concurrent.TimeUnit)5