Adding Encapsulation in VPLS and correcting bugs.
Change-Id: Idc0c1834ae2bbd0fdaf564fd65360cc0f018d18d
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
index 52a3924..2cec14a 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
@@ -15,21 +15,25 @@
*/
package org.onosproject.vpls;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.Host;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.intent.ConnectivityIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
import org.onosproject.routing.IntentSynchronizationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,6 +42,8 @@
import java.util.List;
import java.util.Set;
+import static org.onosproject.net.EncapsulationType.*;
+
/**
* Synchronizes intents between the in-memory intent store and the
* IntentService.
@@ -64,7 +70,7 @@
static final String PREFIX_BROADCAST = "brc";
static final String PREFIX_UNICAST = "uni";
- static final String DASH = "-";
+ static final String SEPARATOR = "-";
private final ApplicationId appId;
private final IntentSynchronizationService intentSynchronizer;
@@ -107,8 +113,8 @@
/**
* Returns list of intents belongs to a VPLS.
*
- * @param name required VPLS network name
- * @return list of intents belongs to a VPLS
+ * @param name the name of the VPLS
+ * @return the list of intents belonging to a VPLS
*/
protected List<Intent> getIntentsFromVpls(String name) {
List<Intent> intents = Lists.newArrayList();
@@ -128,28 +134,32 @@
* @param key key to identify the intent
* @param src the source connect point
* @param dsts the destination connect points
+ * @param encap the encapsulation type
* @return the generated single-point to multi-point intent
*/
protected SinglePointToMultiPointIntent buildBrcIntent(Key key,
FilteredConnectPoint src,
- Set<FilteredConnectPoint> dsts) {
- log.debug(SP2MP, src);
+ Set<FilteredConnectPoint> dsts,
+ EncapsulationType encap) {
+ log.debug("Building broadcast intent {} for source {}", SP2MP, src);
- SinglePointToMultiPointIntent intent;
+ SinglePointToMultiPointIntent.Builder intentBuilder;
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthDst(MacAddress.BROADCAST)
.build();
- intent = SinglePointToMultiPointIntent.builder()
+ intentBuilder = SinglePointToMultiPointIntent.builder()
.appId(appId)
.key(key)
.selector(selector)
.filteredIngressPoint(src)
.filteredEgressPoints(dsts)
- .priority(PRIORITY_OFFSET)
- .build();
- return intent;
+ .priority(PRIORITY_OFFSET);
+
+ encap(intentBuilder, encap);
+
+ return intentBuilder.build();
}
/**
@@ -159,54 +169,60 @@
* @param srcs the source Connect Points
* @param dst the destination Connect Point
* @param host destination Host
+ * @param encap the encapsulation type
* @return the generated multi-point to single-point intent
*/
protected MultiPointToSinglePointIntent buildUniIntent(Key key,
Set<FilteredConnectPoint> srcs,
FilteredConnectPoint dst,
- Host host) {
- log.debug(MP2SP, dst);
+ Host host,
+ EncapsulationType encap) {
+ log.debug("Building unicast intent {} for destination {}", MP2SP, dst);
+
+ MultiPointToSinglePointIntent.Builder intentBuilder;
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthDst(host.mac())
.build();
-
- return MultiPointToSinglePointIntent.builder()
+ intentBuilder = MultiPointToSinglePointIntent.builder()
.appId(appId)
.key(key)
.selector(selector)
.filteredIngressPoints(srcs)
.filteredEgressPoint(dst)
- .priority(PRIORITY_OFFSET)
- .build();
+ .priority(PRIORITY_OFFSET);
+ encap(intentBuilder, encap);
+
+ return intentBuilder.build();
}
/**
- * Builds an intent Key for either for a single-point to multi-point or
- * multi-point to single-point intent, based on a prefix that defines
- * the type of intent, the single connection point representing the source
- * or the destination and the VLAN identifier representing the network.
+ * Builds an intent key either for single-point to multi-point or
+ * multi-point to single-point intents, based on a prefix that defines
+ * the type of intent, the single connect point representing the single
+ * source or destination for that intent, the name of the VPLS the intent
+ * belongs to, and the destination host MAC address the intent reaches.
*
- * @param prefix key prefix
- * @param cPoint connect point for single source/destination
- * @param networkName VPLS network name
- * @param hostMac source/destination mac address
- * @return key to identify the intent
+ * @param prefix the key prefix
+ * @param cPoint the connect point identifying the source/destination
+ * @param vplsName the name of the VPLS
+ * @param hostMac the source/destination MAC address
+ * @return the key to identify the intent
*/
protected Key buildKey(String prefix,
ConnectPoint cPoint,
- String networkName,
+ String vplsName,
MacAddress hostMac) {
- String keyString = networkName +
- DASH +
+ String keyString = vplsName +
+ SEPARATOR +
prefix +
- DASH +
+ SEPARATOR +
cPoint.deviceId() +
- DASH +
+ SEPARATOR +
cPoint.port() +
- DASH +
+ SEPARATOR +
hostMac;
return Key.of(keyString, appId);
@@ -215,8 +231,8 @@
/**
* Returns true if the specified intent exists; false otherwise.
*
- * @param intentKey intent key
- * @return true if the intent exists, false otherwise
+ * @param intentKey the intent key
+ * @return true if the intent exists; false otherwise
*/
protected boolean intentExists(Key intentKey) {
if (intentService.getIntent(intentKey) == null) {
@@ -225,10 +241,22 @@
// Intent does not exist if intent withdrawn
IntentState currentIntentState = intentService.getIntentState(intentKey);
- if (WITHDRAWN_INTENT_STATES.contains(currentIntentState)) {
- return false;
- }
+ return !WITHDRAWN_INTENT_STATES.contains(currentIntentState);
- return true;
+ }
+
+ /**
+ * Adds an encapsulation constraint to the builder given, if encap is not
+ * equal to NONE.
+ *
+ * @param builder the intent builder
+ * @param encap the encapsulation type
+ */
+ private static void encap(ConnectivityIntent.Builder builder,
+ EncapsulationType encap) {
+ if (!encap.equals(NONE)) {
+ builder.constraints(ImmutableList.of(
+ new EncapsulationConstraint(encap)));
+ }
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
index 4e4bd4b..039cd12 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
@@ -33,6 +33,7 @@
import org.onosproject.incubator.net.intf.InterfaceEvent;
import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.EncapsulationType;
import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.Host;
import org.onosproject.net.config.NetworkConfigEvent;
@@ -63,13 +64,10 @@
import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
/**
- * Application to create L2 broadcast overlay networks using VLAN.
+ * Application to create L2 broadcast overlay networks using VLANs.
*/
@Component(immediate = true)
public class Vpls {
- /**
- * Application name of VPLS.
- */
static final String VPLS_APP = "org.onosproject.vpls";
private static final String HOST_FCP_NOT_FOUND =
@@ -108,8 +106,8 @@
private final HostListener hostListener = new InternalHostListener();
- private final InternalInterfaceListener interfaceListener
- = new InternalInterfaceListener();
+ private final InternalInterfaceListener interfaceListener =
+ new InternalInterfaceListener();
private final InternalNetworkConfigListener configListener =
new InternalNetworkConfigListener();
@@ -155,16 +153,16 @@
*/
private void setupConnectivity(boolean isNetworkConfigEvent) {
SetMultimap<String, Interface> networkInterfaces =
- vplsConfigService.getVplsNetworks();
+ vplsConfigService.ifacesByVplsName();
Set<String> vplsAffectedByApi =
- new HashSet<>(vplsConfigService.getVplsAffectedByApi());
+ new HashSet<>(vplsConfigService.vplsAffectedByApi());
if (isNetworkConfigEvent && vplsAffectedByApi.isEmpty()) {
- vplsAffectedByApi.addAll(vplsConfigService.getOldVpls());
+ vplsAffectedByApi.addAll(vplsConfigService.vplsNamesOld());
}
- networkInterfaces.asMap().forEach((networkName, interfaces) -> {
+ networkInterfaces.asMap().forEach((vplsName, interfaces) -> {
Set<Host> hosts = Sets.newHashSet();
interfaces.forEach(intf -> {
// Add hosts that belongs to the specific VPLS
@@ -174,14 +172,17 @@
.forEach(hosts::add);
});
- setupConnectivity(networkName, interfaces, hosts,
- vplsAffectedByApi.contains(networkName));
- vplsAffectedByApi.remove(networkName);
+ EncapsulationType encap =
+ vplsConfigService.encap(vplsName);
+
+ setupConnectivity(vplsName, interfaces, hosts, encap,
+ vplsAffectedByApi.contains(vplsName));
+ vplsAffectedByApi.remove(vplsName);
});
if (!vplsAffectedByApi.isEmpty()) {
- for (String networkName:vplsAffectedByApi) {
- withdrawIntents(networkName, Lists.newArrayList());
+ for (String vplsName : vplsAffectedByApi) {
+ withdrawIntents(vplsName, Lists.newArrayList());
}
}
}
@@ -189,28 +190,30 @@
/**
* Sets up connectivity for specific VPLS.
*
- * @param networkName the VPLS name
+ * @param vplsName the VPLS name
* @param interfaces the interfaces that belong to the VPLS
* @param hosts the hosts that belong to the VPLS
+ * @param encap the encapsulation type
* @param affectedByApi true if this function is triggered from the APIs;
* false otherwise
*/
- private void setupConnectivity(String networkName,
+ private void setupConnectivity(String vplsName,
Collection<Interface> interfaces,
Set<Host> hosts,
+ EncapsulationType encap,
boolean affectedByApi) {
List<Intent> intents = Lists.newArrayList();
List<Key> keys = Lists.newArrayList();
Set<FilteredConnectPoint> fcPoints = buildFCPoints(interfaces);
- intents.addAll(buildUnicastIntents(
- networkName, hosts, fcPoints, affectedByApi));
intents.addAll(buildBroadcastIntents(
- networkName, fcPoints, affectedByApi));
+ vplsName, fcPoints, encap, affectedByApi));
+ intents.addAll(buildUnicastIntents(
+ vplsName, hosts, fcPoints, encap, affectedByApi));
if (affectedByApi) {
intents.forEach(intent -> keys.add(intent.key()));
- withdrawIntents(networkName, keys);
+ withdrawIntents(vplsName, keys);
}
intentInstaller.submitIntents(intents);
@@ -219,14 +222,13 @@
/**
* Withdraws intents belonging to a VPLS, given a VPLS name.
*
- * @param networkName the VPLS name
+ * @param vplsName the VPLS name
* @param keys the keys of the intents to be installed
*/
- private void withdrawIntents(String networkName,
- List<Key> keys) {
+ private void withdrawIntents(String vplsName, List<Key> keys) {
List<Intent> intents = Lists.newArrayList();
- intentInstaller.getIntentsFromVpls(networkName)
+ intentInstaller.getIntentsFromVpls(vplsName)
.forEach(intent -> {
if (!keys.contains(intent.key())) {
intents.add(intent);
@@ -239,14 +241,16 @@
/**
* Sets up broadcast intents between any given filtered connect point.
*
- * @param networkName the VPLS name
+ * @param vplsName the VPLS name
* @param fcPoints the set of filtered connect points
+ * @param encap the encapsulation type
* @param affectedByApi true if the function triggered from APIs;
* false otherwise
* @return the set of broadcast intents
*/
- private Set<Intent> buildBroadcastIntents(String networkName,
+ private Set<Intent> buildBroadcastIntents(String vplsName,
Set<FilteredConnectPoint> fcPoints,
+ EncapsulationType encap,
boolean affectedByApi) {
Set<Intent> intents = Sets.newHashSet();
fcPoints.forEach(point -> {
@@ -257,14 +261,15 @@
Key brcKey = intentInstaller.buildKey(PREFIX_BROADCAST,
point.connectPoint(),
- networkName,
+ vplsName,
MacAddress.BROADCAST);
- if ((!intentInstaller.intentExists(brcKey) || affectedByApi) &&
- !otherPoints.isEmpty()) {
+ if ((!intentInstaller.intentExists(brcKey) || affectedByApi)
+ && !otherPoints.isEmpty()) {
intents.add(intentInstaller.buildBrcIntent(brcKey,
point,
- otherPoints));
+ otherPoints,
+ encap));
}
});
@@ -274,16 +279,18 @@
/**
* Sets up unicast intents between any given filtered connect point.
*
- * @param networkName the VPLS name
+ * @param vplsName the VPLS name
* @param hosts the set of destination hosts
* @param fcPoints the set of filtered connect points
+ * @param encap the encapsulation type
* @param affectedByApi true if the function triggered from APIs;
* false otherwise
* @return the set of unicast intents
*/
- private Set<Intent> buildUnicastIntents(String networkName,
+ private Set<Intent> buildUnicastIntents(String vplsName,
Set<Host> hosts,
Set<FilteredConnectPoint> fcPoints,
+ EncapsulationType encap,
boolean affectedByApi) {
Set<Intent> intents = Sets.newHashSet();
hosts.forEach(host -> {
@@ -301,7 +308,7 @@
Key uniKey = intentInstaller.buildKey(PREFIX_UNICAST,
host.location(),
- networkName,
+ vplsName,
host.mac());
if ((!intentInstaller.intentExists(uniKey) || affectedByApi) &&
@@ -309,7 +316,8 @@
intents.add(intentInstaller.buildUniIntent(uniKey,
otherPoints,
hostPoint,
- host));
+ host,
+ encap));
}
});
@@ -346,7 +354,7 @@
* @return the set of filtered connect points
*/
private Set<FilteredConnectPoint> buildFCPoints(Collection<Interface> interfaces) {
- // Build all filtered connected points in the network
+ // Build all filtered connected points in the VPLS
return interfaces
.stream()
.map(intf -> {
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java b/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
index d706dca..f2bfa9d 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
@@ -45,14 +45,14 @@
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Handles neighbour messages for VPLS use case.
- * Handlers will be changed automatically by interface or network configuration events.
+ * Handles neighbour messages for on behalf of the VPLS application. Handlers
+ * will be changed automatically by interface or network configuration events.
*/
@Component(immediate = true)
public class VplsNeighbourHandler {
private static final String UNKNOWN_CONTEXT = "Unknown context type: {}";
- private static final String CAN_NOT_FIND_NETWORK =
+ private static final String CAN_NOT_FIND_VPLS =
"Cannot find VPLS for port {} with VLAN Id {}.";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -70,8 +70,8 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected NetworkConfigService configService;
- private VplsInterfaceListener interfaceListener
- = new VplsInterfaceListener();
+ private VplsInterfaceListener interfaceListener =
+ new VplsInterfaceListener();
protected VplsNeighbourMessageHandler neighbourHandler =
new VplsNeighbourMessageHandler();
@@ -101,7 +101,7 @@
private void configNeighbourHandler() {
neighbourService.unregisterNeighbourHandlers(appId);
- Set<Interface> interfaces = vplsConfigService.getAllInterfaces();
+ Set<Interface> interfaces = vplsConfigService.allIfaces();
interfaceService.getInterfaces()
.stream()
@@ -145,17 +145,18 @@
*/
protected void handleRequest(NeighbourMessageContext context) {
- SetMultimap<String, Interface> vplsNetwork =
- vplsConfigService.getVplsNetwork(context.vlan(), context.inPort());
+ SetMultimap<String, Interface> vpls =
+ vplsConfigService.ifacesByVplsName(context.vlan(),
+ context.inPort());
- if (vplsNetwork != null) {
- Collection<Interface> vplsInterfaces = vplsNetwork.values();
+ if (vpls != null) {
+ Collection<Interface> vplsInterfaces = vpls.values();
vplsInterfaces.stream()
.filter(intf -> !context.inPort().equals(intf.connectPoint()))
.forEach(context::forward);
} else {
- log.debug(CAN_NOT_FIND_NETWORK, context.inPort(), context.vlan());
+ log.debug(CAN_NOT_FIND_VPLS, context.inPort(), context.vlan());
}
}
@@ -168,18 +169,19 @@
protected void handleReply(NeighbourMessageContext context,
HostService hostService) {
- SetMultimap<String, Interface> vplsNetwork =
- vplsConfigService.getVplsNetwork(context.vlan(), context.inPort());
+ SetMultimap<String, Interface> vpls =
+ vplsConfigService.ifacesByVplsName(context.vlan(),
+ context.inPort());
Set<Host> hosts = hostService.getHostsByMac(context.dstMac());
- if (vplsNetwork != null) {
- Collection<Interface> vplsInterfaces = vplsNetwork.values();
+ if (vpls != null) {
+ Collection<Interface> vplsInterfaces = vpls.values();
hosts.forEach(host -> vplsInterfaces.stream()
.filter(intf -> intf.connectPoint().equals(host.location()))
.filter(intf -> intf.vlan().equals(host.vlan()))
.forEach(context::forward));
} else {
- log.debug(CAN_NOT_FIND_NETWORK, context.inPort(), context.vlan());
+ log.debug(CAN_NOT_FIND_VPLS, context.inPort(), context.vlan());
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsAddCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsAddCommand.java
index ffeb81f..b2c1da5 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsAddCommand.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsAddCommand.java
@@ -26,9 +26,9 @@
/**
* CLI to create VPLSs.
*/
-@Command(scope = "onos", name = "vpls-add", description = "Create a new VPLS")
+@Command(scope = "onos", name = "vpls-add", description = "Creates a new VPLS")
public class VplsAddCommand extends AbstractShellCommand {
- private static final String VPLS_EXIST = "VPLS already exists: %s";
+
private VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
@@ -38,11 +38,12 @@
@Override
protected void execute() {
-
- if (vplsConfigService.getAllVpls().contains(vplsName)) {
- print(VPLS_EXIST, vplsName);
+ // Check if the VPLS name is already configured
+ if (VplsCommandUtils.vplsExists(vplsName)) {
+ print(VplsCommandUtils.VPLS_ALREADY_EXISTS, vplsName);
return;
}
- vplsConfigService.addVpls(vplsName, new HashSet<>());
+
+ vplsConfigService.addVpls(vplsName, new HashSet<>(), null);
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsAddIfaceCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsAddIfaceCommand.java
index 5daaa9e..d6a50ff 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsAddIfaceCommand.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsAddIfaceCommand.java
@@ -21,19 +21,14 @@
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.vpls.config.VplsConfigurationService;
-import java.util.Map;
-
/**
* CLI to add an interface to a VPLS.
*/
@Command(scope = "onos", name = "vpls-add-iface",
- description = "Add an interface to an existing VPLS")
+ description = "Adds an interface to an existing VPLS")
public class VplsAddIfaceCommand extends AbstractShellCommand {
- private static final String IFACE_ADD_FAIL = "Interface cannot be added.";
- private static final String IFACE_EXIST =
- "Interface %s already associated to network %s.";
- private VplsConfigurationService vplsConfigService =
+ private static VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
@Argument(index = 0, name = "vplsName", description = "Name of the VPLS",
@@ -46,24 +41,25 @@
@Override
protected void execute() {
- if (!vplsConfigService.getAllVpls().contains(vplsName)) {
- print(IFACE_ADD_FAIL);
+ // Check if the VPLS exists
+ if (!VplsCommandUtils.vplsExists(vplsName)) {
+ print(VplsCommandUtils.VPLS_NOT_FOUND, vplsName);
return;
}
- if (vplsConfigService.getAllInterfaces()
- .stream()
- .anyMatch(e -> e.name().equals(ifaceName))) {
- print(IFACE_EXIST, ifaceName, vplsConfigService.getVplsNetworks()
- .entries()
- .stream()
- .filter(e->e.getValue().name().equals(ifaceName))
- .map(Map.Entry::getKey)
- .findFirst()
- .get());
+ // Check if the interface exists
+ if (!VplsCommandUtils.ifaceExists(ifaceName)) {
+ print(VplsCommandUtils.IFACE_NOT_FOUND, ifaceName);
return;
}
- vplsConfigService.addInterfaceToVpls(vplsName, ifaceName);
+ // Check if the interface is already associated to a VPLS
+ if (VplsCommandUtils.ifaceAlreadyAssociated(ifaceName)) {
+ print(VplsCommandUtils.IFACE_ALREADY_ASSOCIATED,
+ ifaceName, VplsCommandUtils.vplsNameFromIfaceName(ifaceName));
+ return;
+ }
+
+ vplsConfigService.addIface(vplsName, ifaceName);
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCleanCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCleanCommand.java
index 6507d6b..4156e08 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCleanCommand.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCleanCommand.java
@@ -31,6 +31,6 @@
@Override
protected void execute() {
- vplsConfigService.cleanVpls();
+ vplsConfigService.cleanVplsConfig();
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommandUtils.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommandUtils.java
new file mode 100644
index 0000000..52c74a4
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommandUtils.java
@@ -0,0 +1,118 @@
+package org.onosproject.vpls.cli;
+
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.vpls.config.VplsConfigurationService;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.onlab.osgi.DefaultServiceDirectory.getService;
+
+/**
+ * Util class for VPLS Commands.
+ */
+public final class VplsCommandUtils {
+
+ protected static final String VPLS_NAME = "VPLS name %s: ";
+ protected static final String VPLS_DISPLAY = "VPLS name: %s, associated " +
+ "interfaces: %s, encapsulation: %s";
+ protected static final String VPLS_NOT_FOUND = "VPLS %s not found.";
+ protected static final String IFACE_NOT_FOUND = "Interface %s not found.";
+ protected static final String VPLS_ALREADY_EXISTS = "VPLS %s already exists.";
+ protected static final String IFACE_ALREADY_ASSOCIATED =
+ "Interface %s already associated to VPLS %s.";
+ protected static final String IFACE_NOT_ASSOCIATED =
+ "Interface %s is associated to VPLS %s.";
+
+ private static VplsConfigurationService vplsConfigService =
+ getService(VplsConfigurationService.class);
+ private static InterfaceService interfaceService =
+ getService(InterfaceService.class);
+
+ private VplsCommandUtils() {}
+
+ /**
+ * States if a VPLS exists or not.
+ *
+ * @param vplsName the name of the VPLS
+ * @return true if the VPLS exists; false otherwise
+ */
+ protected static boolean vplsExists(String vplsName) {
+ return vplsConfigService.vplsNames().contains(vplsName);
+ }
+
+ /**
+ * States if an interface is defined or not in the system.
+ *
+ * @param ifaceName the name of the interface
+ * @return true if the interface is defined; false otherwise
+ */
+ protected static boolean ifaceExists(String ifaceName) {
+ return interfaceService.getInterfaces()
+ .stream()
+ .anyMatch(iface -> iface.name().equals(ifaceName));
+ }
+
+ /**
+ * States if an interface is already associated or not to a VPLS.
+ *
+ * @param ifaceName the name of the interface
+ * @return true if the interface is already associated to a VPLS; false
+ * otherwise
+ */
+ protected static boolean ifaceAlreadyAssociated(String ifaceName) {
+ return vplsConfigService.allIfaces()
+ .stream()
+ .anyMatch(iface -> iface.name().equals(ifaceName));
+ }
+
+ /**
+ * Returns the name of a VPLS, given the name of an interface associated to
+ * it.
+ *
+ * @param ifaceName the name of the interface
+ * @return the name of the VPLS that has the interface configured; null if
+ * the interface does not exist or is not associated to any VPLS
+ */
+ protected static String vplsNameFromIfaceName(String ifaceName) {
+ String vplsName = null;
+
+ Optional<String> optVplsName = vplsConfigService.ifacesByVplsName()
+ .entries()
+ .stream()
+ .filter(iface -> iface.getValue().name().equals(ifaceName))
+ .map(Map.Entry::getKey)
+ .findFirst();
+
+ if (optVplsName.isPresent()) {
+ vplsName = optVplsName.get();
+ }
+
+ return vplsName;
+ }
+
+ /**
+ * Returns a list of interfaces associated to a VPLS, given a VPLS name.
+ *
+ * @param vplsName the name of the VPLS
+ * @return the set of interfaces associated to the given VPLS; null if the
+ * VPLS is not found
+ */
+ protected static Set<String> ifacesFromVplsName(String vplsName) {
+ if (!vplsExists(vplsName)) {
+ return null;
+ }
+
+ SetMultimap<String, Interface> ifacesByVplsName =
+ vplsConfigService.ifacesByVplsName();
+ Set<String> ifaceNames = Sets.newHashSet();
+
+ ifacesByVplsName.get(vplsName).forEach(iface -> ifaceNames.add(iface.name()));
+
+ return ifaceNames;
+ }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsDelCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsDelCommand.java
index 693ad97..23e77ee 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsDelCommand.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsDelCommand.java
@@ -25,11 +25,9 @@
* CLI to remove VPLSs.
*/
@Command(scope = "onos", name = "vpls-del",
- description = "Deletes a VPLS")
+ description = "Deletes an existing VPLS")
public class VplsDelCommand extends AbstractShellCommand {
- private static final String NETWORK_NOT_FOUND =
- "VPLS %s not found";
private VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
@@ -39,9 +37,8 @@
@Override
protected void execute() {
-
- if (!vplsConfigService.getAllVpls().contains(vplsName)) {
- print(NETWORK_NOT_FOUND, vplsName);
+ if (!VplsCommandUtils.vplsExists(vplsName)) {
+ print(VplsCommandUtils.VPLS_NOT_FOUND, vplsName);
return;
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsDelIfaceCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsDelIfaceCommand.java
index 695e48f..adf9ce9 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsDelIfaceCommand.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsDelIfaceCommand.java
@@ -19,11 +19,8 @@
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.vpls.config.VplsConfigurationService;
-import java.util.Set;
-
/**
* CLI to remove an interface from an existing VPLS.
*/
@@ -31,23 +28,36 @@
description = "Removes an interface from an existing VPLS")
public class VplsDelIfaceCommand extends AbstractShellCommand {
- private static final String NO_CONFIGURATION = "Interface %s is not configured";
private VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
- @Argument(index = 0, name = "IFACE_NAME", description = "Name of the interface" +
- " to remove from the VPLS", required = true, multiValued = false)
+ @Argument(index = 0, name = "vplsName", description = "Name of the VPLS",
+ required = true, multiValued = false)
+ private String vplsName = null;
+
+ @Argument(index = 1, name = "ifaceName", description = "Name of the interface" +
+ " to be removed from the VPLS", required = true, multiValued = false)
private String ifaceName = null;
@Override
protected void execute() {
- Set<Interface> ifaces = vplsConfigService.getAllInterfaces();
-
- if (!ifaces.stream().map(Interface::name).anyMatch(ifaceName::equals)) {
- print(NO_CONFIGURATION, ifaceName);
+ if (!VplsCommandUtils.vplsExists(vplsName)) {
+ print(VplsCommandUtils.VPLS_NOT_FOUND, vplsName);
+ return;
}
- vplsConfigService.removeInterfaceFromVpls(ifaceName);
+ if (!VplsCommandUtils.ifaceExists(ifaceName)) {
+ print(VplsCommandUtils.IFACE_NOT_FOUND, ifaceName);
+ return;
+ }
+
+ if (!VplsCommandUtils.ifaceAlreadyAssociated(ifaceName)) {
+ print(VplsCommandUtils.IFACE_NOT_ASSOCIATED,
+ ifaceName, VplsCommandUtils.vplsNameFromIfaceName(ifaceName));
+ return;
+ }
+
+ vplsConfigService.removeIface(ifaceName);
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsListCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsListCommand.java
index bfbb054..aca247c 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsListCommand.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsListCommand.java
@@ -23,15 +23,15 @@
/**
* CLI to list VPLSs.
*/
-@Command(scope = "onos", name = "vpls-list", description = "Lists the existing VPLSs")
+@Command(scope = "onos", name = "vpls-list", description = "List the VPLSs configured")
public class VplsListCommand extends AbstractShellCommand {
private VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
@Override
protected void execute() {
- vplsConfigService.getAllVpls().forEach(vpls -> {
- print("%s", vpls);
+ vplsConfigService.vplsNames().forEach(vpls -> {
+ print(VplsCommandUtils.VPLS_NAME, vpls);
});
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsSetEncapCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsSetEncapCommand.java
new file mode 100644
index 0000000..ba46ea7
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsSetEncapCommand.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.vpls.config.VplsConfigurationService;
+
+/**
+ * CLI to set encapsulation for a VPLS.
+ */
+@Command(scope = "onos", name = "vpls-set-encap",
+ description = "Sets the encapsulation type for a given VPLS. None means" +
+ "no encapsulation has been set")
+public class VplsSetEncapCommand extends AbstractShellCommand {
+
+ private static final String VPLS_NOT_FOUND = "VPLS %s not found.";
+ private VplsConfigurationService vplsConfigService =
+ get(VplsConfigurationService.class);
+
+ @Argument(index = 0, name = "vplsName", description = "Name of the VPLS",
+ required = true, multiValued = false)
+ private String vplsName = null;
+
+ @Argument(index = 1, name = "encapsulation", description = "The encapsulation" +
+ "type. For example, VLAN or MPLS. None for no encapsulation",
+ required = true, multiValued = false)
+ String encap = null;
+
+ @Override
+ protected void execute() {
+ if (!VplsCommandUtils.vplsExists(vplsName)) {
+ print(VplsCommandUtils.VPLS_NOT_FOUND, vplsName);
+ return;
+ }
+
+ vplsConfigService.setEncap(vplsName, encap);
+ }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsShowCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsShowCommand.java
index 550d122..9dbeed6 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsShowCommand.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsShowCommand.java
@@ -16,14 +16,13 @@
package org.onosproject.vpls.cli;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.EncapsulationType;
import org.onosproject.vpls.config.VplsConfigurationService;
+import java.util.Map;
import java.util.Set;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -35,40 +34,36 @@
description = "Shows the details of an existing VPLS")
public class VplsShowCommand extends AbstractShellCommand {
- private static final String NAME_FORMAT = "%10s: interface=%s";
- private static final String NETWORK_NOT_FOUND =
- "VPLS with name \'%s\' not found";
private VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
- @Argument(index = 0, name = "NETWORK_NAME", description = "Name of the VPLS",
+ @Argument(index = 0, name = "vplsName", description = "Name of the VPLS",
required = false, multiValued = false)
private String vplsName = null;
@Override
protected void execute() {
- Set<String> vplsNames = vplsConfigService.getAllVpls();
- SetMultimap<String, Interface> vplsNetowrks = vplsConfigService.getVplsNetworks();
- Set<String> ifaceNames = Sets.newHashSet();
-
+ Set<String> vplsNames = vplsConfigService.vplsNames();
+ Map<String, EncapsulationType> encapByVplsName =
+ vplsConfigService.encapByVplsName();
if (!isNullOrEmpty(vplsName)) {
-
- if (vplsNames.contains(vplsName)) {
- vplsNetowrks.get(vplsName).stream()
- .map(Interface::name)
- .forEach(ifaceNames::add);
- print(NAME_FORMAT, vplsName, ifaceNames);
+ // A VPLS name is provided. Check first if the VPLS exists
+ if (VplsCommandUtils.vplsExists(vplsName)) {
+ print(VplsCommandUtils.VPLS_DISPLAY,
+ vplsName,
+ VplsCommandUtils.ifacesFromVplsName(vplsName).toString(),
+ encapByVplsName.get(vplsName).toString());
} else {
- print(NETWORK_NOT_FOUND, vplsName);
+ print(VplsCommandUtils.VPLS_NOT_FOUND, vplsName);
}
} else {
+ // No VPLS names are provided. Display all VPLSs configured
vplsNames.forEach(vplsName -> {
- ifaceNames.clear();
- vplsNetowrks.get(vplsName).stream()
- .map(Interface::name)
- .forEach(ifaceNames::add);
- print(NAME_FORMAT, vplsName, ifaceNames);
+ print(VplsCommandUtils.VPLS_DISPLAY,
+ vplsName,
+ VplsCommandUtils.ifacesFromVplsName(vplsName).toString(),
+ encapByVplsName.get(vplsName).toString());
});
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCmdCompleter.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCommandCompleter.java
similarity index 88%
rename from apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCmdCompleter.java
rename to apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCommandCompleter.java
index 9534635..a1cdfbb 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCmdCompleter.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCommandCompleter.java
@@ -26,12 +26,12 @@
/**
* Completer for "vpls-add-inf" command.
*/
-public class VplsAddIfaceCmdCompleter extends AbstractChoicesCompleter {
+public class VplsAddIfaceCommandCompleter extends AbstractChoicesCompleter {
@Override
protected List<String> choices() {
VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
- return Lists.newArrayList(vplsConfigService.getAllVpls());
+ return Lists.newArrayList(vplsConfigService.vplsNames());
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsDelCommandCompleter.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsDelCommandCompleter.java
index 9c6c061..d360b2a 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsDelCommandCompleter.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsDelCommandCompleter.java
@@ -33,6 +33,6 @@
protected List<String> choices() {
VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
- return Lists.newArrayList(vplsConfigService.getAllVpls());
+ return Lists.newArrayList(vplsConfigService.vplsNames());
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsDelIfaceCommandCompleter.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsDelIfaceCommandCompleter.java
index 81a1583..794ccfc 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsDelIfaceCommandCompleter.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsDelIfaceCommandCompleter.java
@@ -35,7 +35,7 @@
protected List<String> choices() {
VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
- Set<Interface> ifaces = vplsConfigService.getAllInterfaces();
+ Set<Interface> ifaces = vplsConfigService.allIfaces();
return ifaces.stream().map(Interface::name).collect(Collectors.toList());
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCmdCompleter.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsSetEncapCommandCompleter.java
similarity index 85%
copy from apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCmdCompleter.java
copy to apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsSetEncapCommandCompleter.java
index 9534635..409d2a7 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsAddIfaceCmdCompleter.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsSetEncapCommandCompleter.java
@@ -21,17 +21,18 @@
import org.onosproject.vpls.config.VplsConfigurationService;
import java.util.List;
+
import static org.onosproject.cli.AbstractShellCommand.get;
/**
- * Completer for "vpls-add-inf" command.
+ * Completer for "vpls-set-encap" command.
*/
-public class VplsAddIfaceCmdCompleter extends AbstractChoicesCompleter {
+public class VplsSetEncapCommandCompleter extends AbstractChoicesCompleter {
@Override
protected List<String> choices() {
VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
- return Lists.newArrayList(vplsConfigService.getAllVpls());
+ return Lists.newArrayList(vplsConfigService.vplsNames());
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsShowCommandCompleter.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsShowCommandCompleter.java
index 75ce663..0f572ea 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsShowCommandCompleter.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsShowCommandCompleter.java
@@ -33,6 +33,6 @@
protected List<String> choices() {
VplsConfigurationService vplsConfigService =
get(VplsConfigurationService.class);
- return Lists.newArrayList(vplsConfigService.getAllVpls());
+ return Lists.newArrayList(vplsConfigService.vplsNames());
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsAppConfig.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsAppConfig.java
new file mode 100644
index 0000000..398962e
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsAppConfig.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Sets;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.config.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+/**
+ * Represents the VPLS application configuration.
+ */
+public class VplsAppConfig extends Config<ApplicationId> {
+ private static final String VPLS = "vplsList";
+ private static final String NAME = "name";
+ private static final String INTERFACE = "interfaces";
+ private static final String ENCAPSULATION = "encapsulation";
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ /**
+ * Returns a set of configured VPLSs.
+ *
+ * @return set of VPLSs
+ */
+ public Set<VplsConfig> vplss() {
+ Set<VplsConfig> vplss = Sets.newHashSet();
+
+ JsonNode vplsNode = object.get(VPLS);
+
+ if (vplsNode == null) {
+ return vplss;
+ }
+
+ vplsNode.forEach(jsonNode -> {
+ String name = jsonNode.get(NAME).asText();
+
+ Set<String> ifaces = Sets.newHashSet();
+ jsonNode.path(INTERFACE).forEach(ifacesNode ->
+ ifaces.add(ifacesNode.asText())
+ );
+
+ String encap = null;
+ if (jsonNode.hasNonNull(ENCAPSULATION)) {
+ encap = jsonNode.get(ENCAPSULATION).asText();
+ }
+ vplss.add(new VplsConfig(name,
+ ifaces,
+ EncapsulationType.enumFromString(encap)));
+ });
+
+ return vplss;
+ }
+
+ /**
+ * Returns the VPLS configuration given a VPLS name.
+ *
+ * @param name the name of the VPLS
+ * @return the VPLS configuration if it exists; null otherwise
+ */
+ public VplsConfig getVplsWithName(String name) {
+ return vplss().stream()
+ .filter(vpls -> vpls.name().equals(name))
+ .findFirst()
+ .orElse(null);
+ }
+
+ /**
+ * Adds a VPLS to the configuration.
+ *
+ * @param vpls the name of the VPLS
+ */
+ public void addVpls(VplsConfig vpls) {
+ ObjectNode vplsNode = JsonNodeFactory.instance.objectNode();
+
+ vplsNode.put(NAME, vpls.name());
+
+ ArrayNode ifacesNode = vplsNode.putArray(INTERFACE);
+ vpls.ifaces().forEach(ifacesNode::add);
+
+ vplsNode.put(ENCAPSULATION, vpls.encap().toString());
+
+ ArrayNode vplsArray = vplss().isEmpty() ?
+ initVplsConfiguration() : (ArrayNode) object.get(VPLS);
+ vplsArray.add(vplsNode);
+ }
+
+ /**
+ * Removes a VPLS from the configuration.
+ *
+ * @param vplsName the vplsName of the VPLS to be removed
+ */
+ public void removeVpls(String vplsName) {
+ ArrayNode configuredVpls = (ArrayNode) object.get(VPLS);
+
+ for (int i = 0; i < configuredVpls.size(); i++) {
+ if (configuredVpls.get(i).hasNonNull(NAME) &&
+ configuredVpls.get(i).get(NAME).asText().equals(vplsName)) {
+ configuredVpls.remove(i);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Finds a VPLS with a given network interface.
+ *
+ * @param iface the network interface
+ * @return the VPLS if found; null otherwise
+ */
+ public VplsConfig vplsFromIface(String iface) {
+ for (VplsConfig vpls : vplss()) {
+ if (vpls.isAttached(iface)) {
+ return vpls;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Adds a network interface to a VPLS.
+ *
+ * @param vplsName the vplsName of the VPLS
+ * @param iface the network interface to be added
+ */
+ public void addIface(String vplsName, String iface) {
+ JsonNode vplsNodes = object.get(VPLS);
+ vplsNodes.forEach(vplsNode -> {
+ if (hasNamedNode(vplsNode, vplsName)) {
+ ArrayNode ifacesNode = (ArrayNode) vplsNode.get(INTERFACE);
+ for (int i = 0; i < ifacesNode.size(); i++) {
+ if (ifacesNode.get(i).asText().equals(iface)) {
+ return; // Interface already exists.
+ }
+ }
+ ifacesNode.add(iface);
+ }
+ });
+ }
+
+ /**
+ * Removes a network interface from a VPLS.
+ *
+ * @param name the name of the VPLS
+ * @param iface the network interface to be removed
+ */
+ public void removeIface(VplsConfig name, String iface) {
+ JsonNode vplsNodes = object.get(VPLS);
+ vplsNodes.forEach(vplsNode -> {
+ if (hasNamedNode(vplsNode, name.name())) {
+ ArrayNode ifacesNode = (ArrayNode) vplsNode.get(INTERFACE);
+ for (int i = 0; i < ifacesNode.size(); i++) {
+ if (ifacesNode.get(i).asText().equals(iface)) {
+ ifacesNode.remove(i);
+ return;
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Activate, deactivates, sets the encapsulation type for a given VPLS.
+ *
+ * @param vplsName the vplsName of the VPLS
+ * @param encap the encapsulation type, if set
+ */
+ public void setEncap(String vplsName, EncapsulationType encap) {
+ JsonNode vplsNodes = object.get(VPLS);
+ vplsNodes.forEach(vplsNode -> {
+ if (hasNamedNode(vplsNode, vplsName)) {
+ ((ObjectNode) vplsNode).put(ENCAPSULATION, encap.toString());
+ }
+ });
+ }
+
+ /**
+ * States if a JSON node has a "name" attribute and if the value is equal to
+ * the name given.
+ *
+ * @param jsonNode the JSON node
+ * @param name the node name
+ * @return true if the JSON node has a "name" attribute with value equal to
+ * the name given; false otherwise
+ */
+ private boolean hasNamedNode(JsonNode jsonNode, String name) {
+ return jsonNode.hasNonNull(NAME) &&
+ jsonNode.get(NAME).asText().equals(name);
+ }
+
+ /**
+ * Creates an empty VPLS configuration.
+ *
+ * @return empty ArrayNode to store the VPLS configuration
+ */
+ private ArrayNode initVplsConfiguration() {
+ return object.putArray(VPLS);
+ }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfig.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfig.java
index f8323ef..94e96ab 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfig.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfig.java
@@ -15,180 +15,88 @@
*/
package org.onosproject.vpls.config;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Sets;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.config.Config;
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.EncapsulationType;
+import java.util.Objects;
import java.util.Set;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
- * Configuration object for VPLS config.
+ * Configuration of a VPLS.
*/
-public class VplsConfig extends Config<ApplicationId> {
- private static final String VPLS = "vplsNetworks";
- private static final String NAME = "name";
- private static final String INTERFACE = "interfaces";
+public class VplsConfig {
+ private final String name;
+ private final Set<String> ifaces;
+ private final EncapsulationType encap;
/**
- * Returns a set of configured VPLSs.
- *
- * @return set of VPLSs
- */
- public Set<VplsNetworkConfig> vplsNetworks() {
- Set<VplsNetworkConfig> vpls = Sets.newHashSet();
-
- JsonNode vplsNode = object.get(VPLS);
-
- if (vplsNode == null) {
- return vpls;
- }
-
- vplsNode.forEach(jsonNode -> {
- Set<String> ifaces = Sets.newHashSet();
- jsonNode.path(INTERFACE).forEach(ifacesNode ->
- ifaces.add(ifacesNode.asText())
- );
-
- String name = jsonNode.get(NAME).asText();
-
- vpls.add(new VplsNetworkConfig(name, ifaces));
- });
-
- return vpls;
- }
-
- /**
- * Returns the VPLS configuration given a VPLS name.
+ * Creates a new VPLS configuration.
*
* @param name the VPLS name
- * @return the VPLS configuration if it exists; null otherwise
+ * @param ifaces the interfaces associated with the VPLS
+ * @param encap the encapsulation type if set
*/
- public VplsNetworkConfig getVplsWithName(String name) {
- for (VplsNetworkConfig vpls : vplsNetworks()) {
- if (vpls.name().equals(name)) {
- return vpls;
- }
+ public VplsConfig(String name, Set<String> ifaces, EncapsulationType encap) {
+ this.name = checkNotNull(name);
+ this.ifaces = checkNotNull(ImmutableSet.copyOf(ifaces));
+ this.encap = checkNotNull(encap);
+ }
+
+ /**
+ * The name of the VPLS.
+ *
+ * @return the name of the VPLS
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * The name of the interfaces associated with the VPLS.
+ *
+ * @return a set of interface names associated with the VPLS
+ */
+ public Set<String> ifaces() {
+ return ImmutableSet.copyOf(ifaces);
+ }
+
+ /**
+ * The encapsulation type.
+ *
+ * @return the encapsulation type, if active; null otherwise
+ */
+ public EncapsulationType encap() {
+ return encap;
+ }
+
+ /**
+ * States if a given interface is part of a VPLS.
+ *
+ * @param iface the interface attached to a VPLS
+ * @return true if the interface is associated to the VPLS; false otherwise
+ */
+ public boolean isAttached(String iface) {
+ return ifaces.stream().anyMatch(iface::equals);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
}
- return null;
- }
-
- /**
- * Adds a VPLS to the configuration.
- *
- * @param name the name of the VPLS to be added
- */
- public void addVpls(VplsNetworkConfig name) {
- ObjectNode vplsNode = JsonNodeFactory.instance.objectNode();
-
- vplsNode.put(NAME, name.name());
-
- ArrayNode ifacesNode = vplsNode.putArray(INTERFACE);
- name.ifaces().forEach(ifacesNode::add);
-
- ArrayNode vplsArray = vplsNetworks().isEmpty() ?
- initVplsConfiguration() : (ArrayNode) object.get(VPLS);
- vplsArray.add(vplsNode);
- }
-
- /**
- * Removes a VPLS from the configuration.
- *
- * @param name the name of the VPLS to be removed
- */
- public void removeVpls(String name) {
- ArrayNode vplsArray = (ArrayNode) object.get(VPLS);
-
- for (int i = 0; i < vplsArray.size(); i++) {
- if (vplsArray.get(i).hasNonNull(NAME) &&
- vplsArray.get(i).get(NAME).asText().equals(name)) {
- vplsArray.remove(i);
- return;
- }
+ if (obj instanceof VplsConfig) {
+ VplsConfig that = (VplsConfig) obj;
+ return Objects.equals(name, that.name) &&
+ Objects.equals(ifaces, that.ifaces) &&
+ Objects.equals(encap, that.encap);
}
+ return false;
}
- /**
- * Finds a VPLS with a given network interface.
- *
- * @param iface the network interface
- * @return the VPLS if found; null otherwise
- */
- public VplsNetworkConfig getVplsFromInterface(String iface) {
- for (VplsNetworkConfig vpls : vplsNetworks()) {
- if (vpls.isAttached(iface)) {
- return vpls;
- }
- }
- return null;
- }
-
- /**
- * Adds a network interface to a VPLS.
- *
- * @param name the name of the VPLS
- * @param iface the network interface to be added
- */
- public void addInterfaceToVpls(String name, String iface) {
- JsonNode vplsNode = object.get(VPLS);
- vplsNode.forEach(jsonNode -> {
-
- if (hasNamedNode(jsonNode, name)) {
- ArrayNode ifacesNode = (ArrayNode) jsonNode.get(INTERFACE);
- for (int i = 0; i < ifacesNode.size(); i++) {
- if (ifacesNode.get(i).asText().equals(iface)) {
- return; // Interface already exists.
- }
- }
- ifacesNode.add(iface);
- }
- });
- }
-
- /**
- * Removes a network interface from a VPLS.
- *
- * @param name the name of the VPLS
- * @param iface the network interface to be removed
- */
- public void removeInterfaceFromVpls(VplsNetworkConfig name, String iface) {
- JsonNode vplsNode = object.get(VPLS);
- vplsNode.forEach(jsonNode -> {
- if (hasNamedNode(jsonNode, name.name())) {
- ArrayNode ifacesNode = (ArrayNode) jsonNode.get(INTERFACE);
- for (int i = 0; i < ifacesNode.size(); i++) {
- if (ifacesNode.get(i).asText().equals(iface)) {
- ifacesNode.remove(i);
- return;
- }
- }
- }
- });
- }
-
- /**
- * States if a JSON node has a "name" attribute and if the value is equal to
- * the name given.
- *
- * @param jsonNode the JSON node
- * @param name the node name
- * @return true if the JSON node has a "name" attribute with value equal to
- * the name given; false otherwise
- */
- private boolean hasNamedNode(JsonNode jsonNode, String name) {
- return jsonNode.hasNonNull(NAME) &&
- jsonNode.get(NAME).asText().equals(name);
- }
-
- /**
- * Creates an empty VPLS configuration.
- *
- * @return empty ArrayNode to store the VPLS configuration
- */
- private ArrayNode initVplsConfiguration() {
- return object.putArray(VPLS);
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, ifaces, encap);
}
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigurationService.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigurationService.java
index 16cd4c4..6579378 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigurationService.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigurationService.java
@@ -19,102 +19,129 @@
import org.onlab.packet.VlanId;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import java.util.Map;
import java.util.Set;
/**
* Provides information about the VPLS configuration.
*/
public interface VplsConfigurationService {
- Class<VplsConfig> CONFIG_CLASS = VplsConfig.class;
+ Class<VplsAppConfig> CONFIG_CLASS = VplsAppConfig.class;
/**
* Adds a VPLS to the configuration.
*
- * @param name the name of the VPLS
+ * @param vplsName the name of the VPLS
* @param ifaces the interfaces associated with the VPLS
+ * @param encap the encapsulation type
*/
- void addVpls(String name, Set<String> ifaces);
+ void addVpls(String vplsName, Set<String> ifaces, String encap);
/**
* Removes a VPLS from the configuration.
*
- * @param name the name of the VPLS to be removed
+ * @param vplsName the name of the VPLS to be removed
*/
- void removeVpls(String name);
+ void removeVpls(String vplsName);
/**
* Adds a network interface to a VPLS.
*
- * @param name the name of the VPLS
+ * @param vplsName the name of the VPLS
* @param iface the network interface to be added to the VPLS
*/
- void addInterfaceToVpls(String name, String iface);
+ void addIface(String vplsName, String iface);
+
+ /**
+ * Sets an encapsulation parameter for a VPLS.
+ *
+ * @param vplsName the name of the VPLS
+ * @param encap the encapsulation used (i.e. MPLS or VLAN) or
+ */
+ void setEncap(String vplsName, String encap);
+
+ /**
+ * Returns the encapsulation type in use for a given VPLS.
+ *
+ * @param vplsName the name of the VPLS
+ * @return the encapsulation type in use, if any
+ */
+ EncapsulationType encap(String vplsName);
/**
* Removes a network interface from a VPLS.
*
* @param iface the network interface to be removed from the VPLS
*/
- void removeInterfaceFromVpls(String iface);
+ void removeIface(String iface);
/**
* Cleans up the VPLS configuration. Removes all VPLSs.
*/
- void cleanVpls();
+ void cleanVplsConfig();
/**
* Retrieves the VPLS names modified from CLI.
*
- * @return a set of VPLS names modified from CLI
+ * @return the VPLS names modified from CLI
*/
- Set<String> getVplsAffectedByApi();
- // TODO Removes this function after intent framework fix race condition
+ Set<String> vplsAffectedByApi();
+ // TODO Remove this function after the intent framework race condition has been fixed
/**
* Retrieves the interfaces from the VPLS configuration.
*
* @return a set of interfaces contained in the VPLS configuration
*/
- Set<Interface> getAllInterfaces();
+ Set<Interface> allIfaces();
/**
* Retrieves the interfaces belonging to the VPLS.
*
- * @param name the name of the VPLS
+ * @param vplsName the name of the VPLS
* @return a set of interfaces belonging to the VPLS
*/
- Set<Interface> getVplsInterfaces(String name);
+ Set<Interface> ifaces(String vplsName);
/**
* Retrieves all VPLS names.
*
* @return a set of VPLS names
*/
- Set<String> getAllVpls();
+ Set<String> vplsNames();
/**
* Retrieves all VPLS names from the old config.
*
* @return a set of VPLS names
*/
- Set<String> getOldVpls();
+ Set<String> vplsNamesOld();
// TODO Removes this function after intent framework fix race condition
/**
- * Retrieves the VPLS names and associated interfaces from the configuration.
+ * Returns the VPLS names and associated interfaces from the configuration.
*
- * @return a map VPLS names and associated interfaces
+ * @return a map of VPLS names and associated interfaces
*/
- SetMultimap<String, Interface> getVplsNetworks();
+ SetMultimap<String, Interface> ifacesByVplsName();
/**
- * Retrieves a VPLS network given a VLAN Id and a connect point.
+ * Returns the list of interfaces grouped by VPLS name, given a VLAN Id and
+ * a connect point.
*
* @param vlan the VLAN Id
* @param connectPoint the connect point
- * @return a map VPLS names and associated interfaces; null otherwise
+ * @return a map of VPLS names and associated interfaces; null otherwise
*/
- SetMultimap<String, Interface> getVplsNetwork(VlanId vlan,
- ConnectPoint connectPoint);
+ SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
+ ConnectPoint connectPoint);
+
+ /**
+ * Returns the VPLS names and associated encapsulation type.
+ *
+ * @return a map of VPLS names and associated encapsulation type
+ */
+ Map<String, EncapsulationType> encapByVplsName();
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsNetworkConfig.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsNetworkConfig.java
deleted file mode 100644
index b3c721b..0000000
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsNetworkConfig.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.vpls.config;
-
-import com.google.common.collect.ImmutableSet;
-
-import java.util.Objects;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Configuration of a VPLS Network.
- */
-public class VplsNetworkConfig {
- private final String name;
- private final Set<String> ifaces;
-
- /**
- * Creates a new VPLS configuration.
- *
- * @param name the VPLS name
- * @param ifaces the interfaces associated with the VPLS
- */
- public VplsNetworkConfig(String name, Set<String> ifaces) {
- this.name = checkNotNull(name);
- this.ifaces = checkNotNull(ImmutableSet.copyOf(ifaces));
- }
-
- /**
- * Returns the name of the VPLS.
- *
- * @return the name of the VPLS
- */
- public String name() {
- return name;
- }
-
- /**
- * Returns the name of interfaces associated with the VPLS.
- *
- * @return a set of interface names associated with the VPLS
- */
- public Set<String> ifaces() {
- return ImmutableSet.copyOf(ifaces);
- }
-
- /**
- * States if a given interface is part of a VPLS.
- *
- * @param iface the interface attached to a VPLS
- * @return true if the interface is associated to the VPLS; false otherwise
- */
- public boolean isAttached(String iface) {
- return ifaces.stream().anyMatch(i -> i.equals(iface));
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof VplsNetworkConfig) {
- final VplsNetworkConfig that = (VplsNetworkConfig) obj;
- return Objects.equals(this.name, that.name) &&
- Objects.equals(this.ifaces, that.ifaces);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(name, ifaces);
- }
-}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigurationImpl.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigurationImpl.java
index e977170..0c2f09b 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigurationImpl.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigurationImpl.java
@@ -16,8 +16,10 @@
package org.onosproject.vpls.config.impl;
import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -31,19 +33,22 @@
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.vpls.config.VplsAppConfig;
import org.onosproject.vpls.config.VplsConfig;
-import org.onosproject.vpls.config.VplsNetworkConfig;
import org.onosproject.vpls.config.VplsConfigurationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
/**
@@ -80,21 +85,22 @@
private final Set<String> vplsAffectedByApi = new HashSet<>();
- private VplsConfig vplsConfig = new VplsConfig();
+ private VplsAppConfig vplsAppConfig = new VplsAppConfig();
private SetMultimap<String, String> ifacesOfVpls = HashMultimap.create();
private SetMultimap<String, String> oldIfacesOfVpls = HashMultimap.create();
- private SetMultimap<String, Interface> vplsNetworks = HashMultimap.create();
+ private SetMultimap<String, Interface> vplsIfaces = HashMultimap.create();
+ private Map<String, EncapsulationType> vplsEncaps = Maps.newHashMap();
private final InternalNetworkConfigListener configListener =
new InternalNetworkConfigListener();
- private ConfigFactory<ApplicationId, VplsConfig> vplsConfigFactory =
- new ConfigFactory<ApplicationId, VplsConfig>(
- SubjectFactories.APP_SUBJECT_FACTORY, VplsConfig.class, VPLS) {
+ private ConfigFactory<ApplicationId, VplsAppConfig> vplsConfigFactory =
+ new ConfigFactory<ApplicationId, VplsAppConfig>(
+ SubjectFactories.APP_SUBJECT_FACTORY, VplsAppConfig.class, VPLS) {
@Override
- public VplsConfig createConfig() {
- return new VplsConfig();
+ public VplsAppConfig createConfig() {
+ return new VplsAppConfig();
}
};
@@ -115,23 +121,164 @@
log.info("Stopped");
}
+ @Override
+ public void addVpls(String vplsName, Set<String> ifaces, String encap) {
+ EncapsulationType encapType = EncapsulationType.enumFromString(encap);
+
+ if (ifacesOfVpls.containsKey(vplsName)) {
+ if (ifaces.isEmpty()) {
+ return;
+ }
+ ifaces.forEach(iface -> vplsAppConfig.addIface(vplsName, iface));
+ vplsAppConfig.setEncap(vplsName, encapType);
+ } else {
+ vplsAppConfig.addVpls(new VplsConfig(vplsName, ifaces, encapType));
+ }
+
+ vplsAffectedByApi.add(vplsName);
+ applyConfig(vplsAppConfig);
+ }
+
+ @Override
+ public void removeVpls(String vplsName) {
+ if (ifacesOfVpls.containsKey(vplsName)) {
+ vplsAppConfig.removeVpls(vplsName);
+ vplsAffectedByApi.add(vplsName);
+ applyConfig(vplsAppConfig);
+ }
+ }
+
+ @Override
+ public void addIface(String vplsName, String iface) {
+ if (ifacesOfVpls.containsKey(vplsName)) {
+ vplsAppConfig.addIface(vplsName, iface);
+ vplsAffectedByApi.add(vplsName);
+ applyConfig(vplsAppConfig);
+ }
+ }
+
+ @Override
+ public void setEncap(String vplsName, String encap) {
+ EncapsulationType encapType = EncapsulationType.enumFromString(encap);
+
+ if (ifacesOfVpls.containsKey(vplsName)) {
+ vplsAppConfig.setEncap(vplsName, encapType);
+ vplsAffectedByApi.add(vplsName);
+ applyConfig(vplsAppConfig);
+ }
+ }
+
+ @Override
+ public void removeIface(String iface) {
+ if (ifacesOfVpls.containsValue(iface)) {
+ VplsConfig vpls = vplsAppConfig.vplsFromIface(iface);
+ vplsAppConfig.removeIface(vpls, iface);
+ vplsAffectedByApi.add(vpls.name());
+ applyConfig(vplsAppConfig);
+ }
+ }
+
+ @Override
+ public void cleanVplsConfig() {
+ ifacesOfVpls.entries().forEach(e -> {
+ vplsAppConfig.removeVpls(e.getKey());
+ vplsAffectedByApi.add(e.getKey());
+ });
+ applyConfig(vplsAppConfig);
+ }
+
+ @Override
+ public EncapsulationType encap(String vplsName) {
+ EncapsulationType encap = null;
+ if (vplsEncaps.containsKey(vplsName)) {
+ encap = vplsEncaps.get(vplsName);
+ }
+
+ return encap;
+ }
+
+ @Override
+ public Set<String> vplsAffectedByApi() {
+ Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectedByApi);
+ vplsAffectedByApi.clear();
+
+ return vplsNames;
+ }
+
+ @Override
+ public Set<Interface> allIfaces() {
+ Set<Interface> allVplsInterfaces = new HashSet<>();
+ vplsIfaces.values().forEach(allVplsInterfaces::add);
+
+ return allVplsInterfaces;
+ }
+
+ @Override
+ public Set<Interface> ifaces(String vplsName) {
+ Set<Interface> vplsInterfaces = new HashSet<>();
+ vplsIfaces.get(vplsName).forEach(vplsInterfaces::add);
+
+ return vplsInterfaces;
+ }
+
+ @Override
+ public Set<String> vplsNames() {
+ return ifacesOfVpls.keySet();
+ }
+
+ @Override
+ public Set<String> vplsNamesOld() {
+ return oldIfacesOfVpls.keySet();
+ }
+
+ @Override
+ public SetMultimap<String, Interface> ifacesByVplsName() {
+ return ImmutableSetMultimap.copyOf(vplsIfaces);
+ }
+
+ @Override
+ public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
+ ConnectPoint connectPoint) {
+ String vplsName =
+ vplsIfaces.entries().stream()
+ .filter(e -> e.getValue().connectPoint().equals(connectPoint))
+ .filter(e -> e.getValue().vlan().equals(vlan))
+ .map(e -> e.getKey())
+ .findFirst()
+ .orElse(null);
+ SetMultimap<String, Interface> result = HashMultimap.create();
+ if (vplsName != null && vplsIfaces.containsKey(vplsName)) {
+ vplsIfaces.get(vplsName)
+ .forEach(intf -> result.put(vplsName, intf));
+ return result;
+ }
+ return null;
+ }
+
+ @Override
+ public Map<String, EncapsulationType> encapByVplsName() {
+ return ImmutableMap.copyOf(vplsEncaps);
+ }
+
/**
* Retrieves the VPLS configuration from network configuration.
*/
private void loadConfiguration() {
loadAppId();
- vplsConfig = configService.getConfig(vplsAppId, VplsConfig.class);
+ vplsAppConfig = configService.getConfig(vplsAppId, VplsAppConfig.class);
- if (vplsConfig == null) {
+ if (vplsAppConfig == null) {
log.warn(CONFIG_NULL);
- configService.addConfig(vplsAppId, VplsConfig.class);
+ configService.addConfig(vplsAppId, VplsAppConfig.class);
return;
}
oldIfacesOfVpls = ifacesOfVpls;
ifacesOfVpls = getConfigInterfaces();
- vplsNetworks = getConfigCPoints();
+ vplsIfaces = getConfigCPoints();
+ vplsEncaps = getConfigEncap();
+
log.debug(CONFIG_CHANGED, ifacesOfVpls);
}
@@ -148,21 +295,37 @@
/**
* Applies a given configuration to the VPLS application.
*/
- private void applyConfig(VplsConfig vplsConfig) {
+ private void applyConfig(VplsAppConfig vplsAppConfig) {
loadAppId();
- configService.applyConfig(vplsAppId, VplsConfig.class, vplsConfig.node());
+ configService.applyConfig(vplsAppId, VplsAppConfig.class, vplsAppConfig.node());
}
/**
- * Retrieves the VPLS names and associated interfaces names from the configuration.
+ * Retrieves the VPLS names and related encapsulation types from the
+ * configuration.
*
- * @return a map VPLS names and associated interface names
+ * @return a map of VPLS names and associated encapsulation types
+ */
+ private Map<String, EncapsulationType> getConfigEncap() {
+ Map<String, EncapsulationType> configEncap = new HashMap<>();
+
+ vplsAppConfig.vplss().forEach(vpls -> {
+ configEncap.put(vpls.name(), vpls.encap());
+ });
+
+ return configEncap;
+ }
+
+ /**
+ * Retrieves the VPLS names and related interfaces names from the configuration.
+ *
+ * @return a map of VPLS names and related interface names
*/
private SetMultimap<String, String> getConfigInterfaces() {
SetMultimap<String, String> confIntfByVpls =
HashMultimap.create();
- vplsConfig.vplsNetworks().forEach(vpls -> {
+ vplsAppConfig.vplss().forEach(vpls -> {
if (vpls.ifaces().isEmpty()) {
confIntfByVpls.put(vpls.name(), EMPTY);
} else {
@@ -174,9 +337,9 @@
}
/**
- * Retrieves the VPLS names and associated interfaces from the configuration.
+ * Retrieves the VPLS names and related interfaces from the configuration.
*
- * @return a map VPLS names and associated interfaces
+ * @return a map of VPLS names and related interfaces
*/
private SetMultimap<String, Interface> getConfigCPoints() {
log.debug(CHECK_CONFIG);
@@ -209,127 +372,10 @@
case CONFIG_REMOVED:
loadConfiguration();
break;
-
default:
break;
}
}
}
}
-
- @Override
- public void addVpls(String name, Set<String> ifaces) {
- VplsNetworkConfig vpls;
-
- if (ifacesOfVpls.containsKey(name)) {
- if (ifaces.isEmpty()) {
- return;
- }
-
- ifaces.forEach(iface ->
- vplsConfig.addInterfaceToVpls(name, iface));
- } else {
- vpls = new VplsNetworkConfig(name, ifaces);
- vplsConfig.addVpls(vpls);
- }
-
- vplsAffectedByApi.add(name);
- applyConfig(vplsConfig);
- }
-
- @Override
- public void removeVpls(String name) {
- if (ifacesOfVpls.containsKey(name)) {
- vplsConfig.removeVpls(name);
- vplsAffectedByApi.add(name);
- applyConfig(vplsConfig);
- }
- }
-
- @Override
- public void addInterfaceToVpls(String name, String iface) {
- if (ifacesOfVpls.containsKey(name)) {
- vplsConfig.addInterfaceToVpls(name, iface);
- vplsAffectedByApi.add(name);
- applyConfig(vplsConfig);
- }
- }
-
- @Override
- public void removeInterfaceFromVpls(String iface) {
- if (ifacesOfVpls.containsValue(iface)) {
- VplsNetworkConfig vpls = vplsConfig.getVplsFromInterface(iface);
- vplsConfig.removeInterfaceFromVpls(vpls, iface);
- vplsAffectedByApi.add(vpls.name());
- applyConfig(vplsConfig);
- }
- }
-
- @Override
- public void cleanVpls() {
- ifacesOfVpls.entries().forEach(e -> {
- vplsConfig.removeVpls(e.getKey());
- vplsAffectedByApi.add(e.getKey());
- });
- applyConfig(vplsConfig);
- }
-
- @Override
- public Set<String> getVplsAffectedByApi() {
- Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectedByApi);
-
- vplsAffectedByApi.clear();
-
- return vplsNames;
- }
-
- @Override
- public Set<Interface> getAllInterfaces() {
- Set<Interface> allInterfaces = new HashSet<>();
- vplsNetworks.values().forEach(allInterfaces::add);
-
- return allInterfaces;
- }
-
- @Override
- public Set<Interface> getVplsInterfaces(String name) {
- Set<Interface> vplsInterfaces = new HashSet<>();
- vplsNetworks.get(name).forEach(vplsInterfaces::add);
-
- return vplsInterfaces;
- }
-
- @Override
- public Set<String> getAllVpls() {
- return ifacesOfVpls.keySet();
- }
-
- @Override
- public Set<String> getOldVpls() {
- return oldIfacesOfVpls.keySet();
- }
-
- @Override
- public SetMultimap<String, Interface> getVplsNetworks() {
- return ImmutableSetMultimap.copyOf(vplsNetworks);
- }
-
- @Override
- public SetMultimap<String, Interface> getVplsNetwork(VlanId vlan,
- ConnectPoint connectPoint) {
- String vplsNetworkName =
- vplsNetworks.entries().stream()
- .filter(e -> e.getValue().connectPoint().equals(connectPoint))
- .filter(e -> e.getValue().vlan().equals(vlan))
- .map(e -> e.getKey())
- .findFirst()
- .orElse(null);
- SetMultimap<String, Interface> result = HashMultimap.create();
- if (vplsNetworkName != null && vplsNetworks.containsKey(vplsNetworkName)) {
- vplsNetworks.get(vplsNetworkName)
- .forEach(intf -> result.put(vplsNetworkName, intf));
- return result;
- }
- return null;
- }
}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
index 3229c7b..b5d6ec9 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
@@ -15,6 +15,6 @@
*/
/**
- * Configuration implementation to create L2 broadcast network using VLAN.
+ * Configuration service implementation for VPLS.
*/
package org.onosproject.vpls.config.impl;
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/package-info.java
index f080044..a0a94d2 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/package-info.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/package-info.java
@@ -17,4 +17,4 @@
/**
* Configuration to create L2 broadcast network using VLAN.
*/
-package org.onosproject.vpls.config;
+package org.onosproject.vpls.config;
\ No newline at end of file
diff --git a/apps/vpls/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/vpls/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 5815ffd..3aa3bd3 100644
--- a/apps/vpls/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/apps/vpls/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -45,6 +45,13 @@
<action class="org.onosproject.vpls.cli.VplsListCommand"/>
</command>
<command>
+ <action class="org.onosproject.vpls.cli.VplsSetEncapCommand"/>
+ <completers>
+ <ref component-id="VplsSetEncapCommandCompleter"/>
+ <null/>
+ </completers>
+ </command>
+ <command>
<action class="org.onosproject.vpls.cli.VplsShowCommand"/>
<completers>
<ref component-id="VplsShowCommandCompleter"/>
@@ -56,8 +63,9 @@
</command>
</command-bundle>
- <bean id="VplsAddIfaceCommandCompleter" class="org.onosproject.vpls.cli.completer.VplsAddIfaceCmdCompleter"/>
+ <bean id="VplsAddIfaceCommandCompleter" class="org.onosproject.vpls.cli.completer.VplsAddIfaceCommandCompleter"/>
<bean id="VplsDelCommandCompleter" class="org.onosproject.vpls.cli.completer.VplsDelCommandCompleter"/>
<bean id="VplsDelIfaceCommandCompleter" class="org.onosproject.vpls.cli.completer.VplsDelIfaceCommandCompleter"/>
+ <bean id="VplsSetEncapCommandCompleter" class="org.onosproject.vpls.cli.completer.VplsSetEncapCommandCompleter"/>
<bean id="VplsShowCommandCompleter" class="org.onosproject.vpls.cli.completer.VplsShowCommandCompleter"/>
-</blueprint>
+</blueprint>
\ No newline at end of file