list) {
+ if (AppEndpoint.class.isAssignableFrom(endpoint.getClass())) {
+ final var appEndpoint = (AppEndpoint) endpoint;
+ if (appEndpoint.getAppEndpointType() == AppEndpointType.OUTPUT_ENDPOINT) {
+ list.add(new RouteStepEndpoint(appEndpoint.getAccessURL(),
+ HttpMethod.GET));
+ } else {
+ list.add(new RouteStepEndpoint(appEndpoint.getAccessURL(),
+ HttpMethod.POST));
+ }
+ } else {
+ list.add(new RouteStepEndpoint(endpoint.getAccessURL(),
+ HttpMethod.POST));
+ }
+ }
+
+ /**
+ * Creates and deploys a Camel route for the Dataspace Connector. First, Dataspace Connector
+ * specific configuration is added to the Velocity Context, which should already contain
+ * general route information. Then, the correct route template for the given AppRoute object
+ * is chosen from the Dataspace Connector templates. Last, the generated XML route is sent to
+ * the Camel application defined in application.properties.
+ *
+ * @param appRoute the AppRoute object
+ * @param velocityContext the Velocity context
+ * @throws Exception if the route file cannot be created or deployed
+ */
+ private void createDataspaceConnectorRoute(final AppRoute appRoute,
+ final VelocityContext velocityContext)
+ throws Exception {
+
+ if (log.isDebugEnabled()) {
+ log.debug("---- [RouteManager createDataspaceConnectorRoute]Creating route for Dataspace Connector...");
+ }
+
+ //add reference to Camel-Instance's error handler to Velocity context
+ velocityContext.put("errorHandlerRef", camelErrorHandlerRef);
+
+ //add basic auth header for connector endpoint
+ dataspaceConnectorRouteConfigurer.addBasicAuthToContext(velocityContext);
+
+ //choose correct XML template based on route
+ final var template = dataspaceConnectorRouteConfigurer.getRouteTemplate(appRoute);
+
+ if (template != null) {
+ final var velocityEngine = new VelocityEngine();
+ velocityEngine.init();
+
+ //populate route template with properties from velocity context to create route
+ final var writer = populateTemplate(template, velocityEngine, velocityContext);
+
+ //send the generated route (XML) to Camel via HTTP
+ routeHttpHelper.sendRouteFileToCamelApplication(writer.toString());
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn("---- [RouteManager createDataspaceConnectorRoute] Template is null. Unable to create XML route file for AppRoute"
+ + " with ID '{}'", appRoute.getId());
+ }
+
+ throw new NoSuitableTemplateException("No suitable Camel route template found for "
+ + "AppRoute with ID '" + appRoute.getId() + "'");
+ }
+ }
+
+ /**
+ * Creates and deploys a Camel route for the Trusted Connector. First, Trusted Connector
+ * specific configuration is added to the Velocity Context, which should already contain
+ * general route information. Then, the correct route template for the given AppRoute
+ * object is chosen from the Trusted Connector templates. Last, the generated XML route is
+ * written to the directory defined in application.properties.
+ *
+ * @param appRoute the AppRoute object
+ * @param velocityContext the Velocity context
+ * @param configurationModel the Configuration Model containing key- and truststore passwords
+ * required for the Trusted Connector's SSL configuration
+ * @param camelRouteId ID of the Camel route, which is used as the file name
+ * @throws Exception if the route file cannot be created or deployed
+ */
+ private void createTrustedConnectorRoute(final AppRoute appRoute,
+ final VelocityContext velocityContext,
+ final ConfigurationModel configurationModel,
+ final String camelRouteId) throws Exception {
+ if (log.isDebugEnabled()) {
+ log.debug("---- [RouteManager createTrustedConnectorRoute] Creating route for Trusted Connector...");
+ }
+
+ //add SSL configuration for connector endpoint
+ TrustedConnectorRouteConfigurer.addSslConfig(velocityContext, configurationModel);
+
+ //choose correct XML template based on route
+ final var template = TrustedConnectorRouteConfigurer.getRouteTemplate(appRoute);
+
+ if (template != null) {
+ final var velocityEngine = new VelocityEngine();
+ velocityEngine.init();
+
+ //populate route template with properties from velocity context to create route
+ final var writer = populateTemplate(template, velocityEngine, velocityContext);
+
+ //write the generated route (XML) to a file in the designated directory
+ routeFileHelper.writeToFile(camelRouteId + ".xml", writer.toString());
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn("Template is null. Unable to create XML route file for AppRoute"
+ + " with ID '{}'", appRoute.getId());
+ }
+
+ throw new NoSuitableTemplateException("No suitable Camel route template found for "
+ + "AppRoute with ID '" + appRoute.getId() + "'");
+ }
+ }
+
+ /**
+ * Populates a given Velocity template using the values from a given Velocity context.
+ *
+ * @param resource the template
+ * @param velocityEngine the Velocity engine required for populating the template
+ * @param velocityContext the context containing the values to insert into the template
+ * @return the populated template as a string
+ * @throws Exception if an error occurs while filling out the route template
+ */
+ private StringWriter populateTemplate(final Resource resource,
+ final VelocityEngine velocityEngine,
+ final VelocityContext velocityContext) throws Exception {
+ final var stringWriter = new StringWriter();
+ InputStreamReader inputStreamReader;
+
+ try {
+ inputStreamReader = new InputStreamReader(resource.getInputStream());
+ velocityEngine.evaluate(velocityContext, stringWriter, "", inputStreamReader);
+ } catch (Exception e) {
+ final var camelRouteId = (String) velocityContext.get("routeId");
+
+ if (log.isErrorEnabled()) {
+ log.error("An error occurred while populating template. Please check all respective "
+ + "files for connection with ID '{}' for correctness! (Error message: {})",
+ camelRouteId, e.toString());
+ }
+
+ throw e;
+ }
+
+ return stringWriter;
+ }
+
+ /**
+ * Deletes all Camel routes associated with app routes from a given config model by calling
+ * {@link RouteManager#deleteRoute(AppRoute)}.
+ *
+ * @param configurationModel the config model
+ * @throws RouteDeletionException if any of the Camel routes cannot be deleted
+ */
+ public void deleteRouteFiles(final ConfigurationModel configurationModel)
+ throws RouteDeletionException {
+ for (final var appRoute: configurationModel.getAppRoute()) {
+ deleteRoute(appRoute);
+ }
+ }
+
+ /**
+ * Deletes the Camel route for a given {@link AppRoute}. If the Configuration Manager is
+ * currently managing a Dataspace Connector, the route is deleted at the Camel application. If
+ * the Configuration Manager is currently managing a Trusted Connector, the route file is
+ * removed from the designated directory.
+ *
+ * @param appRoute the AppRoute
+ * @throws RouteDeletionException if the Camel route cannot be deleted
+ */
+ public void deleteRoute(final AppRoute appRoute) throws RouteDeletionException {
+ final var camelRouteId = getCamelRouteId(appRoute);
+
+ try {
+ if (dataspaceConnectorEnabled) {
+ routeHttpHelper.deleteRouteAtCamelApplication(camelRouteId);
+ } else {
+ routeFileHelper.deleteFile(camelRouteId + ".xml");
+ }
+ } catch (Exception e) {
+ throw new RouteDeletionException("Error deleting Camel route for AppRoute with ID '"
+ + appRoute.getId() + "'", e);
+ }
+
+ }
+
+ /**
+ * Generated the ID of the Camel route for a given {@link AppRoute}. The Camel route ID consists
+ * of the String 'app-route_' followed by the UUID from the AppRoute's ID.
+ *
+ * @param appRoute the AppRoute
+ * @return the Camel route ID
+ */
+ private String getCamelRouteId(final AppRoute appRoute) {
+ final var appRouteId = appRoute.getId().toString()
+ .split("/")[appRoute.getId().toString().split("/").length - 1];
+ return "app-route_" + appRouteId;
+ }
+
+}
diff --git a/src/main/java/de/fraunhofer/isst/configmanager/util/camel/dto/RouteStepEndpoint.java b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/dto/RouteStepEndpoint.java
new file mode 100644
index 00000000..ffc1dd5e
--- /dev/null
+++ b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/dto/RouteStepEndpoint.java
@@ -0,0 +1,19 @@
+package de.fraunhofer.isst.configmanager.util.camel.dto;
+
+import java.net.URI;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.experimental.FieldDefaults;
+import org.springframework.http.HttpMethod;
+
+@Data
+@AllArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE)
+public class RouteStepEndpoint {
+
+ URI endpointUrl;
+ HttpMethod httpMethod;
+
+}
diff --git a/src/main/java/de/fraunhofer/isst/configmanager/util/camel/dto/package-info.java b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/dto/package-info.java
new file mode 100644
index 00000000..20b27dc6
--- /dev/null
+++ b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/dto/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains DTOs used during the creation of Camel routes.
+ */
+package de.fraunhofer.isst.configmanager.util.camel.dto;
diff --git a/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/NoSuitableTemplateException.java b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/NoSuitableTemplateException.java
new file mode 100644
index 00000000..8e1b2611
--- /dev/null
+++ b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/NoSuitableTemplateException.java
@@ -0,0 +1,28 @@
+package de.fraunhofer.isst.configmanager.util.camel.exceptions;
+
+/**
+ * Thrown to indicate that no suitable Camel route template was found for a given AppRoute.
+ */
+public class NoSuitableTemplateException extends Exception {
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructs a NoSuitableTemplateException with the specified message.
+ *
+ * @param msg the message.
+ */
+ public NoSuitableTemplateException(final String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs a NoSuitableTemplateException with the specified message and cause.
+ *
+ * @param msg the message.
+ * @param cause the cause.
+ */
+ public NoSuitableTemplateException(final String msg, final Throwable cause) {
+ super(msg, cause);
+ }
+
+}
diff --git a/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/RouteCreationException.java b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/RouteCreationException.java
new file mode 100644
index 00000000..f2f10916
--- /dev/null
+++ b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/RouteCreationException.java
@@ -0,0 +1,28 @@
+package de.fraunhofer.isst.configmanager.util.camel.exceptions;
+
+/**
+ * Thrown to indicate that an error occurred during creation or deployment of a Camel route.
+ */
+public class RouteCreationException extends Exception {
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructs a RouteCreationException with the specified message.
+ *
+ * @param msg the message.
+ */
+ public RouteCreationException(final String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs a RouteCreationException with the specified message and cause.
+ *
+ * @param msg the message.
+ * @param cause the cause.
+ */
+ public RouteCreationException(final String msg, final Throwable cause) {
+ super(msg, cause);
+ }
+
+}
diff --git a/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/RouteDeletionException.java b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/RouteDeletionException.java
new file mode 100644
index 00000000..b74c8b5a
--- /dev/null
+++ b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/RouteDeletionException.java
@@ -0,0 +1,28 @@
+package de.fraunhofer.isst.configmanager.util.camel.exceptions;
+
+/**
+ * Thrown to indicate that an error occurred while trying to delete a Camel route.
+ */
+public class RouteDeletionException extends Exception {
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructs a RouteDeletionException with the specified message.
+ *
+ * @param msg the message.
+ */
+ public RouteDeletionException(final String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs a RouteDeletionException with the specified message and cause.
+ *
+ * @param msg the message.
+ * @param cause the cause.
+ */
+ public RouteDeletionException(final String msg, final Throwable cause) {
+ super(msg, cause);
+ }
+
+}
diff --git a/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/package-info.java b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/package-info.java
new file mode 100644
index 00000000..60961e3d
--- /dev/null
+++ b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/exceptions/package-info.java
@@ -0,0 +1,12 @@
+/**
+ * Exceptions specific for managing Camel routes.
+ *
+ * This package contains all Exceptions that indicate errors during the creation, deployment or
+ * deletion of Camel routes.
+ *
+ *
+ * @version 7.0.0 (last changed at version)
+ * @since 7.0.0 (documented since)
+ * @author IDS-ConfigurationManager Contributors
+ */
+package de.fraunhofer.isst.configmanager.util.camel.exceptions;
diff --git a/src/main/java/de/fraunhofer/isst/configmanager/util/camel/package-info.java b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/package-info.java
new file mode 100644
index 00000000..d6a98022
--- /dev/null
+++ b/src/main/java/de/fraunhofer/isst/configmanager/util/camel/package-info.java
@@ -0,0 +1,11 @@
+/**
+ * Classes relevant for managing Camel routes.
+ *
+ * This package contains all classes required for creating, deploying and deleting Camel routes.
+ *
+ *
+ * @version 7.0.0 (last changed at version)
+ * @since 7.0.0 (documented since)
+ * @author IDS-ConfigurationManager Contributors
+ */
+package de.fraunhofer.isst.configmanager.util.camel;
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 34180f33..ea4eacb7 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -39,3 +39,12 @@ dataspace.communication.ssl=true
# Miscellaneous Settings
spring.banner.location=classpath:banner.txt
+
+# camel
+camel.xml-routes.directory=./camel/routes
+camel.application.url=https://localhost:9090
+camel.application.username=admin
+camel.application.password=password
+camel.application.path.routes=/api/routes
+camel.application.path.beans=/api/beans
+camel.application.error-handler=errorHandler
diff --git a/src/main/resources/camel-templates/dataspaceconnector/connector_to_http_template.vm b/src/main/resources/camel-templates/dataspaceconnector/connector_to_http_template.vm
new file mode 100644
index 00000000..0cfea678
--- /dev/null
+++ b/src/main/resources/camel-templates/dataspaceconnector/connector_to_http_template.vm
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ POST
+ ${connectorAuthHeader}
+
+
+
+
+
+ #foreach($endpoint in $routeStepEndpoints)
+ $endpoint.getHttpMethod().toString()
+
+ #end
+
+ POST
+ #if($genericEndpointAuthHeader)
+ ${genericEndpointAuthHeader}
+ #end
+
+
+
+
+
diff --git a/src/main/resources/camel-templates/dataspaceconnector/http_to_connector_template.vm b/src/main/resources/camel-templates/dataspaceconnector/http_to_connector_template.vm
new file mode 100644
index 00000000..a38aae63
--- /dev/null
+++ b/src/main/resources/camel-templates/dataspaceconnector/http_to_connector_template.vm
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ GET
+ #if($genericEndpointAuthHeader)
+ ${genericEndpointAuthHeader}
+ #end
+
+
+
+
+
+ #foreach($endpoint in $routeStepEndpoints)
+ $endpoint.getHttpMethod().toString()
+
+ #end
+
+ PUT
+ ${connectorAuthHeader}
+
+
+
+
+
diff --git a/src/main/resources/camel-templates/trustedconnector/idscp2_client_template_1.vm b/src/main/resources/camel-templates/trustedconnector/idscp2_client_template_1.vm
new file mode 100644
index 00000000..138b9b62
--- /dev/null
+++ b/src/main/resources/camel-templates/trustedconnector/idscp2_client_template_1.vm
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #set ($startUrlHost = $startUrl.split("//")[1].split(":")[0])
+ #set ($startUrlPort = $startUrl.split("//")[1].split(":")[1])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/camel-templates/trustedconnector/idscp2_client_template_2.vm b/src/main/resources/camel-templates/trustedconnector/idscp2_client_template_2.vm
new file mode 100644
index 00000000..8b08d614
--- /dev/null
+++ b/src/main/resources/camel-templates/trustedconnector/idscp2_client_template_2.vm
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #set ($startUrlHost = $startUrl.split("//")[1].split(":")[0])
+ #set ($startUrlPort = $startUrl.split("//")[1].split(":")[1])
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ping
+
+
+
+
+
+
+
+ application/json
+
+
+
+
+
+
diff --git a/src/main/resources/camel-templates/trustedconnector/idscp2_server_template_1.vm b/src/main/resources/camel-templates/trustedconnector/idscp2_server_template_1.vm
new file mode 100644
index 00000000..bf10a48a
--- /dev/null
+++ b/src/main/resources/camel-templates/trustedconnector/idscp2_server_template_1.vm
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/camel-templates/trustedconnector/idscp2_server_template_2.vm b/src/main/resources/camel-templates/trustedconnector/idscp2_server_template_2.vm
new file mode 100644
index 00000000..1068d722
--- /dev/null
+++ b/src/main/resources/camel-templates/trustedconnector/idscp2_server_template_2.vm
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+ {"data" : "testData"}
+
+
+ pong
+
+
+
+
+
+
+
diff --git a/src/test/java/de/fraunhofer/isst/configmanager/petrinet/builder/InfomodelPetriNetBuilderTest.java b/src/test/java/de/fraunhofer/isst/configmanager/petrinet/builder/InfomodelPetriNetBuilderTest.java
index ea7b6f5e..a3ec35ce 100644
--- a/src/test/java/de/fraunhofer/isst/configmanager/petrinet/builder/InfomodelPetriNetBuilderTest.java
+++ b/src/test/java/de/fraunhofer/isst/configmanager/petrinet/builder/InfomodelPetriNetBuilderTest.java
@@ -56,7 +56,9 @@ class InfomodelPetriNetBuilderTest {
private static final int MAXIMUM_STARTEND = 3;
/**
- * Generate a random PetriNet, try to simulate it and print out the GraphViz representation
+ * Example: Generate a random PetriNet, try to simulate it and print out the GraphViz representation
+ * Generated PetriNet can have an infinite amount of possible configurations, if this happens the
+ * example will run indefinitely.
*/
@Test
@Disabled
@@ -114,38 +116,45 @@ void testBuildPetriNet() throws IOException {
}
}
+ /**
+ * Example: Create a set of Formulas and evaluate them on the example PetriNet
+ */
@Test
@Disabled
void testExamplePetriNet(){
+ //build the example net and log DOT visualization
var petriNet = buildPaperNet();
+ log.info(GraphVizGenerator.generateGraphViz(petriNet));
- if (log.isInfoEnabled()) {
- log.info(GraphVizGenerator.generateGraphViz(petriNet));
- }
-
- //build stepGraph and visualize
+ //build stepGraph
var graph = PetriNetSimulator.buildStepGraph(petriNet);
+ log.info(String.format("%d possible states!", graph.getSteps().size()));
- if (log.isInfoEnabled()) {
- //log.info(GraphVizGenerator.generateGraphViz(graph));
- log.info(String.format("%d possible states!", graph.getSteps().size()));
- }
-
+ //get set of paths from calculated stepgraph
var allPaths = PetriNetSimulator.getAllPaths(graph);
log.info(String.format("Found %d valid Paths!", allPaths.size()));
- //an end node is eventually reachable
- var endReachable = nodeEV(nodeNF(nodeExpression(x -> x.getSourceArcs().isEmpty(), "")));
- log.info("Evaluating Formula: " + endReachable.writeFormula());
- //log.info("Result: " + CTLEvaluator.evaluate(endReachable, graph.getInitial().getNodes().stream().filter(node -> node.getID().equals(URI.create("place://start"))).findAny().get(), allPaths));
- //a transition is reachable, which reads data without 'france' in context, after that transition data is overwritten or erased (or an end is reached)
- var formulaFrance = transitionPOS(transitionAND(transitionAF(arcExpression(x -> x.getContext().getRead() != null && x.getContext().getRead().equals("data") && !x.getContext().getContext().contains("france"), "")), transitionEV(transitionOR(transitionAF(arcExpression(x -> x.getContext().getWrite() != null && x.getContext().getWrite().equals("data") || x.getContext().getErase() != null && x.getContext().getErase().equals("data"), "")), transitionMODAL(nodeNF(nodeExpression(x -> x.getSourceArcs().isEmpty(), " ")))))));
+
+ //Evaluate Formula 1: a transition is reachable, which reads data without 'france' in context, after that transition data is overwritten or erased (or an end is reached)
+ var formulaFrance = transitionPOS(
+ transitionAND(
+ transitionAF(arcExpression(x -> x.getContext().getRead() != null && x.getContext().getRead().equals("data") && !x.getContext().getContext().contains("france"), "")),
+ transitionEV(
+ transitionOR(
+ transitionAF(arcExpression(x -> x.getContext().getWrite() != null && x.getContext().getWrite().equals("data") || x.getContext().getErase() != null && x.getContext().getErase().equals("data"), "")),
+ transitionMODAL(nodeNF(nodeExpression(x -> x.getSourceArcs().isEmpty(), " ")))
+ )
+ )
+ )
+ );
log.info("Formula France: " + formulaFrance.writeFormula());
log.info("Result: " + CTLEvaluator.evaluate(formulaFrance, graph.getInitial().getNodes().stream().filter(node -> node.getID().equals(URI.create("trans://getData"))).findAny().get(), allPaths));
- //a transition is reachable, which reads data
+
+ //Evaluate Formula 2: a transition is reachable, which reads data
var formulaDataUsage = nodeMODAL(transitionPOS(transitionAF(arcExpression(x -> x.getContext().getRead() != null && x.getContext().getRead().equals("data"), ""))));
log.info("Formula Data: " + formulaDataUsage.writeFormula());
log.info("Result: " + CTLEvaluator.evaluate(formulaDataUsage, graph.getInitial().getNodes().stream().filter(node -> node.getID().equals(URI.create("place://start"))).findAny().get(), allPaths));
- //a transition is reachable, which is reading data. From there another transition is reachable, which also reads data, from this the end or a transition which overwrites or erases data is reachable.
+
+ //Evaluate Formula 3: a transition is reachable, which is reading data. From there another transition is reachable, which also reads data, from this the end or a transition which overwrites or erases data is reachable.
var formulaUseAndDelete = transitionPOS(
transitionAND(
transitionAF(arcExpression(x -> x.getContext().getRead() != null && x.getContext().getRead().equals("data"), "")),
@@ -167,20 +176,30 @@ void testExamplePetriNet(){
log.info("Result: " + CTLEvaluator.evaluate(formulaUseAndDelete, graph.getInitial().getNodes().stream().filter(node -> node.getID().equals(URI.create("trans://getData"))).findAny().get(), allPaths));
}
+ /**
+ * Example: Unfold the example PetriNet and check for parallel evaluations
+ */
@Test
@Disabled
void testUnfoldNet(){
+ //build example petrinet
var petriNet = buildPaperNet();
- var stepGraph = PetriNetSimulator.buildStepGraph(petriNet);
+
+ //unfold and visualize example petrinet
var unfolded = PetriNetSimulator.getUnfoldedPetriNet(petriNet);
log.info(GraphVizGenerator.generateGraphViz(unfolded));
- log.info(String.valueOf(unfolded.deepCopy().equals(unfolded)));
+
+ //build step graph of unfolded net
var unfoldedGraph = PetriNetSimulator.buildStepGraph(unfolded);
log.info(String.format("Step Graph has %d possible combinations!", unfoldedGraph.getSteps().size()));
- log.info("Getting parallel sets...");
+
+ //get possible parallel executions of transitions from the calculated stepgraph
var parallelSets = PetriNetSimulator.getParallelSets(unfoldedGraph);
log.info(String.format("Found %d possible parallel executions!", parallelSets.size()));
- log.info(String.format("3 parallel reading Transitions: %s", ParallelEvaluator.nParallelTransitionsWithCondition(x -> x.getContext().getRead() != null && x.getContext().getRead().equals("data"), 3, parallelSets)));
+
+ //evaluate: 3 transitions are reading data in parallel
+ var result = ParallelEvaluator.nParallelTransitionsWithCondition(x -> x.getContext().getRead() != null && x.getContext().getRead().equals("data"), 3, parallelSets);
+ log.info(String.format("3 parallel reading Transitions: %s", result));
}
/**
@@ -199,17 +218,11 @@ public static ArrayList extends T> randomSubList(List input) {
return newList;
}
- @Test
- @Disabled
- void testFormula(){
- var formula = nodeAND(nodeMODAL(transitionNOT(FF())), nodeOR(nodeNF(nodeExpression(x -> true, "testMsg")),TT()));
- if (log.isInfoEnabled()) {
- log.info(formula.writeFormula());
- }
- }
-
+ /**
+ * Build the example PetriNet from the paper, to evaluate formulas on
+ * @return Example PetriNet described in the WFDU Paper
+ */
private PetriNet buildPaperNet(){
- var nodes = new HashSet();
//create nodes
var start = new PlaceImpl(URI.create("place://start"));
start.setMarkers(1);
@@ -230,7 +243,7 @@ private PetriNet buildPaperNet(){
var stor3 = new PlaceImpl(URI.create("place://stored3"));
var stor4 = new PlaceImpl(URI.create("place://stored4"));
var end = new PlaceImpl(URI.create("place://end"));
- nodes.addAll(List.of(start, copy, init, dat1, dat2, con1, con2, con3, con4, sample, mean, med, rules, stor1, stor2, stor3, stor4, end));
+ var nodes = new HashSet(List.of(start, copy, init, dat1, dat2, con1, con2, con3, con4, sample, mean, med, rules, stor1, stor2, stor3, stor4, end));
//create transitions with context
var initTrans = new TransitionImpl(URI.create("trans://init"));
initTrans.setContextObject(new ContextObject(List.of(), null, null, null, ContextObject.TransType.CONTROL));
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
index 591b8475..a4e731ee 100644
--- a/src/test/resources/application.properties
+++ b/src/test/resources/application.properties
@@ -26,3 +26,12 @@ dataspace.connector.api.username=admin
dataspace.connector.api.password=password
dataspace.connector.connectionattemps=2
dataspace.communication.ssl=true
+
+# camel
+camel.xml-routes.directory=./camel/routes
+camel.application.url=https://localhost:9090
+camel.application.username=admin
+camel.application.password=password
+camel.application.path.routes=/api/routes
+camel.application.path.beans=/api/beans
+camel.application.error-handler=errorHandler