mirror of
https://github.com/Echtzeitsysteme/gips-examples.git
synced 2024-06-03 02:31:53 +00:00
Adds first tiny working example
This commit is contained in:
parent
8524585745
commit
084689e119
|
@ -1,16 +1,16 @@
|
|||
Manifest-Version: 1.0
|
||||
Automatic-Module-Name: org.emoflon.gips.gipsl.examples.mdvne.seq
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: org.emoflon.gips.gipsl.examples.mdvne.seq
|
||||
Bundle-Vendor: My Company
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-SymbolicName: org.emoflon.gips.gipsl.examples.mdvne.seq; singleton:=true
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Require-Bundle: org.emoflon.ibex.common,
|
||||
org.emoflon.ibex.gt,
|
||||
org.emoflon.gips.core,
|
||||
org.emoflon.ibex.gt.democles,
|
||||
org.emoflon.ibex.gt.hipe,
|
||||
network.metrics
|
||||
|
||||
Manifest-Version: 1.0
|
||||
Automatic-Module-Name: org.emoflon.gips.gipsl.examples.mdvne.seq
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: org.emoflon.gips.gipsl.examples.mdvne.seq
|
||||
Bundle-Vendor: My Company
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Export-Package: org.emoflon.gips.gipsl.examples.mdvne.seq
|
||||
Bundle-SymbolicName: org.emoflon.gips.gipsl.examples.mdvne.seq; singleton:=true
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Require-Bundle: org.emoflon.ibex.common,
|
||||
org.emoflon.ibex.gt,
|
||||
org.emoflon.gips.core,
|
||||
org.emoflon.ibex.gt.democles,
|
||||
org.emoflon.ibex.gt.hipe,
|
||||
network.model
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
package org.emoflon.gips.gipsl.examples.mdvne.seq;
|
||||
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.emoflon.gips.core.ilp.ILPSolverOutput;
|
||||
import org.emoflon.gips.gipsl.examples.mdvne.seq.api.gips.SeqGipsAPI;
|
||||
|
||||
/**
|
||||
* Implementation adapter for GIPS and iflye. This is used to run the GIPS-based
|
||||
* MdVNE adapter from the iflye framework. Basically, this is an external entry
|
||||
* point to trigger the GIPS-based MdVNE implementation from other frameworks.
|
||||
*
|
||||
* @author Maximilian Kratz {@literal <maximilian.kratz@es.tu-darmstadt.de>}
|
||||
*/
|
||||
public class MdvneGipsIflyeAdapter {
|
||||
|
||||
/**
|
||||
* MdVNE GIPS API object.
|
||||
*/
|
||||
static SeqGipsAPI api;
|
||||
|
||||
/**
|
||||
* If false, the API must be initialized.
|
||||
*/
|
||||
static boolean init = false;
|
||||
|
||||
/**
|
||||
* Executes the embedding GIPS-based VNE algorithm.
|
||||
*
|
||||
* @param model Resource set that contains the model (= the root node of the
|
||||
* model).
|
||||
* @return True if embedding was successful.
|
||||
*/
|
||||
public static boolean execute(final ResourceSet model) {
|
||||
if (model == null) {
|
||||
throw new IllegalArgumentException("Model was null.");
|
||||
}
|
||||
|
||||
if (model.getResources() == null || model.getResources().isEmpty()) {
|
||||
throw new IllegalArgumentException("Model resource set was null or empty.");
|
||||
}
|
||||
|
||||
// Initialize the API, if necessary
|
||||
if (!init) {
|
||||
api = new SeqGipsAPI();
|
||||
api.init(model);
|
||||
init = true;
|
||||
}
|
||||
|
||||
// Build the ILP problem (including updates)
|
||||
api.buildILPProblem(true);
|
||||
|
||||
// Solve the ILP problem
|
||||
final ILPSolverOutput output = api.solveILPProblem();
|
||||
|
||||
// TODO: Remove system outputs
|
||||
System.out.println("=> GIPS iflye adapter: Solver status: " + output.status());
|
||||
System.out.println("=> GIPS iflye adapter: Objective value: " + output.objectiveValue());
|
||||
|
||||
final var srv2srvMappings = api.getSrv2srv().getNonZeroVariableMappings();
|
||||
final var srv2srvRule = api.getSrv2srv().getGTRule();
|
||||
srv2srvMappings.forEach(m -> {
|
||||
System.out.println("srv2srv: " + m.getName() + ": " + m.getFreeVariables().get("index").getValue());
|
||||
// m.getFreeVariables().get(0);
|
||||
srv2srvRule.apply(m.getMatch(), true);
|
||||
});
|
||||
|
||||
final var sw2nodeMappings = api.getSw2node().getNonZeroVariableMappings();
|
||||
final var sw2nodeRule = api.getSw2node().getGTRule();
|
||||
sw2nodeMappings.forEach(m -> {
|
||||
System.out.println("sw2node: " + m.getName() + ": " + m.getFreeVariables().get("index").getValue());
|
||||
sw2nodeRule.apply(m.getMatch(), true);
|
||||
});
|
||||
|
||||
final var l2sMappings = api.getL2s().getNonZeroVariableMappings();
|
||||
final var l2sRule = api.getL2s().getGTRule();
|
||||
l2sMappings.forEach(m -> {
|
||||
System.out.println("l2s: " + m.getName() + ": " + m.getFreeVariables().get("index").getValue());
|
||||
l2sRule.apply(m.getMatch(), true);
|
||||
});
|
||||
|
||||
// // TODO: Print all variable values
|
||||
// api.getSrv2srv().getNonZeroVariableMappings().forEach(c -> {
|
||||
// // TODO: Fix print out
|
||||
// System.out.println(c.getName() + ": " + c.getFreeVariableNames());
|
||||
// });
|
||||
//
|
||||
// // TODO: This must be done in the order of the index variables
|
||||
// // Apply all valid mappings
|
||||
// api.getSrv2srv().applyNonZeroMappings();
|
||||
// api.getSw2node().applyNonZeroMappings();
|
||||
//// api.getL2p().applyNonZeroMappings();
|
||||
// api.getL2s().applyNonZeroMappings();
|
||||
//// api.getNet2net().applyNonZeroMappings();
|
||||
|
||||
// Terminate API
|
||||
// api.terminate();
|
||||
// TODO: Currently, this throws an Exception:
|
||||
//
|
||||
// java.lang.IllegalArgumentException: Cannot remove a consumer which was not
|
||||
// registered before!
|
||||
// at
|
||||
// org.emoflon.ibex.gt.api.GraphTransformationPattern.unsubscribeAppearing(GraphTransformationPattern.java:310)
|
||||
// at org.emoflon.gips.core.gt.GTMapper.terminate(GTMapper.java:69)
|
||||
// at org.emoflon.gips.core.GipsEngine.lambda$1(GIPSEngine.java:71)
|
||||
// at java.base/java.util.HashMap.forEach(HashMap.java:1421)
|
||||
// at org.emoflon.gips.core.GipsEngine.terminate(GIPSEngine.java:71)
|
||||
|
||||
return output.solutionCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the initialized state of the GIPS API.
|
||||
*/
|
||||
public static void resetInit() {
|
||||
init = false;
|
||||
}
|
||||
|
||||
}
|
|
@ -10,3 +10,259 @@ config {
|
|||
debugOutput := true;
|
||||
tolerance := true [value := 0.00001];
|
||||
}
|
||||
|
||||
// NACS
|
||||
condition serverNotMapped = forbid serverIsMapped
|
||||
pattern serverIsMapped {
|
||||
host: SubstrateServer
|
||||
|
||||
virtualNode: VirtualServer {
|
||||
-host -> host
|
||||
}
|
||||
}
|
||||
|
||||
condition switchNotMapped = forbid switchIsMapped
|
||||
pattern switchIsMapped {
|
||||
host: SubstrateNode
|
||||
|
||||
virtualSwitch: VirtualSwitch {
|
||||
-host -> host
|
||||
}
|
||||
}
|
||||
|
||||
condition linkNotMapped = forbid linkIsMapped
|
||||
pattern linkIsMapped {
|
||||
host: SubstrateHostLink
|
||||
|
||||
virtualLink: VirtualLink {
|
||||
-host -> host
|
||||
}
|
||||
}
|
||||
|
||||
condition networkNotMapped = forbid networkIsMapped && forbid networkIsMappedSrv
|
||||
pattern networkIsMapped {
|
||||
host: SubstrateNetwork
|
||||
|
||||
virtualNetwork: VirtualNetwork {
|
||||
-host -> host
|
||||
}
|
||||
}
|
||||
pattern networkIsMappedSrv {
|
||||
host: SubstrateServer
|
||||
|
||||
virtualNetwork: VirtualNetwork {
|
||||
-hostServer -> host
|
||||
}
|
||||
}
|
||||
|
||||
// Patterns for finding non embedded virtual elements
|
||||
pattern vsrvNotMapped {
|
||||
virtualServer: VirtualServer
|
||||
}
|
||||
when serverNotMapped
|
||||
|
||||
pattern vswNotMapped {
|
||||
virtualSwitch: VirtualSwitch
|
||||
}
|
||||
when switchNotMapped
|
||||
|
||||
pattern vlNotMapped {
|
||||
virtualLink: VirtualLink
|
||||
}
|
||||
when linkNotMapped
|
||||
|
||||
// Actual rules
|
||||
rule serverMatchPositive {
|
||||
root: Root {
|
||||
-networks -> substrateNetwork
|
||||
-networks -> virtualNetwork
|
||||
}
|
||||
|
||||
substrateServer: SubstrateServer {
|
||||
.residualCpu := substrateServer.residualCpu - virtualNode.cpu
|
||||
.residualMemory := substrateServer.residualMemory - virtualNode.memory
|
||||
.residualStorage := substrateServer.residualStorage - virtualNode.storage
|
||||
}
|
||||
|
||||
virtualNode: VirtualServer {
|
||||
++ -host -> substrateServer
|
||||
}
|
||||
|
||||
substrateNetwork: SubstrateNetwork {
|
||||
-nodes -> substrateServer
|
||||
}
|
||||
|
||||
virtualNetwork: VirtualNetwork {
|
||||
-nodes -> virtualNode
|
||||
}
|
||||
|
||||
# virtualNode.cpu <= substrateServer.residualCpu
|
||||
# virtualNode.memory <= substrateServer.residualMemory
|
||||
# virtualNode.storage <= substrateServer.residualStorage
|
||||
}
|
||||
when serverNotMapped
|
||||
|
||||
rule switchNodeMatchPositive {
|
||||
root: Root {
|
||||
-networks -> substrateNetwork
|
||||
-networks -> virtualNetwork
|
||||
}
|
||||
|
||||
substrateNode: SubstrateNode
|
||||
|
||||
virtualSwitch : VirtualSwitch {
|
||||
++ -host -> substrateNode
|
||||
}
|
||||
|
||||
substrateNetwork: SubstrateNetwork {
|
||||
-nodes -> substrateNode
|
||||
}
|
||||
|
||||
virtualNetwork: VirtualNetwork {
|
||||
-nodes -> virtualSwitch
|
||||
}
|
||||
}
|
||||
when switchNotMapped
|
||||
|
||||
rule linkPathMatchPositive {
|
||||
root: Root {
|
||||
-networks -> substrateNetwork
|
||||
-networks -> virtualNetwork
|
||||
}
|
||||
|
||||
substratePath: SubstratePath {
|
||||
.residualBandwidth := substratePath.residualBandwidth - virtualLink.bandwidth
|
||||
|
||||
// Update all substrate links
|
||||
forEach links->l {
|
||||
iterator::l.residualBandwidth := iterator::l.residualBandwidth - virtualLink.bandwidth
|
||||
}
|
||||
}
|
||||
|
||||
virtualLink: VirtualLink {
|
||||
++ -host -> substratePath
|
||||
}
|
||||
|
||||
substrateNetwork: SubstrateNetwork {
|
||||
-paths -> substratePath
|
||||
}
|
||||
|
||||
virtualNetwork: VirtualNetwork {
|
||||
-links -> virtualLink
|
||||
}
|
||||
|
||||
# virtualLink.bandwidth <= substratePath.residualBandwidth
|
||||
|
||||
// Explicitly exclude substrate paths with a residual bandwidth equals to 0
|
||||
# substratePath.residualBandwidth > 0
|
||||
}
|
||||
when linkNotMapped
|
||||
|
||||
rule linkServerMatchPositive {
|
||||
root: Root {
|
||||
-networks -> substrateNetwork
|
||||
-networks -> virtualNetwork
|
||||
}
|
||||
|
||||
substrateServer: SubstrateServer
|
||||
|
||||
virtualLink: VirtualLink {
|
||||
++ -host -> substrateServer
|
||||
}
|
||||
|
||||
substrateNetwork: SubstrateNetwork {
|
||||
-nodes -> substrateServer
|
||||
}
|
||||
|
||||
virtualNetwork: VirtualNetwork {
|
||||
-links -> virtualLink
|
||||
}
|
||||
}
|
||||
when linkNotMapped
|
||||
|
||||
rule networkRule {
|
||||
root: Root {
|
||||
-networks -> substrateNetwork
|
||||
-networks -> virtualNetwork
|
||||
}
|
||||
|
||||
substrateNetwork: SubstrateNetwork
|
||||
|
||||
virtualNetwork: VirtualNetwork {
|
||||
++ -host -> substrateNetwork
|
||||
}
|
||||
}
|
||||
when networkNotMapped
|
||||
|
||||
//
|
||||
// GIPSL starts here!
|
||||
//
|
||||
|
||||
// Server 2 Server
|
||||
mapping srv2srv with serverMatchPositive {
|
||||
var index : EInt
|
||||
};
|
||||
|
||||
constraint -> pattern::vsrvNotMapped {
|
||||
mappings.srv2srv->filter(m | m.nodes().virtualNode == self.nodes().virtualServer)->sum(m | m.value()) == 1
|
||||
}
|
||||
|
||||
constraint -> mapping::srv2srv {
|
||||
self.value() >= 0 + 0.001 => self.variables().index >= 0 + 0.001
|
||||
}
|
||||
|
||||
// Switch 2 Node
|
||||
mapping sw2node with switchNodeMatchPositive{
|
||||
var index : EInt
|
||||
};
|
||||
|
||||
constraint -> pattern::vswNotMapped {
|
||||
mappings.sw2node->filter(m | m.nodes().virtualSwitch == self.nodes().virtualSwitch)->sum(m | m.value()) == 1
|
||||
}
|
||||
|
||||
constraint -> mapping::sw2node {
|
||||
self.value() >= 0 + 0.001 => self.variables().index >= 0 + 0.001
|
||||
}
|
||||
|
||||
// Link 2 Server
|
||||
mapping l2s with linkServerMatchPositive {
|
||||
var index : EInt
|
||||
};
|
||||
|
||||
//constraint -> pattern::linkServerMatchPositive {
|
||||
// (mappings.srv2srv->filter(mpp | mpp.nodes().virtualNode == self.nodes().virtualLink.source & mpp.nodes().substrateServer == self.nodes().substrateServer)->sum(m | m.value()) +
|
||||
// mappings.sw2node->filter(mpp | mpp.nodes().virtualSwitch == self.nodes().virtualLink.source & mpp.nodes().substrateNode == self.nodes().substrateServer)->sum(m | m.value())) +
|
||||
// (mappings.srv2srv->filter(mpp | mpp.nodes().virtualNode == self.nodes().virtualLink.target & mpp.nodes().substrateServer == self.nodes().substrateServer)->sum(m | m.value()) +
|
||||
// mappings.sw2node->filter(mpp | mpp.nodes().virtualSwitch == self.nodes().virtualLink.target & mpp.nodes().substrateNode == self.nodes().substrateServer)->sum(m | m.value()))
|
||||
// >= 2 * mappings.l2s->filter(mpp | mpp.nodes().substrateServer == self.nodes().substrateServer & mpp.nodes().virtualLink == self.nodes().virtualLink)->sum(m | m.value())
|
||||
//}
|
||||
|
||||
constraint -> pattern::vlNotMapped {
|
||||
mappings.l2s->filter(m | m.nodes().virtualLink == self.nodes().virtualLink)->sum(m | m.value()) == 1
|
||||
}
|
||||
|
||||
constraint -> mapping::l2s {
|
||||
self.value() >= 0 + 0.001 => self.variables().index >= 0 + 0.001
|
||||
}
|
||||
|
||||
// Connect link to node mappings via the index variable
|
||||
constraint -> pattern::linkServerMatchPositive {
|
||||
mappings.l2s->filter(m | m.nodes().virtualLink == self.nodes().virtualLink & m.nodes().substrateServer == self.nodes().substrateServer)->sum(m | m.variables().index)
|
||||
>=
|
||||
mappings.srv2srv->filter(m | m.nodes().virtualNode == self.nodes().virtualLink.source)->sum(m | m.variables().index)
|
||||
+ 0.001
|
||||
|
||||
&
|
||||
|
||||
mappings.l2s->filter(m | m.nodes().virtualLink == self.nodes().virtualLink & m.nodes().substrateServer == self.nodes().substrateServer)->sum(m | m.variables().index)
|
||||
>=
|
||||
mappings.sw2node->filter(m | m.nodes().virtualSwitch == self.nodes().virtualLink.target)->sum(m | m.variables().index)
|
||||
+ 0.001
|
||||
}
|
||||
|
||||
// TODO: Implement the same mechanism for link 2 path!
|
||||
|
||||
//// TODO: There must be no duplicate index variable value
|
||||
//constraint -> mapping::srv2srv {
|
||||
// mappings.srv2srv->filter(m | m.variables().index == self.variables().index)->count() == 1
|
||||
//}
|
||||
|
|
Loading…
Reference in a new issue