REST API for pseudowire addition / deletion.
Refactored pseudowire code to use REST in order
to add or delete pseudowires individually. Previous implementation
used the network configuration, which is now completely
removed from the code. Further, I re-organized the code
and create a utility class that holds all the necessary
functionality for verifying pseudowires.
Further, I removed all mastership checks in the pw code
since now a specific pseudowire creation is sent to a single
instance, which will handle the call.
Change-Id: I1eb5e7cc7730ad792ea84dd389475768153e2b68
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index d951b53..b9912ac 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -15,8 +15,6 @@
*/
package org.onosproject.segmentrouting;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
@@ -94,7 +92,6 @@
import org.onosproject.routeservice.RouteService;
import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
import org.onosproject.segmentrouting.config.DeviceConfiguration;
-import org.onosproject.segmentrouting.config.PwaasConfig;
import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
import org.onosproject.segmentrouting.config.XConnectConfig;
@@ -104,9 +101,13 @@
import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelHandler;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+
import org.onosproject.segmentrouting.pwaas.L2Tunnel;
import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
+
import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
import org.onosproject.segmentrouting.storekey.McastStoreKey;
import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
@@ -142,6 +143,7 @@
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_REGISTERED;
import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UNREGISTERED;
+import static org.onosproject.segmentrouting.pwaas.PwaasUtil.configurationValidity;
/**
* Segment routing manager.
@@ -234,7 +236,7 @@
private RouteHandler routeHandler = null;
LinkHandler linkHandler = null;
private SegmentRoutingNeighbourDispatcher neighbourHandler = null;
- private L2TunnelHandler l2TunnelHandler = null;
+ private DefaultL2TunnelHandler l2TunnelHandler = null;
private InternalEventHandler eventHandler = new InternalEventHandler();
private final InternalHostListener hostListener = new InternalHostListener();
private final InternalConfigListener cfgListener = new InternalConfigListener(this);
@@ -314,16 +316,6 @@
}
};
- private final ConfigFactory<ApplicationId, PwaasConfig> pwaasConfigFactory =
- new ConfigFactory<ApplicationId, PwaasConfig>(
- SubjectFactories.APP_SUBJECT_FACTORY,
- PwaasConfig.class, "pwaas") {
- @Override
- public PwaasConfig createConfig() {
- return new PwaasConfig();
- }
- };
-
private static final Object THREAD_SCHED_LOCK = new Object();
private static int numOfEventsQueued = 0;
private static int numOfEventsExecuted = 0;
@@ -430,7 +422,6 @@
cfgService.registerConfigFactory(appConfigFactory);
cfgService.registerConfigFactory(xConnectConfigFactory);
cfgService.registerConfigFactory(mcastConfigFactory);
- cfgService.registerConfigFactory(pwaasConfigFactory);
log.info("Configuring network before adding listeners");
cfgListener.configureNetwork();
@@ -474,7 +465,6 @@
cfgService.unregisterConfigFactory(appConfigFactory);
cfgService.unregisterConfigFactory(xConnectConfigFactory);
cfgService.unregisterConfigFactory(mcastConfigFactory);
- cfgService.unregisterConfigFactory(pwaasConfigFactory);
compCfgService.unregisterProperties(getClass(), false);
hostService.removeListener(hostListener);
@@ -567,55 +557,90 @@
}
@Override
- public L2TunnelHandler.Result addPseudowire(String tunnelId, String pwLabel, String cP1,
- String cP1InnerVlan, String cP1OuterVlan, String cP2,
- String cP2InnerVlan, String cP2OuterVlan,
- String mode, String sdTag) {
- // Try to inject an empty Pwaas config if it is not found for the first time
- PwaasConfig config = cfgService.getConfig(appId(), PwaasConfig.class);
- if (config == null) {
- log.debug("Pwaas config not found. Try to create an empty one.");
- cfgService.applyConfig(appId(), PwaasConfig.class, new ObjectMapper().createObjectNode());
- config = cfgService.getConfig(appId(), PwaasConfig.class);
+ public L2TunnelHandler.Result addPseudowire(L2TunnelDescription l2TunnelDescription) {
+
+ List<L2Tunnel> tunnels = getL2Tunnels();
+ List<L2TunnelPolicy> policies = getL2Policies();
+
+ // combine polices and tunnels to pseudowires
+ List<L2TunnelDescription> pseudowires = tunnels.stream()
+ .map(l2Tunnel -> {
+ L2TunnelPolicy policy = null;
+ for (L2TunnelPolicy l2Policy : policies) {
+ if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
+ policy = l2Policy;
+ break;
+ }
+ }
+
+ return new DefaultL2TunnelDescription(l2Tunnel, policy);
+ })
+ .collect(Collectors.toList());
+
+
+ // creating a new list with the new pseudowire
+ Set<L2TunnelDescription> newPseudowires = new HashSet<>(pseudowires);
+
+ // corner case where we try to add the exact same pseudowire
+ if (newPseudowires.contains(l2TunnelDescription)) {
+ log.info("Pseudowire with {} already exists!", l2TunnelDescription);
+ return L2TunnelHandler.Result.SUCCESS;
}
- ObjectNode object = config.addPseudowire(tunnelId, pwLabel,
- cP1, cP1InnerVlan, cP1OuterVlan,
- cP2, cP2InnerVlan, cP2OuterVlan,
- mode, sdTag);
- if (object == null) {
- log.warn("Could not add pseudowire to the configuration!");
+ // add the new pseudowire to the Set
+ newPseudowires.add(l2TunnelDescription);
+
+ // validate the new set of pseudowires
+ boolean res = configurationValidity(newPseudowires);
+ if (res) {
+
+ // deploy a set with ONLY the new pseudowire
+ newPseudowires = new HashSet<>();
+ newPseudowires.add(l2TunnelDescription);
+ l2TunnelHandler.deploy(newPseudowires);
+
+ log.info("Pseudowire with {} deployment started, check log for any errors in this process!",
+ l2TunnelDescription.l2Tunnel().tunnelId());
+ return L2TunnelHandler.Result.SUCCESS;
+ } else {
+
+ log.error("Pseudowire with {} can not be added!", l2TunnelDescription.l2Tunnel().tunnelId());
return L2TunnelHandler.Result.ADDITION_ERROR;
}
-
- // inform everyone about the valid change in the pw configuration
- cfgService.applyConfig(appId(), PwaasConfig.class, object);
- return L2TunnelHandler.Result.SUCCESS;
}
@Override
- public L2TunnelHandler.Result removePseudowire(String pwId) {
+ public L2TunnelHandler.Result removePseudowire(Integer pwId) {
- PwaasConfig config = cfgService.getConfig(appId(), PwaasConfig.class);
- if (config == null) {
- log.warn("Configuration for Pwaas class could not be found!");
- return L2TunnelHandler.Result.CONFIG_NOT_FOUND;
- }
+ List<L2Tunnel> tunnels = getL2Tunnels();
+ List<L2TunnelPolicy> policies = getL2Policies();
- ObjectNode object = config.removePseudowire(pwId);
- if (object == null) {
- log.warn("Could not delete pseudowire from configuration!");
+ // get the pseudowire, if it exists
+ List<L2TunnelDescription> pseudowires = tunnels.stream().map(l2Tunnel -> {
+ L2TunnelPolicy policy = null;
+ for (L2TunnelPolicy l2Policy : policies) {
+ if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
+ policy = l2Policy;
+ break;
+ }
+ }
+
+ return new DefaultL2TunnelDescription(l2Tunnel, policy);
+ }).filter(l2desc ->
+ l2desc.l2Tunnel().tunnelId() == pwId
+ ).collect(Collectors.toList());
+
+ if (pseudowires.size() == 0) {
+ log.error("Pseudowire with id {} does not exist", pwId);
return L2TunnelHandler.Result.REMOVAL_ERROR;
+ } else {
+
+ l2TunnelHandler.tearDown(new HashSet<>(pseudowires));
+
+ log.info("Removal of pseudowire with {} started, check log for any errors in this process!",
+ pwId);
+ return L2TunnelHandler.Result.SUCCESS;
}
-
- // sanity check, this should never fail since we removed a pw
- // and we always check when we update the configuration
- config.isValid();
-
- // inform everyone
- cfgService.applyConfig(appId(), PwaasConfig.class, object);
-
- return L2TunnelHandler.Result.SUCCESS;
}
@Override
@@ -1411,21 +1436,6 @@
default:
break;
}
- } else if (event.configClass().equals(PwaasConfig.class)) {
- checkState(l2TunnelHandler != null, "DefaultL2TunnelHandler is not initialized");
- switch (event.type()) {
- case CONFIG_ADDED:
- l2TunnelHandler.processPwaasConfigAdded(event);
- break;
- case CONFIG_UPDATED:
- l2TunnelHandler.processPwaasConfigUpdated(event);
- break;
- case CONFIG_REMOVED:
- l2TunnelHandler.processPwaasConfigRemoved(event);
- break;
- default:
- break;
- }
}
}
@@ -1440,8 +1450,7 @@
if (!event.configClass().equals(SegmentRoutingDeviceConfig.class) &&
!event.configClass().equals(SegmentRoutingAppConfig.class) &&
!event.configClass().equals(InterfaceConfig.class) &&
- !event.configClass().equals(XConnectConfig.class) &&
- !event.configClass().equals(PwaasConfig.class)) {
+ !event.configClass().equals(XConnectConfig.class)) {
log.debug("Ignore event {} due to class mismatch", event);
return false;
}