diff --git a/src/main/jastadd/flatter/transforms/ServiceChannelTransforms.jadd b/src/main/jastadd/flatter/transforms/ServiceChannelTransforms.jadd index 9e877c6b270122dd15195414dc340524ad1acc64..3c23272c1f36db83ca03417960e869eb3de12de1 100644 --- a/src/main/jastadd/flatter/transforms/ServiceChannelTransforms.jadd +++ b/src/main/jastadd/flatter/transforms/ServiceChannelTransforms.jadd @@ -8,7 +8,7 @@ aspect ServiceChannelTransforms { Page res = new Page(); Map<String, PnObject> addedObjects = new HashMap<>(); - System.out.println("Transforming service transition: " + this.getId()); + System.out.println("[INFO] Transforming service transition: " + this.getId()); ServiceTransitionInformation sti = this.getStaticTransitionInformation().asServiceTransitionInformation(); res.setId(TemplateConstants.CHANNEL_SERVICE_PAGE_PREFIX + "-" + sti.getServiceName()); diff --git a/src/main/jastadd/flatter/transforms/ServicePrototypeTransforms.jadd b/src/main/jastadd/flatter/transforms/ServicePrototypeTransforms.jadd index 36ad739df466307c87a918ef22ddf2944d967bb4..ba14489df2d85d33167877e39324ec590d3432d2 100644 --- a/src/main/jastadd/flatter/transforms/ServicePrototypeTransforms.jadd +++ b/src/main/jastadd/flatter/transforms/ServicePrototypeTransforms.jadd @@ -9,15 +9,17 @@ aspect ServicePrototypeTransforms { } // apply rule S4 - syn Page Page.transformPrototypePage() { + syn Page Page.transformPrototypePage(int detectedCapacity) { int serverCapacity = 0; String serviceName = this.getServiceName(); DinerosTransition serviceTransition = null; for(DinerosTransition dt : petriNet().allDinerosTransitions()){ - if(dt.getStaticTransitionInformation().isServiceTransitionInformation()){ + if(detectedCapacity == -1 && dt.getStaticTransitionInformation().isServiceTransitionInformation()){ serverCapacity = dt.getStaticTransitionInformation().asServiceTransitionInformation().getServerChannel().getCapacity(); + } else { + serverCapacity = detectedCapacity; } if(dt.getStaticTransitionInformation().isServiceTransitionInformation()){ if(dt.getStaticTransitionInformation().asServiceTransitionInformation().getServiceName().equals(serviceName)){ diff --git a/src/main/jastadd/flatter/transforms/SignalTransforms.jadd b/src/main/jastadd/flatter/transforms/SignalTransforms.jadd index f5d7fe3f8590f920e75b3c7e26383f1333041f04..0573d26f95b947fa001cf098e754b8ae3eda6d02 100644 --- a/src/main/jastadd/flatter/transforms/SignalTransforms.jadd +++ b/src/main/jastadd/flatter/transforms/SignalTransforms.jadd @@ -48,13 +48,17 @@ aspect SignalTransforms { Transition toTrue = net.getTransitionById(TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_TRUE + "-" + l.getName()); Transition toFalse = net.getTransitionById(TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_FALSE + "-" + l.getName()); + System.out.println("toTrue: " + toTrue.getId()); + System.out.println("toFalse: " + toFalse.getId()); // create elements for rule I2 & I3 RefTransition toTrueRt = PrimitiveTemplates.getReferenceTransition(toTrue); - toTrueRt.setId(toTrue.getId() + "REF-" + i + "-" + j); + toTrueRt.setId(toTrue.getId() + "-" + t.getId() + "-REF-" + i + "-" + j); + System.out.println("Adding ref transition: " + toTrue.getId() + "-" + t.getId() + "-REF-" + i + "-" + j); + System.out.println("REF: " + toTrueRt.getRef().getId()); res.addObject(toTrueRt); RefTransition toFalseRt = PrimitiveTemplates.getReferenceTransition(toFalse); - toFalseRt.setId(toFalse.getId() + "REF-" + i + "-" + j); + toFalseRt.setId(toFalse.getId() + "-" + t.getId() + "-REF-" + i + "-" + j); res.addObject(toFalseRt); RefPlace djRefPlace = PrimitiveTemplates.getReferencePlace(pdi); djRefPlace.setId("DJREF-" + i + "-" + j); diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java index c3dd544ba76edc84ec1107e6638e953d73db6369..f06baf7484241b8f040f96c23bd42018d2c395ab 100644 --- a/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java +++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java @@ -2,6 +2,7 @@ package de.tudresden.inf.st.pnml.flatter; import de.tudresden.inf.st.pnml.base.constants.PnmlConstants; import de.tudresden.inf.st.pnml.flatter.config.ConfigReader; +import de.tudresden.inf.st.pnml.flatter.graph.ServiceGraph; import de.tudresden.inf.st.pnml.flatter.tina.KtzioProxy; import de.tudresden.inf.st.pnml.flatter.tina.SiftProxy; import de.tudresden.inf.st.pnml.flatter.tina.TinaProxy; @@ -24,18 +25,23 @@ public class Main { String configPath = (args.length > 1) ? args[1] : null; String pnmlPath = (args.length > 0) ? args[0] : null; - if (pnmlPath == null || configPath == null) { - System.out.println("No model found on given input path."); + if (pnmlPath == null) { + System.out.println("[ERROR] No model found on given input path."); return; } + if(configPath == null || configPath.equals("")){ + System.out.println("[WARNING] No config path configured, no model checking will be executed."); + } + // parse the global not flatted petri net - //pnmlPath = "/home/sebastian/git/dineros/dineros-v2/dineros/pnml-relast-base/src/main/resources/nets/TestNet3.pnml"; - //configPath = "src/main/config/siftConfig.json"; PetriNet petriNet = PnmlParser.parsePnml(pnmlPath).get(0); // [STAGE 1] Resolve service prototype pages - TransformationUtils.transformPrototypePagesRecursive(petriNet.getPage(0), null, petriNet); + ServiceGraph serviceGraph = new ServiceGraph(); + serviceGraph.init(petriNet); + + TransformationUtils.transformPrototypePagesRecursive(petriNet.getPage(0), null, petriNet, serviceGraph); petriNet.flushAttrAndCollectionCache(); // [STAGE 2] Transform topic transitions @@ -72,6 +78,7 @@ public class Main { petriNet.addPage(signalValuePage); petriNet.transformSignalElements(signalValuePage); petriNet.flushTreeCache(); + petriNet.flushAttrAndCollectionCache(); for(DinerosTransition dt : petriNet.allDinerosTransitions()){ Page dtClausePage = dt.getStaticTransitionInformation().asSignalTransitionInformation() @@ -122,29 +129,31 @@ public class Main { // [STAGE 8] Analyze // read config for analyzer from file - ConfigReader cr = new ConfigReader(configPath); - String[] tinaConfig = cr.getTinaConfigParams(); - String[] siftConfig = cr.getSiftConfigParams(); - - // insert into tina - if (tinaConfig.length > 1) { - System.out.println("[FLATTENER] Inserting into tina."); - TinaProxy tinaProxy = new TinaProxy(); - String tinaTargetPath = homeDirectory + "/temp/tina/" + "tina-result-" + exportId + ".txt"; - tinaProxy.analyzePetriNet(inhibitorTargetPath, tinaTargetPath, tinaConfig); - } - - // insert into sift - if (siftConfig.length > 1) { - System.out.println("[FLATTENER] Inserting into sift."); - SiftProxy siftProxy = new SiftProxy(); - String siftTargetPath = homeDirectory + "/temp/sift/" + "sift-result-" + exportId + ".ktz"; - siftProxy.analyzePetriNet(inhibitorTargetPath, siftTargetPath, siftConfig); - - System.out.println("[FLATTENER] Converting with ktzio."); - KtzioProxy ktzioProxy = new KtzioProxy(); - String ktzioPath = homeDirectory + "/temp/sift/" + "sift-result-converted-" + exportId + ".txt"; - ktzioProxy.convertBinaryToText(siftTargetPath, ktzioPath); + if(configPath != null && !configPath.equals("")) { + ConfigReader cr = new ConfigReader(configPath); + String[] tinaConfig = cr.getTinaConfigParams(); + String[] siftConfig = cr.getSiftConfigParams(); + + // insert into tina + if (tinaConfig.length > 1) { + System.out.println("[FLATTENER] Inserting into tina."); + TinaProxy tinaProxy = new TinaProxy(); + String tinaTargetPath = homeDirectory + "/temp/tina/" + "tina-result-" + exportId + ".txt"; + tinaProxy.analyzePetriNet(inhibitorTargetPath, tinaTargetPath, tinaConfig); + } + + // insert into sift + if (siftConfig.length > 1) { + System.out.println("[FLATTENER] Inserting into sift."); + SiftProxy siftProxy = new SiftProxy(); + String siftTargetPath = homeDirectory + "/temp/sift/" + "sift-result-" + exportId + ".ktz"; + siftProxy.analyzePetriNet(inhibitorTargetPath, siftTargetPath, siftConfig); + + System.out.println("[FLATTENER] Converting with ktzio."); + KtzioProxy ktzioProxy = new KtzioProxy(); + String ktzioPath = homeDirectory + "/temp/sift/" + "sift-result-converted-" + exportId + ".txt"; + ktzioProxy.convertBinaryToText(siftTargetPath, ktzioPath); + } } System.out.println("[FLATTENER] Finished."); diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/graph/ServiceGraph.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/graph/ServiceGraph.java new file mode 100644 index 0000000000000000000000000000000000000000..3a38e739f92c030a0f601bd1e4dd867792d29281 --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/graph/ServiceGraph.java @@ -0,0 +1,106 @@ +package de.tudresden.inf.st.pnml.flatter.graph; + +import de.tudresden.inf.st.pnml.jastadd.model.*; + +import java.util.ArrayList; +import java.util.List; + +public class ServiceGraph { + + public List<Node> graph; + + public static class Node{ + + public String name; + public String serviceName; + public List<Node> targets; + public List<Node> sources; + + public Node(String name, String serviceName, List<Node> targets, List<Node> sources) { + this.name = name; + this.serviceName = serviceName; + this.targets = targets; + this.sources = sources; + } + } + + public List<Node> init(PetriNet petriNet){ + + graph = new ArrayList<>(); + + // [1] Create a node for each service channel + for(DinerosTransition t : petriNet.allDinerosTransitions()){ + if(t.getStaticTransitionInformation().isServiceTransitionInformation()){ + graph.add(new Node(t.getId(), t.getStaticTransitionInformation() + .asServiceTransitionInformation().getServiceName(), new ArrayList<>(), new ArrayList<>())); + } + } + + // [2] Iterate over nodes to build connections + for(Node n : graph){ + for(DinerosTransition t : petriNet.allDinerosTransitions()){ + if(t.getId().equals(n.name)){ + for(ServiceChannel sc : t.getStaticTransitionInformation().asServiceTransitionInformation().getClientChannels()){ + for(Node iterNode : graph){ + if(!n.name.equals(iterNode.name) && + isPnObjectInPageTree(petriNet.getTransitionById(iterNode.name).ContainingPage(), sc.getRequestPlaceId())){ + // [3] Build connections + n.sources.add(iterNode); + iterNode.targets.add(n); + } + } + } + } + } + } + + return graph; + } + + public boolean isPotentiallyCyclic(String serviceName){ + + for(Node n : graph){ + if(n.serviceName.equals(serviceName)){ + return isPotentiallyCyclicInternal(n, n); + } + } + + return true; + } + + private boolean isPotentiallyCyclicInternal(Node node, Node iterNode){ + + for(Node n : iterNode.targets){ + if(n.name.equals(node.name)){ + return true; + } + } + + for(Node n : iterNode.targets){ + if(isPotentiallyCyclicInternal(node, n)){ + return true; + } + } + + return false; + } + + private boolean isPnObjectInPageTree(Page page, String id){ + + // bfs + for(PnObject po : page.getObjects()){ + if(po.getId().equals(id)){ + return true; + } + } + + for(PnObject po : page.getObjects()){ + if(po.isPageNode() && + isPnObjectInPageTree(po.asPage(), id)){ + return true; + } + } + + return false; + } +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/tina/NdrioProxy.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/tina/NdrioProxy.java index 3e6023e4fa0c5b725bddf810b7d45b825d7d8d85..602d3a05b13f252ff96e6f5f0fdd36578ee6bfe3 100644 --- a/src/main/java/de/tudresden/inf/st/pnml/flatter/tina/NdrioProxy.java +++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/tina/NdrioProxy.java @@ -18,10 +18,10 @@ public class NdrioProxy extends AbstractTinaProxy{ if(!isWindows){ - if(homeDirectory.contains("pnml-relast-flatter")){ + if(homeDirectory.contains("pnml-relast-flattener")){ ndrioProcessBuilder.command(homeDirectory + "/libs/tina-3.7.0/bin/ndrio", inputPath, outputPath); }else{ - ndrioProcessBuilder.command(homeDirectory + "/pnml-relast-checker/libs/tina-3.7.0/bin/ndrio", inputPath, outputPath); + ndrioProcessBuilder.command(homeDirectory + "/pnml-relast-flattener/libs/tina-3.7.0/bin/ndrio", inputPath, outputPath); } }else{ logger.error("Windows is currently not supported. Exiting ..."); diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ReferenceFlatter.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ReferenceFlatter.java index 297b7b857d8663619ed0f2b20779db17b8c2ab64..508931c285b33333848e1e64e4922d4a1e421539 100644 --- a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ReferenceFlatter.java +++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ReferenceFlatter.java @@ -113,7 +113,7 @@ public class ReferenceFlatter { Page topLevelPage = null; for (Page p : petriNet.allPages()){ - if(p.ContainingPage() == null){ + if(p.getId().equals("top")){ topLevelPage = p; } } diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/TransformationUtils.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/TransformationUtils.java index 9effaf336c68a1d9db1e0cd1d5a9b61606901537..42688199ce3a220411beb51af2bd77fc3b0a5f85 100644 --- a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/TransformationUtils.java +++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/TransformationUtils.java @@ -1,5 +1,6 @@ package de.tudresden.inf.st.pnml.flatter.transform; +import de.tudresden.inf.st.pnml.flatter.graph.ServiceGraph; import de.tudresden.inf.st.pnml.jastadd.model.*; import java.util.HashMap; @@ -152,11 +153,37 @@ public class TransformationUtils { } } - public static void transformPrototypePagesRecursive(Page page, Page parentPage, PetriNet petriNet){ + private static DinerosTransition getTransitionByServiceName(PetriNet petriNet, String serviceName){ + + for(DinerosTransition t : petriNet.allDinerosTransitions()){ + if(t.getStaticTransitionInformation().isServiceTransitionInformation()){ + if(t.getStaticTransitionInformation(). + asServiceTransitionInformation().getServiceName().equals(serviceName)){ + return t; + } + } + } + + return null; + } + + public static void transformPrototypePagesRecursive(Page page, Page parentPage, PetriNet petriNet, ServiceGraph serviceGraph){ if(page.canTransformPrototypePage()){ - System.out.println("Transforming page: " + page.getId()); - Page transformedPage = page.transformPrototypePage(); + System.out.println("[INFO] Transforming page: " + page.getId()); + + Page transformedPage; + + if(serviceGraph.isPotentiallyCyclic(page.getServiceName())){ + System.out.println("[WARNING] Detected potentially cyclic service call on: " + page.getServiceName()); + System.out.println("[WARNING] Falling back to user defined thread number for: " + page.getServiceName()); + transformedPage = page.transformPrototypePage(-1); + } else { + int numInstances = getTransitionByServiceName(petriNet, + page.getServiceName()).getStaticTransitionInformation().asServiceTransitionInformation().getNumClientChannel(); + transformedPage = page.transformPrototypePage(numInstances); + System.out.println("[INFO] Transforming prototype page: " + page.getServiceName() + " to " + numInstances + " instances."); + } if(parentPage == null){ for(int i = 0; i < petriNet.getNumPage(); i++){ @@ -185,7 +212,7 @@ public class TransformationUtils { } for(Page iterPage : subPages){ - transformPrototypePagesRecursive(iterPage, page, petriNet); + transformPrototypePagesRecursive(iterPage, page, petriNet, serviceGraph); } }