use of de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException in project scylla by bptlab.
the class ProcessModelParser method parse.
@Override
public ProcessModel parse(Element rootElement) throws ScyllaValidationException {
Namespace bpmnNamespace = rootElement.getNamespace();
List<Element> processElements = rootElement.getChildren("process", bpmnNamespace);
if (processElements.isEmpty()) {
throw new ScyllaValidationException("No process in file.");
}
// pool references to process models
Map<String, String> processIdToPoolName = new HashMap<String, String>();
Map<String, MessageFlow> messageFlows = new HashMap<String, MessageFlow>();
Element collaboration = rootElement.getChild("collaboration", bpmnNamespace);
if (collaboration != null) {
for (Element el : collaboration.getChildren()) {
String elementName = el.getName();
if (elementName.equals("participant")) {
if (el.getAttributeValue("processRef") != null) {
String participantName = el.getAttributeValue("name");
String processId = el.getAttributeValue("processRef");
processIdToPoolName.put(processId, participantName);
}
} else if (elementName.equals("messageFlow")) {
String id = el.getAttributeValue("id");
String sourceRef = el.getAttributeValue("sourceRef");
String targetRef = el.getAttributeValue("targetRef");
MessageFlow messageFlow = new MessageFlow(id, sourceRef, targetRef);
messageFlows.put(id, messageFlow);
} else {
DebugLogger.log("Element " + el.getName() + " of collaboration not supported.");
}
}
}
Map<String, ProcessModel> processModels = new HashMap<String, ProcessModel>();
for (Element process : processElements) {
ProcessModel processModel = parseProcess(process, bpmnNamespace, false, commonProcessElements);
String processId = processModel.getId();
if (processIdToPoolName.containsKey(processId)) {
String participant = processIdToPoolName.get(processId);
processModel.setParticipant(participant);
}
processModels.put(processId, processModel);
}
if (processModels.size() == 1) {
return processModels.values().iterator().next();
} else {
try {
Set<ProcessModel> processModelsTriggeredInCollaboration = new HashSet<ProcessModel>();
ProcessModel processModelTriggeredExternally = null;
for (String processId : processModels.keySet()) {
ProcessModel pm = processModels.get(processId);
int startNodeId = pm.getStartNode();
String identifierOfStartNode = pm.getIdentifiers().get(startNodeId);
boolean isTriggeredInCollaboration = false;
for (MessageFlow mf : messageFlows.values()) {
if (mf.getTargetRef().equals(identifierOfStartNode)) {
isTriggeredInCollaboration = true;
break;
}
}
if (isTriggeredInCollaboration) {
processModelsTriggeredInCollaboration.add(pm);
} else {
if (processModelTriggeredExternally != null) {
throw new ScyllaValidationException("BPMN file contains multiple process models that are triggered externally.");
}
processModelTriggeredExternally = pm;
}
}
processModelTriggeredExternally.setProcessModelsInCollaboration(processModelsTriggeredInCollaboration);
return processModelTriggeredExternally;
} catch (NodeNotFoundException | MultipleStartNodesException | NoStartNodeException e) {
e.printStackTrace();
throw new ScyllaValidationException(e.getMessage());
}
}
}
use of de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException 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
}
use of de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException in project scylla by bptlab.
the class BPMNTimerPIGEPlugin method eventRoutine.
@Override
public void eventRoutine(ProcessInstanceGenerationEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
SimulationModel model = (SimulationModel) desmojEvent.getModel();
String processId = desmojEvent.getProcessId();
ProcessSimulationComponents desmojObjects = model.getDesmojObjectsMap().get(processId);
ProcessModel processModel = desmojObjects.getProcessModel();
Integer startNodeId;
try {
startNodeId = processModel.getStartNode();
if (desmojObjects.getDistributions().get(startNodeId) == null) {
// no arrival rate defined, check if start event is timer event and use value from there
Map<EventDefinitionType, Map<String, String>> eventDefinitions = processModel.getEventDefinitions().get(startNodeId);
Map<String, String> definitionAttributes = eventDefinitions.get(EventDefinitionType.TIMER);
if (definitionAttributes != null) {
// if start event is timer event
// ISO 8601 duration
String timeDuration = definitionAttributes.get("timeCycle");
if (timeDuration == null) {
String identifier = processModel.getIdentifiers().get(startNodeId);
DebugLogger.log("Timer event " + identifier + " has no timer definition, skip.");
} else // TODO support timeDate and timeDuration attributes?
{
Duration javaDuration = Duration.parse(timeDuration);
long duration = javaDuration.get(ChronoUnit.SECONDS);
TimeUnit unit = TimeUnit.SECONDS;
TimeSpan timeSpan = new TimeSpan(duration, unit);
desmojEvent.setTimeSpanToNextProcessInstance(timeSpan);
}
}
}
} catch (NodeNotFoundException | MultipleStartNodesException | NoStartNodeException e) {
DebugLogger.error(e.getMessage());
DebugLogger.log("Error during instantiation of process model " + processModel.getId() + ".");
}
}
use of de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException 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.");
}
}
}
use of de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException in project scylla by bptlab.
the class ProcessInstanceGenerationEvent method eventRoutine.
// TODO XSD validation
// TODO fixed cost per task
@Override
public void eventRoutine(ProcessInstance processInstance) throws SuspendExecution {
this.processInstance = processInstance;
SimulationModel model = (SimulationModel) getModel();
TimeInstant currentSimulationTime = model.presentTime();
TimeUnit timeUnit = DateTimeUtils.getReferenceTimeUnit();
long currentTime = currentSimulationTime.getTimeRounded(timeUnit);
if (currentTime >= endTimeRelativeToGlobalStart) {
// if the end time is reached
return;
}
boolean showInTrace = traceIsOn();
String name = getName();
ProcessSimulationComponents desmojObjects = model.getDesmojObjectsMap().get(processId);
ProcessModel processModel = desmojObjects.getProcessModel();
try {
Integer startNodeId = processModel.getStartNode();
timeSpanToStartEvent = new TimeSpan(0);
ProcessInstanceGenerationEventPluggable.runPlugins(this, processInstance);
BPMNStartEvent event = new BPMNStartEvent(model, name, currentSimulationTime, desmojObjects, processInstance, startNodeId);
int processInstanceId = desmojObjects.incrementProcessInstancesStarted();
// schedule next process instance start event
if (processInstanceId <= desmojObjects.getSimulationConfiguration().getNumberOfProcessInstances()) {
double duration = desmojObjects.getDistributionSample(startNodeId);
TimeUnit unit = desmojObjects.getDistributionTimeUnit(startNodeId);
ProcessInstance nextProcessInstance = new ProcessInstance(model, processModel, processInstanceId, showInTrace);
timeSpanToNextProcessInstance = new TimeSpan(duration, unit);
ProcessInstanceGenerationEvent nextEvent = new ProcessInstanceGenerationEvent(model, processId, endTimeRelativeToGlobalStart, showInTrace);
nextEvent.schedule(nextProcessInstance, timeSpanToNextProcessInstance);
}
// schedule for start of simulation
event.schedule(processInstance, timeSpanToStartEvent);
} catch (NodeNotFoundException | MultipleStartNodesException | NoStartNodeException | ScyllaRuntimeException e) {
DebugLogger.error(e.getMessage());
e.printStackTrace();
DebugLogger.log("Error during instantiation of process model " + processModel.getId() + ".");
// no node initialized, use zero
int nodeId = 0;
SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
}
}
Aggregations