use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class BatchBPMNEEPlugin method eventRoutine.
@Override
public void eventRoutine(BPMNEndEvent event, ProcessInstance processInstance) throws ScyllaRuntimeException {
BatchPluginUtils pluginInstance = BatchPluginUtils.getInstance();
pluginInstance.logBPMNEventForNonResponsiblePI(event, processInstance);
// Schedule parental end events
ProcessInstance parentProcessInstance = processInstance.getParent();
if (parentProcessInstance != null) {
ProcessModel processModel = processInstance.getProcessModel();
int parentNodeId = processModel.getNodeIdInParent();
BatchCluster cluster = pluginInstance.getRunningCluster(parentProcessInstance, parentNodeId);
if (cluster != null) {
cluster.setProcessInstanceToFinished();
// Schedule them only if either all process instances has passed the last event of the batch activity or the execution type is parallel
if (cluster.areAllProcessInstancesFinished() || cluster.hasExecutionType(BatchClusterExecutionType.PARALLEL)) {
if (pluginInstance.isProcessInstanceCompleted(processInstance)) {
List<TaskTerminateEvent> parentalEndEvents = cluster.getParentalEndEvents();
for (TaskTerminateEvent pee : parentalEndEvents) {
ProcessInstance pi = pee.getProcessInstance();
pee.schedule(pi);
}
parentalEndEvents.clear();
pluginInstance.setClusterToTerminated(parentProcessInstance, parentNodeId);
}
// Prevent parental task terminate event from scheduling, if there is any (from subprocess plugin)
Map<Integer, ScyllaEvent> nextEventMap = event.getNextEventMap();
if (!nextEventMap.isEmpty()) {
Map<Integer, TimeSpan> timeSpanToNextEventMap = event.getTimeSpanToNextEventMap();
int indexOfParentalTaskTerminateEvent = 0;
nextEventMap.remove(indexOfParentalTaskTerminateEvent);
timeSpanToNextEventMap.remove(indexOfParentalTaskTerminateEvent);
}
} else if (cluster.hasExecutionType(BatchClusterExecutionType.SEQUENTIAL_CASEBASED)) {
// Schedule the next start event
pluginInstance.scheduleNextCaseInBatchProcess(cluster);
}
}
}
}
use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class BatchTBPlugin method eventRoutine.
@SuppressWarnings("unchecked")
@Override
public void eventRoutine(TaskBeginEvent event, ProcessInstance processInstance) throws ScyllaRuntimeException {
// System.out.println(event + " with display name " + event.getDisplayName() + " || " + event.getNextEventMap() + " and source " + event.getSource());
BatchPluginUtils pluginInstance = BatchPluginUtils.getInstance();
pluginInstance.logTaskEventForNonResponsiblePI(event, processInstance);
ProcessSimulationComponents desmojObjects = event.getDesmojObjects();
// SimulationModel model = (SimulationModel) desmojEvent.getModel();
int nodeId = event.getNodeId();
ProcessModel processModel = processInstance.getProcessModel();
ProcessInstance parentProcessInstance = processInstance.getParent();
if (parentProcessInstance != null) {
int parentNodeId = processModel.getNodeIdInParent();
BatchCluster cluster = pluginInstance.getRunningCluster(parentProcessInstance, parentNodeId);
// If we are the representative (first executed) process instance we add the setUp time for this task
if (cluster != null && parentProcessInstance == cluster.getResponsibleProcessInstance()) {
// therefore we fist take a sample of the setUp distribution
double setUpTimeToAdd = desmojObjects.getSetUpDistributionSample(nodeId);
TimeUnit unit = desmojObjects.getSetUpDistributionTimeUnit(nodeId);
TimeSpan setUpTimeToAddAsTimeSpan = new TimeSpan(setUpTimeToAdd, unit);
// get the old value (this will always be the entry 0 in our map, because it's always the next)
double standardTime = event.getTimeSpanToNextEventMap().get(0).getTimeAsDouble(TimeUnit.SECONDS);
// and overwrite the time to the next task in the timeSpanToNextEventMap (=set the calculated time as the new time)
TimeSpan timeForTaskWithSetUp = new TimeSpan(standardTime + setUpTimeToAddAsTimeSpan.getTimeAsDouble(TimeUnit.SECONDS), TimeUnit.SECONDS);
event.getTimeSpanToNextEventMap().put(0, timeForTaskWithSetUp);
}
}
// SimulationConfiguration simulationConfiguration = desmojObjects.getSimulationConfiguration();
/*Map<Integer, BatchActivity> batchActivities = (Map<Integer, BatchActivity>) simulationConfiguration
.getExtensionValue(getName(), "batchActivities");*/
Map<Integer, BatchActivity> batchActivities = processModel.getBatchActivities();
if (batchActivities.containsKey(nodeId) && processModel.getSubProcesses().containsKey(nodeId)) {
// subprocess plugin wants to schedule BPMNStartEvents for subprocess
// we prevent it
Map<Integer, ScyllaEvent> nextEventMap = event.getNextEventMap();
Map<Integer, TimeSpan> timeSpanToNextEventMap = event.getTimeSpanToNextEventMap();
for (Integer indexOfSubprocessBPMNStartEvent : nextEventMap.keySet()) {
ScyllaEvent eventToSchedule = nextEventMap.get(indexOfSubprocessBPMNStartEvent);
if (eventToSchedule instanceof BPMNStartEvent || eventToSchedule instanceof TaskTerminateEvent) {
nextEventMap.remove(indexOfSubprocessBPMNStartEvent);
timeSpanToNextEventMap.remove(indexOfSubprocessBPMNStartEvent);
break;
}
}
}
}
use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class BatchTEPlugin method eventRoutine.
@SuppressWarnings("unchecked")
@Override
public void eventRoutine(TaskEnableEvent event, ProcessInstance processInstance) throws ScyllaRuntimeException {
BatchPluginUtils pluginInstance = BatchPluginUtils.getInstance();
pluginInstance.logTaskEventForNonResponsiblePI(event, processInstance);
// ProcessSimulationComponents desmojObjects = event.getDesmojObjects();
// SimulationModel model = (SimulationModel) desmojEvent.getModel();
int nodeId = event.getNodeId();
ProcessModel processModel = processInstance.getProcessModel();
// SimulationConfiguration simulationConfiguration = desmojObjects.getSimulationConfiguration();
/*Map<Integer, BatchActivity> batchActivities = (Map<Integer, BatchActivity>) simulationConfiguration
.getExtensionValue(getName(), "batchActivities");*/
Map<Integer, BatchActivity> batchActivities = processModel.getBatchActivities();
if (batchActivities.containsKey(nodeId) && processModel.getSubProcesses().containsKey(nodeId)) {
// in any case: put taskbeginevent of subprocess container on hold
// String source = desmojEvent.getSource();
int indexOfSubprocessBeginEvent = 0;
Map<Integer, ScyllaEvent> nextEventMap = event.getNextEventMap();
Map<Integer, TimeSpan> timeSpanToNextEventMap = event.getTimeSpanToNextEventMap();
// Map<String, TaskBeginEvent> subprocessStartEventsOnHold =
// pluginInstance.getSubprocessStartEventsOnHold();
TaskBeginEvent subprocessBeginEvent = (TaskBeginEvent) nextEventMap.get(indexOfSubprocessBeginEvent);
pluginInstance.assignToBatchCluster(processInstance, nodeId, subprocessBeginEvent);
nextEventMap.remove(indexOfSubprocessBeginEvent);
timeSpanToNextEventMap.remove(indexOfSubprocessBeginEvent);
}
}
use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class BoundaryEventPluginUtils method createNonTimerBoundaryEvents.
private void createNonTimerBoundaryEvents(SimulationModel model, BoundaryObject bo, double startOfInterval, double endOfInterval) throws ScyllaRuntimeException {
double timeUntilWhenNonTimerEventsAreCreated = bo.getTimeUntilWhenNonTimerEventsAreCreated();
if (!bo.isGenerateMoreNonTimerBoundaryEvents() || timeUntilWhenNonTimerEventsAreCreated >= endOfInterval) {
return;
}
ProcessSimulationComponents desmojObjects = bo.getDesmojObjects();
ProcessModel processModel = desmojObjects.getProcessModel();
Map<Integer, EventType> eventTypes = processModel.getEventTypes();
Map<Integer, Boolean> cancelActivities = processModel.getCancelActivities();
int nodeId = bo.getNodeId();
while (timeUntilWhenNonTimerEventsAreCreated < endOfInterval) {
// If the parent task has not already ended...
// simulation configuration defines probability of firing boundary events
Map<Integer, Object> branchingDistributions = desmojObjects.getExtensionDistributions().get(PLUGIN_NAME);
@SuppressWarnings("unchecked") DiscreteDistEmpirical<Integer> distribution = (DiscreteDistEmpirical<Integer>) branchingDistributions.get(nodeId);
if (distribution == null) {
// There are no non-timer boundary events at this task...
bo.setGenerateMoreNonTimerBoundaryEvents(false);
return;
}
// decide on next node
model.skipTraceNote();
Integer nodeIdOfElementToSchedule = distribution.sample();
// System.out.println("Choosed: "+processModel.getIdentifiers().get(nodeIdOfElementToSchedule)+" "+processModel.getIdentifiers().get(nodeId));
if (nodeIdOfElementToSchedule == nodeId) {
// No next boundary non-timer event, finish
bo.setGenerateMoreNonTimerBoundaryEvents(false);
return;
} else {
// There are boundary events
EventType eventType = eventTypes.get(nodeIdOfElementToSchedule);
if (eventType == EventType.BOUNDARY) {
// Determine whether the boundary event to schedule is an interrupting one.
boolean eventIsInterrupting = cancelActivities.get(nodeIdOfElementToSchedule);
// Get time relative to the start of the task when this boundary event will trigger.
double relativeTimeToTrigger = desmojObjects.getDistributionSample(nodeIdOfElementToSchedule);
if (relativeTimeToTrigger == 0) {
// If this happens something is wrong anyways...
continue;
}
// Add the relative time of this boundary event, to determine when no more events are scheduled.
TimeUnit unit = desmojObjects.getDistributionTimeUnit(nodeIdOfElementToSchedule);
TimeSpan durationAsTimeSpan = new TimeSpan(relativeTimeToTrigger, unit);
timeUntilWhenNonTimerEventsAreCreated += durationAsTimeSpan.getTimeAsDouble(TimeUnit.SECONDS);
// Took this message sending part out. It was just to complicated for boundary events, fixed to their parent task.
// Furthermore it is not needed anymore.
/*String message = null;
boolean showInTrace = model.traceIsOn();
Map<EventDefinitionType, Map<String, String>> definitions = processModel.getEventDefinitions().get(nodeIdOfElementToSchedule);
String displayName = processModel.getDisplayNames().get(nodeIdOfElementToSchedule);
if (displayName == null) {
displayName = processModel.getIdentifiers().get(nodeIdOfElementToSchedule);
}
for (EventDefinitionType definition : definitions.keySet()) {
if (definition == EventDefinitionType.MESSAGE) {
message = "Schedule boundary message event: " + displayName;
}
else if (definition == EventDefinitionType.CONDITIONAL) {
message = "Schedule boundary conditional event: " + displayName;
}
else if (definition == EventDefinitionType.SIGNAL) {
message = "Schedule boundary signal event: " + displayName;
}
else if (definition == EventDefinitionType.ESCALATION) {
message = "Schedule boundary escalation event: " + displayName;
}
else {
if (eventIsInterrupting) {
if (definition == EventDefinitionType.ERROR) {
message = "Schedule boundary error event: " + displayName;
}
else if (definition == EventDefinitionType.COMPENSATION) {
message = "Schedule boundary compensation event: " + displayName;
}
else if (definition == EventDefinitionType.CANCEL) {
message = "Schedule boundary cancel event: " + displayName;
}
}
else {
SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName,
nodeIdOfElementToSchedule);
SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
String identifier = processModel.getIdentifiers().get(nodeIdOfElementToSchedule);
throw new ScyllaRuntimeException("BPMNEvent " + identifier + " not supported.");
}
}*
bo.getMessagesOfBoundaryEventsToSchedule().computeIfAbsent(timeUntilWhenNonTimerEventsAreCreated,
k -> new ArrayList<String>());
bo.getMessagesOfBoundaryEventsToSchedule().get(timeUntilWhenNonTimerEventsAreCreated)
.add(message);
}
*/
String source = bo.getSource();
ProcessInstance processInstance = bo.getProcessInstance();
TimeInstant timeInstant = new TimeInstant(startOfInterval, TimeUnit.SECONDS);
// And create the event with the time it should trigger.
BPMNIntermediateEvent event = new BPMNIntermediateEvent(model, source, timeInstant, desmojObjects, processInstance, nodeIdOfElementToSchedule);
bo.getBoundaryEventsToSchedule().computeIfAbsent(timeUntilWhenNonTimerEventsAreCreated, k -> new ArrayList<BPMNIntermediateEvent>());
bo.getBoundaryEventsToSchedule().get(timeUntilWhenNonTimerEventsAreCreated).add(event);
if (eventIsInterrupting) {
// If the element is interrupting, finish and clean up
// boundaryObjects.values().remove(bo);
bo.setGenerateMoreNonTimerBoundaryEvents(false);
break;
}
}
}
}
bo.setTimeUntilWhenNonTimerEventsAreCreated(timeUntilWhenNonTimerEventsAreCreated);
}
use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class BPMNTimerPluginUtils method getTimeSpanUntilNextEvent.
/**
* Returns TimeSpan object (duration and timeUnit) representing time until next event. Available for timer events.
*
* @param processModel
* @param nodeId
* @return
* @return
*/
static TimeSpan getTimeSpanUntilNextEvent(ProcessModel processModel, int nodeId) {
TimeSpan timeSpan = null;
Map<EventDefinitionType, Map<String, String>> definitions = processModel.getEventDefinitions().get(nodeId);
if (definitions != null) {
if (definitions.get(EventDefinitionType.TIMER) != null) {
Map<String, String> eventAttributes = definitions.get(EventDefinitionType.TIMER);
// String timeDate = eventAttributes.get("timeDate");
// if (timeDate != null) {
// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
// Date date = formatter.parse(timeDate);
// }
// String timeCycle = eventAttributes.get("timeCycle");
String timeDuration = eventAttributes.get("timeDuration");
Duration jtDuration = Duration.parse(timeDuration);
long duration = jtDuration.getSeconds();
TimeUnit timeUnit = TimeUnit.SECONDS;
timeSpan = new TimeSpan(duration, timeUnit);
}
}
return timeSpan;
}
Aggregations