Search in sources :

Example 1 with Resource

use of de.hpi.bpt.scylla.model.global.resource.Resource in project scylla by bptlab.

the class SimulationModel method convertToResourceObjects.

private void convertToResourceObjects(Map<String, Resource> resources) throws InstantiationException {
    resourceObjects = new HashMap<String, ResourceQueue>();
    for (String resourceType : resources.keySet()) {
        Resource resource = resources.get(resourceType);
        int quantity = resource.getQuantity();
        ResourceQueue resQueue = new ResourceQueue(quantity);
        if (resource instanceof DynamicResource) {
            DynamicResource dynResource = (DynamicResource) resource;
            Map<String, DynamicResourceInstance> resourceInstances = dynResource.getResourceInstances();
            for (String resourceInstanceName : resourceInstances.keySet()) {
                DynamicResourceInstance instance = resourceInstances.get(resourceInstanceName);
                double cost = instance.getCost();
                TimeUnit timeUnit = instance.getTimeUnit();
                List<TimetableItem> timetable = instance.getTimetable();
                ResourceObject resObject = new ResourceObject(resourceType, resourceInstanceName, cost, timeUnit, timetable);
                resQueue.add(resObject);
                boolean availableAtStart = resObject.isAvailable(startDateTime);
                SimulationUtils.scheduleNextResourceAvailableEvent(this, resObject, startDateTime, availableAtStart);
            }
        } else {
            throw new InstantiationException("Type of resource " + resourceType + " not supported.");
        }
        resourceObjects.put(resourceType, resQueue);
    }
}
Also used : DynamicResource(de.hpi.bpt.scylla.model.global.resource.DynamicResource) Resource(de.hpi.bpt.scylla.model.global.resource.Resource) DynamicResource(de.hpi.bpt.scylla.model.global.resource.DynamicResource) DynamicResourceInstance(de.hpi.bpt.scylla.model.global.resource.DynamicResourceInstance) TimeUnit(java.util.concurrent.TimeUnit) TimetableItem(de.hpi.bpt.scylla.model.global.resource.TimetableItem)

Example 2 with Resource

use of de.hpi.bpt.scylla.model.global.resource.Resource in project scylla by bptlab.

the class GlobalConfigurationParser method parse.

@Override
public GlobalConfiguration parse(Element rootElement) throws ScyllaValidationException {
    System.out.println(rootElement.getNamespace());
    Iterator<EventOrderType> eventOrderTypesIterator = PluginLoader.dGetPlugins(EventOrderType.class);
    // ServiceLoader.load(EventOrderType.class).iterator();
    // Get all event order type plugins and store them in eventOrderTypes
    Map<String, EventOrderType> eventOrderTypes = new HashMap<String, EventOrderType>();
    while (eventOrderTypesIterator.hasNext()) {
        EventOrderType eot = eventOrderTypesIterator.next();
        eventOrderTypes.put(eot.getName(), eot);
    }
    Namespace bsimNamespace = rootElement.getNamespace();
    List<Element> globalConfigurationElements = rootElement.getChildren(null, bsimNamespace);
    String globalConfId = rootElement.getAttributeValue("id");
    Long randomSeed = null;
    ZoneId zoneId = ZoneId.of("UTC");
    Map<String, Resource> resources = new HashMap<String, Resource>();
    List<EventOrderType> resourceAssignmentOrder = new ArrayList<EventOrderType>();
    // resourceId:[instanceName:timetableId]
    Map<String, Map<String, String>> resourcesToTimetableIds = new HashMap<String, Map<String, String>>();
    Map<String, List<TimetableItem>> timetables = new HashMap<String, List<TimetableItem>>();
    for (Element el : globalConfigurationElements) {
        String elementName = el.getName();
        if (isKnownElement(elementName)) {
            if (el.getText().isEmpty()) {
                continue;
            }
            if (elementName.equals("resourceAssignmentOrder")) {
                String resourceAssignmentOrderString = el.getText();
                String[] orderTypeArray = resourceAssignmentOrderString.split(",");
                for (String orderTypeName : orderTypeArray) {
                    if (orderTypeName.isEmpty()) {
                        continue;
                    }
                    EventOrderType eventOrderType = eventOrderTypes.get(orderTypeName);
                    if (eventOrderType == null) {
                        throw new ScyllaValidationException("Event order type " + orderTypeName + " for resource assignment is unknown.");
                    }
                    resourceAssignmentOrder.add(eventOrderType);
                }
            } else if (elementName.equals("randomSeed")) {
                randomSeed = Long.parseLong(el.getText());
            } else if (elementName.equals("zoneOffset")) {
                zoneId = ZoneId.of("GMT" + el.getText());
            } else if (elementName.equals("resourceData")) {
                List<Element> rDataElements = el.getChildren();
                for (Element elem : rDataElements) {
                    String resourceId = elem.getAttributeValue("id");
                    String rDataElementName = elem.getName();
                    if (rDataElementName.equals("dynamicResource")) {
                        String resourceName = elem.getAttributeValue("name");
                        Integer defaultQuantity = Integer.valueOf(elem.getAttributeValue("defaultQuantity"));
                        Double defaultCost = Double.valueOf(elem.getAttributeValue("defaultCost"));
                        TimeUnit defaultTimeUnit = TimeUnit.valueOf(elem.getAttributeValue("defaultTimeUnit"));
                        DynamicResource dynamicResource = new DynamicResource(resourceId, resourceName, defaultQuantity, defaultCost, defaultTimeUnit);
                        String defaultTimetableId = elem.getAttributeValue("defaultTimetableId");
                        if (resourcesToTimetableIds.containsKey(resourceId)) {
                            throw new ScyllaValidationException("Multiple resource definitions: " + resourceId);
                        }
                        resourcesToTimetableIds.put(resourceId, new HashMap<String, String>());
                        Map<String, DynamicResourceInstance> resourceInstances = dynamicResource.getResourceInstances();
                        List<Element> instanceElements = elem.getChildren("instance", bsimNamespace);
                        // fill up list of resource instances if not explicitly defined
                        if (instanceElements.size() > defaultQuantity) {
                            throw new ScyllaValidationException("Too many instances defined for resource " + resourceId);
                        }
                        int numberOfDefaultInstances = defaultQuantity - instanceElements.size();
                        for (int i = 0; i < numberOfDefaultInstances; i++) {
                            String name = "#" + i;
                            DynamicResourceInstance instance = new DynamicResourceInstance(defaultCost, defaultTimeUnit);
                            resourceInstances.put(name, instance);
                            if (defaultTimetableId != null) {
                                resourcesToTimetableIds.get(resourceId).put(name, defaultTimetableId);
                            }
                        }
                        // parse defined resource instances
                        for (Element element : instanceElements) {
                            String name = element.getAttributeValue("name");
                            if (name == null) {
                                throw new ScyllaValidationException("Resource instance of type " + resourceId + " does not have name.");
                            }
                            Double cost;
                            if (element.getAttributeValue("cost") == null) {
                                cost = defaultCost;
                            } else {
                                cost = Double.valueOf(element.getAttributeValue("cost"));
                            }
                            TimeUnit timeUnit;
                            if (element.getAttributeValue("timeUnit") == null) {
                                timeUnit = defaultTimeUnit;
                            } else {
                                timeUnit = TimeUnit.valueOf(element.getAttributeValue("timeUnit"));
                            }
                            DynamicResourceInstance instance = new DynamicResourceInstance(cost, timeUnit);
                            if (resourceInstances.containsKey(name)) {
                                throw new ScyllaValidationException("Duplicate resource instance: " + name);
                            }
                            resourceInstances.put(name, instance);
                            String timetableId = element.getAttributeValue("timetableId");
                            if (timetableId != null) {
                                resourcesToTimetableIds.get(resourceId).put(name, timetableId);
                            }
                        }
                        resources.put(resourceId, dynamicResource);
                    } else {
                        DebugLogger.log("Element " + elem.getName() + " of resource data is expected to be known, but not supported.");
                    }
                }
            } else if (elementName.equals("timetables")) {
                List<Element> tElements = el.getChildren("timetable", bsimNamespace);
                for (Element tElement : tElements) {
                    String timetableId = tElement.getAttributeValue("id");
                    List<TimetableItem> items = new ArrayList<TimetableItem>();
                    List<Element> tItemElements = tElement.getChildren("timetableItem", bsimNamespace);
                    for (Element tItemElement : tItemElements) {
                        DayOfWeek weekdayFrom = DayOfWeek.valueOf(tItemElement.getAttributeValue("from"));
                        DayOfWeek weekdayTo = DayOfWeek.valueOf(tItemElement.getAttributeValue("to"));
                        LocalTime beginTime = LocalTime.parse(tItemElement.getAttributeValue("beginTime"));
                        LocalTime endTime = LocalTime.parse(tItemElement.getAttributeValue("endTime"));
                        // TODO check for overlapping timetable items and handle them
                        if (DateTimeUtils.compareWeekdayTime(weekdayFrom, beginTime, weekdayTo, endTime) != 0) {
                            if (weekdayFrom.compareTo(weekdayTo) > 0) {
                                // e.g. FRIDAY to MONDAY
                                TimetableItem item = new TimetableItem(weekdayFrom, DayOfWeek.SUNDAY, beginTime, LocalTime.MAX);
                                items.add(item);
                                item = new TimetableItem(DayOfWeek.MONDAY, weekdayTo, LocalTime.MIN, endTime);
                                items.add(item);
                            } else {
                                TimetableItem item = new TimetableItem(weekdayFrom, weekdayTo, beginTime, endTime);
                                items.add(item);
                            }
                        }
                    }
                    timetables.put(timetableId, items);
                }
            }
        } else {
            DebugLogger.log("Element " + el.getName() + " of global configuration is not supported.");
        }
    }
    // match timetables (if any available) and resource data (if any available)s
    for (String resourceId : resourcesToTimetableIds.keySet()) {
        Map<String, String> resourceInstanceIdToTimetableIds = resourcesToTimetableIds.get(resourceId);
        for (String resourceInstanceName : resourceInstanceIdToTimetableIds.keySet()) {
            String timetableId = resourceInstanceIdToTimetableIds.get(resourceInstanceName);
            if (!timetables.containsKey(timetableId)) {
                DebugLogger.log("Timetable " + timetableId + " not found.");
            }
            List<TimetableItem> timetable = timetables.get(timetableId);
            Resource resource = resources.get(resourceId);
            if (resource instanceof DynamicResource) {
                DynamicResource dResource = (DynamicResource) resource;
                dResource.getResourceInstances().get(resourceInstanceName).setTimetable(timetable);
            }
        }
    }
    if (resources.isEmpty()) {
        throw new ScyllaValidationException("No resource data definitions in file.");
    }
    if (randomSeed == null) {
        Random random = new Random();
        randomSeed = random.nextLong();
    }
    DebugLogger.log("Random seed for whole simulation (if not overriden by simulation configuration): " + randomSeed);
    GlobalConfiguration globalConfiguration = new GlobalConfiguration(globalConfId, zoneId, randomSeed, resources, resourceAssignmentOrder);
    return globalConfiguration;
}
Also used : HashMap(java.util.HashMap) Element(org.jdom2.Element) ArrayList(java.util.ArrayList) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) Random(java.util.Random) DynamicResourceInstance(de.hpi.bpt.scylla.model.global.resource.DynamicResourceInstance) TimeUnit(java.util.concurrent.TimeUnit) ArrayList(java.util.ArrayList) List(java.util.List) TimetableItem(de.hpi.bpt.scylla.model.global.resource.TimetableItem) DayOfWeek(java.time.DayOfWeek) GlobalConfiguration(de.hpi.bpt.scylla.model.global.GlobalConfiguration) ZoneId(java.time.ZoneId) LocalTime(java.time.LocalTime) EventOrderType(de.hpi.bpt.scylla.plugin_type.parser.EventOrderType) DynamicResource(de.hpi.bpt.scylla.model.global.resource.DynamicResource) Resource(de.hpi.bpt.scylla.model.global.resource.Resource) Namespace(org.jdom2.Namespace) DynamicResource(de.hpi.bpt.scylla.model.global.resource.DynamicResource) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with Resource

use of de.hpi.bpt.scylla.model.global.resource.Resource 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;
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) Element(org.jdom2.Element) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) ZonedDateTime(java.time.ZonedDateTime) List(java.util.List) ResourceReference(de.hpi.bpt.scylla.model.configuration.ResourceReference) TimeDistributionWrapper(de.hpi.bpt.scylla.model.configuration.distribution.TimeDistributionWrapper) HashSet(java.util.HashSet) Resource(de.hpi.bpt.scylla.model.global.resource.Resource) SimulationConfiguration(de.hpi.bpt.scylla.model.configuration.SimulationConfiguration) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

Resource (de.hpi.bpt.scylla.model.global.resource.Resource)3 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)2 DynamicResource (de.hpi.bpt.scylla.model.global.resource.DynamicResource)2 DynamicResourceInstance (de.hpi.bpt.scylla.model.global.resource.DynamicResourceInstance)2 TimetableItem (de.hpi.bpt.scylla.model.global.resource.TimetableItem)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 TimeUnit (java.util.concurrent.TimeUnit)2 Element (org.jdom2.Element)2 ResourceReference (de.hpi.bpt.scylla.model.configuration.ResourceReference)1 SimulationConfiguration (de.hpi.bpt.scylla.model.configuration.SimulationConfiguration)1 TimeDistributionWrapper (de.hpi.bpt.scylla.model.configuration.distribution.TimeDistributionWrapper)1 GlobalConfiguration (de.hpi.bpt.scylla.model.global.GlobalConfiguration)1 ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)1 EventOrderType (de.hpi.bpt.scylla.plugin_type.parser.EventOrderType)1 DayOfWeek (java.time.DayOfWeek)1 LocalTime (java.time.LocalTime)1 ZoneId (java.time.ZoneId)1 ZonedDateTime (java.time.ZonedDateTime)1