ONOS-2184 - Implementation of virtual network topology provider.
Change-Id: I846ba56c138187c6e5435692798e709b74a78020
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompiler.java
index 04f42e5..1fdebe1 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompiler.java
@@ -31,15 +31,12 @@
import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
import org.onosproject.incubator.net.virtual.VirtualPort;
import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.EncapsulationType;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
-import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.net.intent.constraint.EncapsulationConstraint;
import org.onosproject.net.intent.impl.IntentCompilationException;
import org.onosproject.net.topology.TopologyService;
import org.slf4j.Logger;
@@ -93,12 +90,32 @@
Optional<Path> path = getPaths(intent).stream()
.findFirst();
if (path != null && path.isPresent()) {
- path.get().links().forEach(link -> {
- Intent physicalIntent = createPtPtIntent(intent, link);
- intents.add(physicalIntent);
+ List<Link> links = path.get().links();
- // store the virtual intent to physical intent tunnelId mapping
- store.addTunnelId(intent, TunnelId.valueOf(physicalIntent.key().toString()));
+ // First create an intent between the intent ingress CP and the first link source CP,
+ // only if the two CPs are not the same.
+ Link firstLink = links.get(0);
+ if (!intent.ingressPoint().equals(firstLink.src())) {
+ intents.add(createPtPtIntent(intent, intent.ingressPoint(), firstLink.src()));
+ }
+
+ // Next create an intent between the intent egress CP and the last link destination CP,
+ // only if the two CPs are not the same.
+ Link lastLink = links.get(links.size() - 1);
+ if (!intent.egressPoint().equals(lastLink.dst())) {
+ intents.add(createPtPtIntent(intent, lastLink.dst(), intent.egressPoint()));
+ }
+
+ // Now loop through all of the virtual links in the path and create an intent.
+ // An intent is also created connecting two virtual links.
+ final int[] index = {0};
+ links.forEach(link -> {
+ intents.add(createPtPtIntent(intent, link.src(), link.dst()));
+ if (index[0] > 0) {
+ Link previousLink = links.get(index[0] - 1);
+ intents.add(createPtPtIntent(intent, previousLink.dst(), link.src()));
+ }
+ index[0]++;
});
} else {
throw new IntentCompilationException("Unable to find a path for intent " + intent);
@@ -124,7 +141,7 @@
}
/**
- * Encodes the key using the network identifier, application identifer, source and destination
+ * Encodes the key using the network identifier, application identifier, source and destination
* connect points.
*
* @param networkId virtual network identifier
@@ -133,26 +150,26 @@
* @param dst destination connect point
* @return encoded key
*/
+
private static Key encodeKey(NetworkId networkId, ApplicationId applicationId, ConnectPoint src, ConnectPoint dst) {
String key = String.format(KEY_FORMAT, networkId, src, dst);
return Key.of(key, applicationId);
}
/**
- * Creates a point-to-point intent from the virtual network intent and virtual link.
+ * Creates a point-to-point intent using the virtual network intent between the source and destination
+ * connect point.
*
* @param intent virtual network intent
- * @param link virtual link
+ * @param src source connect point
+ * @param dst destination connect point
* @return point to point intent
*/
- private Intent createPtPtIntent(VirtualNetworkIntent intent, Link link) {
- ConnectPoint ingressPoint = mapVirtualToPhysicalPort(intent.networkId(), link.src());
- ConnectPoint egressPoint = mapVirtualToPhysicalPort(intent.networkId(), link.dst());
+ private Intent createPtPtIntent(VirtualNetworkIntent intent, ConnectPoint src, ConnectPoint dst) {
+ ConnectPoint ingressPoint = mapVirtualToPhysicalPort(intent.networkId(), src);
+ ConnectPoint egressPoint = mapVirtualToPhysicalPort(intent.networkId(), dst);
Key intentKey = encodeKey(intent.networkId(), intent.appId(), ingressPoint, egressPoint);
- List<Constraint> constraints = new ArrayList<>();
- constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
-
// TODO Currently there can only be one intent between the ingress and egress across
// all virtual networks. We may want to support multiple intents between the same src/dst pairs.
PointToPointIntent physicalIntent = PointToPointIntent.builder()
@@ -160,11 +177,16 @@
.appId(intent.appId())
.ingressPoint(ingressPoint)
.egressPoint(egressPoint)
- .constraints(constraints)
+ .constraints(intent.constraints())
+ .selector(intent.selector())
+ .treatment(intent.treatment())
.build();
log.debug("Submitting physical intent: " + physicalIntent);
intentService.submit(physicalIntent);
+ // Store the physical intent against this virtual intent.
+ store.addTunnelId(intent, TunnelId.valueOf(physicalIntent.key().toString()));
+
return physicalIntent;
}