use of de.hpi.bpt.scylla.model.configuration.distribution.TimeDistributionWrapper in project scylla by bptlab.
the class ProcessSimulationComponents method setSmallestTimeUnit.
private void setSmallestTimeUnit(Map<Integer, TimeDistributionWrapper> durations) {
for (Integer nodeId : durations.keySet()) {
TimeDistributionWrapper dist = durations.get(nodeId);
TimeUnit distTimeUnit = dist.getTimeUnit();
if (distTimeUnit.ordinal() < model.getSmallestTimeUnit().ordinal()) {
model.setSmallestTimeUnit(distTimeUnit);
}
}
}
use of de.hpi.bpt.scylla.model.configuration.distribution.TimeDistributionWrapper in project scylla by bptlab.
the class SimulationConfigurationParser method parseSimulationConfiguration.
private SimulationConfiguration parseSimulationConfiguration(Element sim, Namespace simNamespace, String processIdFromSimElement, ProcessModel processModel, Long randomSeed) throws ScyllaValidationException {
Map<String, Resource> resources = simulationEnvironment.getGlobalConfiguration().getResources();
if (processModel == null) {
throw new ScyllaValidationException("Simulation configuration is for (sub)process '" + processIdFromSimElement + "', which is not found in the simulation environment.");
}
String processRef = processIdFromSimElement;
String simId = null;
Integer numberOfProcessInstances = null;
ZonedDateTime startDateTime = null;
ZonedDateTime endDateTime = null;
if (processModel.getParent() == null) {
List<Element> startEvents = sim.getChildren("startEvent", simNamespace);
if (startEvents.size() == 0)
throw new ScyllaValidationException("No definition of start event in simulation scenario.");
else {
for (Element el : startEvents) {
// it is sufficient if at least one of the start events has an arrival rate defined
if (el.getChild("arrivalRate", simNamespace) != null) {
break;
}
throw new ScyllaValidationException("No arrival rate defined in any of the start events in simulation scenario.");
}
}
// store identifier of simulation configuration only if it is for top level process
simId = sim.getAttributeValue("id");
numberOfProcessInstances = Integer.valueOf(sim.getAttributeValue("processInstances"));
startDateTime = DateTimeUtils.parse(sim.getAttributeValue("startDateTime"));
String endDateTimeString = sim.getAttributeValue("endDateTime");
if (endDateTimeString != null) {
endDateTime = DateTimeUtils.parse(endDateTimeString);
}
String randomSeedString = sim.getAttributeValue("randomSeed");
if (randomSeedString != null) {
randomSeed = Long.valueOf(sim.getAttributeValue("randomSeed"));
DebugLogger.log("Random seed for simulation configuration " + processRef + ": " + randomSeed);
}
}
Map<Integer, TimeDistributionWrapper> arrivalRates = new HashMap<Integer, TimeDistributionWrapper>();
Map<Integer, TimeDistributionWrapper> durations = new HashMap<Integer, TimeDistributionWrapper>();
Map<Integer, TimeDistributionWrapper> setUpDurations = new HashMap<Integer, TimeDistributionWrapper>();
Map<Integer, Set<ResourceReference>> resourceReferences = new HashMap<Integer, Set<ResourceReference>>();
// gateways and events
// Map<Integer, BranchingBehavior> branchingBehaviors = new HashMap<Integer, BranchingBehavior>();
Map<Integer, SimulationConfiguration> configurationsOfSubProcesses = new HashMap<Integer, SimulationConfiguration>();
// take resource definitions from process model
Map<Integer, Set<String>> resourceReferencesFromProcessModel = processModel.getResourceReferences();
for (Integer nodeId : resourceReferencesFromProcessModel.keySet()) {
Set<String> resourceRefFromModel = resourceReferencesFromProcessModel.get(nodeId);
Set<ResourceReference> resourceRefs = new HashSet<ResourceReference>();
for (String resourceId : resourceRefFromModel) {
int amount = 1;
Map<String, String> assignmentDefinition = new HashMap<String, String>();
ResourceReference resourceReference = new ResourceReference(resourceId, amount, assignmentDefinition);
resourceRefs.add(resourceReference);
}
resourceReferences.put(nodeId, resourceRefs);
}
for (Element el : sim.getChildren()) {
String elementName = el.getName();
if (isKnownElement(elementName)) {
if (elementName.equals("resources")) {
// in parent process
continue;
}
String identifier = el.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;
}
if (elementName.equals("startEvent")) {
Element elem = el.getChild("arrivalRate", simNamespace);
if (elem != null) {
TimeDistributionWrapper distribution = getTimeDistributionWrapper(elem, simNamespace);
arrivalRates.put(nodeId, distribution);
}
} else if (elementName.equals("task") || elementName.endsWith("Task") || elementName.equals("subProcess")) {
Element durationElem = el.getChild("duration", simNamespace);
if (durationElem != null) {
TimeDistributionWrapper distribution = getTimeDistributionWrapper(durationElem, simNamespace);
durations.put(nodeId, distribution);
}
Element setUpDurationElem = el.getChild("setUpDuration", simNamespace);
if (setUpDurationElem != null) {
TimeDistributionWrapper distribution = getTimeDistributionWrapper(setUpDurationElem, simNamespace);
setUpDurations.put(nodeId, distribution);
}
Element resourcesElem = el.getChild("resources", simNamespace);
if (resourcesElem != null) {
List<Element> resourceElements = resourcesElem.getChildren("resource", simNamespace);
// process model)
if (resourceElements.size() > 0) {
Set<ResourceReference> resourceRefs = new HashSet<ResourceReference>();
Set<String> resourceIdentifiers = new HashSet<String>();
for (Element elem : resourceElements) {
String resourceId = elem.getAttributeValue("id");
if (resources.get(resourceId) == null) {
throw new ScyllaValidationException("Simulation configuration " + simId + " refers to unknown resource " + resourceId + ".");
}
if (resourceIdentifiers.contains(resourceId)) {
throw new ScyllaValidationException("Simulation configuration " + simId + " defines multiple resources for task / subprocess " + identifier);
}
resourceIdentifiers.add(resourceId);
// XXX implementation currently supports more than one instance per resource. however
// BPMN standard does not support that.
// int amount = 1;
int amount = Integer.parseInt(elem.getAttributeValue("amount"));
Map<String, String> assignmentDefinition = new HashMap<String, String>();
Element assignmentDefinitionElement = elem.getChild("assignmentDefinition", simNamespace);
if (assignmentDefinitionElement != null) {
List<Element> adElements = assignmentDefinitionElement.getChildren(null, simNamespace);
for (Element adElem : adElements) {
assignmentDefinition.put(adElem.getName(), adElem.getText());
}
}
ResourceReference resourceReference = new ResourceReference(resourceId, amount, assignmentDefinition);
resourceRefs.add(resourceReference);
}
resourceReferences.put(nodeId, resourceRefs);
}
}
if (elementName.equals("subProcess")) {
ProcessModel subProcess = processModel.getSubProcesses().get(nodeId);
String subProcessIdFromSimElement = el.getAttributeValue("id");
SimulationConfiguration simulationConfiguration = parseSimulationConfiguration(el, simNamespace, subProcessIdFromSimElement, subProcess, randomSeed);
configurationsOfSubProcesses.put(nodeId, simulationConfiguration);
}
} else {
DebugLogger.log("Element " + el.getName() + " of simulation scenario is expected to be known, but not supported.");
}
} else {
DebugLogger.log("Element " + el.getName() + " of simulation scenario not supported.");
}
}
SimulationConfiguration simulationConfiguration = new SimulationConfiguration(simId, processModel, numberOfProcessInstances, startDateTime, endDateTime, randomSeed, arrivalRates, durations, setUpDurations, resourceReferences, configurationsOfSubProcesses);
return simulationConfiguration;
}
use of de.hpi.bpt.scylla.model.configuration.distribution.TimeDistributionWrapper 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;
}
Aggregations