This commit brings in BridgeDomain Configuration Service under the umbrella of SAL Network Configuration Services.
The idea of this SAL service is to provide a Protocol Plugin agnostic way of configuring Bridge Domains.
SAL NetworkConfiguration services are implemented as a pluggable bundle on its own to showcase the extensibility of SAL layer.
NetworkConfiguration bundle is subdivided into various Services under their own package structure.
Change-Id: I60e12e304bfa9e3200d1e42b3b516a9717a51407
Signed-off-by: Madhu Venugopal <vmadhu@cisco.com>
<!-- SAL Extension bundles -->
<module>../../sal/connection/api</module>
<module>../../sal/connection/implementation</module>
+ <module>../../sal/networkconfiguration/api</module>
+ <module>../../sal/networkconfiguration/implementation</module>
<!-- Web bundles -->
<module>../../web/root</module>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+ <modelVersion>4.0.0</modelVersion>\r
+ <parent>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>commons.opendaylight</artifactId>\r
+ <version>1.4.0-SNAPSHOT</version>\r
+ <relativePath>../../../commons/opendaylight</relativePath>\r
+ </parent>\r
+\r
+ <artifactId>sal.networkconfiguration</artifactId>\r
+ <version>0.0.1-SNAPSHOT</version>\r
+ <packaging>bundle</packaging>\r
+\r
+ <build>\r
+ <plugins>\r
+ <plugin>\r
+ <groupId>org.apache.felix</groupId>\r
+ <artifactId>maven-bundle-plugin</artifactId>\r
+ <version>2.3.6</version>\r
+ <extensions>true</extensions>\r
+ <configuration>\r
+ <instructions>\r
+ <Import-Package>\r
+ org.slf4j,\r
+ org.osgi.framework,\r
+ org.apache.felix.dm,\r
+ org.opendaylight.controller.sal.core,\r
+ org.opendaylight.controller.sal.utils\r
+ </Import-Package>\r
+ <Export-Package>\r
+ org.opendaylight.controller.sal.networkconfig.bridgedomain\r
+ </Export-Package>\r
+ </instructions>\r
+ <manifestLocation>${project.basedir}/META-INF</manifestLocation>\r
+ </configuration>\r
+ </plugin>\r
+ </plugins>\r
+ </build>\r
+ <dependencies>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>sal</artifactId>\r
+ <version>0.5.0-SNAPSHOT</version>\r
+ </dependency>\r
+ </dependencies>\r
+</project>\r
--- /dev/null
+package org.opendaylight.controller.sal.networkconfig.bridgedomain;
+
+/**
+ * Enum constant that is used as a key for the configuration parameters for BridgeDomains and Ports.
+ * The main intention of having a constant type is to avoid fragmentation and find common grounds for
+ * applications to rely on.
+ *
+ * This is set to expand based on various capabilities south-bound protocol might expose.
+ * Not all of them be supported by all the plugins. But this gives a consolidated view of
+ * all the supported feature configs and avoid config fragmentation.
+ */
+public enum ConfigConstants {
+ TYPE("type"),
+ VLAN("Vlan"),
+ VLAN_MODE("vlan_mode"),
+ TUNNEL_TYPE("Tunnel Type"),
+ SOURCE_IP("Source IP"),
+ DEST_IP("Destination IP"),
+ MACADDRESS("MAC Address"),
+ INTERFACE_IDENTIFIER("Interface Identifier"),
+ MGMT("Management"),
+ CUSTOM("Custom Configurations");
+
+ private ConfigConstants(String name) {
+ this.name = name;
+ }
+
+ private String name;
+
+ public String toString() {
+ return name;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.networkconfig.bridgedomain;
+
+public interface IBridgeDomainConfigService extends IPluginInBridgeDomainConfigService {
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.networkconfig.bridgedomain;
+
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.Status;
+
+/**
+ * @file IPluginInConfigurationService.java
+ *
+ */
+public interface IPluginInBridgeDomainConfigService {
+ /**
+ * Create a Bridge Domain
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @param params Map representation of config name (ConfigConstants) and Parameter value (represented as Object).
+ * @return Status.StatusCode.SUCCESS if bridge domain is created successfully. Failure Status otherwise.
+ * @note This method will return false if one or more of the supplied params is not supported by the
+ * protocol plugin that serves the Node.
+ */
+ public Status createBridgeDomain(Node node, String bridgeIdentifier, Map<ConfigConstants, Object> params) throws Throwable;
+
+ /**
+ * Delete a Bridge Domain
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @return Status.StatusCode.SUCCESS if bridge domain is deleted successfully. Failure Status otherwise.
+ */
+ public Status deleteBridgeDomain(Node node, String bridgeIdentifier);
+
+ /**
+ * Returns the configured Bridge Domains
+ *
+ * @param node Node serving this configuration service
+ * @return List of Bridge Domain Identifiers
+ */
+ public List<String> getBridgeDomains(Node node);
+
+ /**
+ * add Bridge Domain Configuration
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @param params Map representation of config Name (ConfigConstants) and config value(represented as Object).
+ * @return Status.StatusCode.SUCCESS if bridge domain configuration is added successfully. Failure Status otherwise.
+ * @note This method will return false if one or more of the supplied params is not supported by the
+ * protocol plugin that serves the Node.
+ */
+ public Status addBridgeDomainConfig(Node node, String bridgeIdentifier, Map<ConfigConstants, Object> params);
+
+ /**
+ * Delete Bridge Domain Configuration
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @param params Map representation of config name (ConfigConstants) and Parameter value (represented as Object).
+ * @return Status.StatusCode.SUCCESS if bridge domain configuration is deleted successfully. Failure Status otherwise.
+ * @note This method will return false if one or more of the supplied params is not supported by the
+ * protocol plugin that serves the Node.
+ */
+ public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier, Map<ConfigConstants, Object> params);
+
+ /**
+ * Returns Bridge Domain Configurations
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @return Map representation of config Name (ConfigConstants) and config value(represented as Object).
+ */
+
+ public Map<ConfigConstants, Object> getBridgeDomainConfigs(Node node, String bridgeIdentifier);
+
+ /**
+ * Returns a Node dedicated to a Bridge Domain (if available) that is created using createBridgeDomain.
+ * @param configNode Node serving this configuration service.
+ * @param bridgeIdentifier Name of the bridge domain that would map to a dedicated Node
+ * @return Node dedicated to a bridge domain that is created using createBridgeDomain.
+ * returns null if there is no such dedicated node is available or represented.
+ */
+ public Node getBridgeDomainNode(Node configNode, String bridgeIdentifier);
+
+ /**
+ * Add a port to a bridge domain
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @param portIdentifier String representation of a Port.
+ * @param params Map representation of config name (ConfigConstants) and Parameter value (represented as Object).
+ * @return Status.StatusCode.SUCCESS if a port is added successfully. Failure Status otherwise.
+ * @note This method will return false if one or more of the supplied params is not supported by the
+ * protocol plugin that serves the Node.
+ */
+ public Status addPort(Node node, String bridgeIdentifier, String portIdentifier,
+ Map<ConfigConstants, Object> params);
+
+ /**
+ * Delete a Port from a bridge domain
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @param portIdentifier String representation of a Port.
+ * @return Status.StatusCode.SUCCESS if a port is added successfully. Failure Status otherwise.
+ */
+ public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier);
+
+ /**
+ * add Port Configuration
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @param portIdentifier String representation of a Port.
+ * @param params Map representation of config name (ConfigConstants) and Parameter value (represented as Object).
+ * @return Status.StatusCode.SUCCESS if a port configuration is added successfully. Failure Status otherwise.
+ * @note This method will return false if one or more of the supplied params is not supported by the
+ * protocol plugin that serves the Node.
+ */
+ public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier,
+ Map<ConfigConstants, Object> params);
+
+ /**
+ * Delete Port Configuration
+ *
+ * @param node Node serving this configuration service
+ * @param portIdentifier String representation of a Port.
+ * @param config Map representation of ConfigName and Configuration Value in Strings.
+ * @return Status.StatusCode.SUCCESS if a port configuration is removed successfully. Failure Status otherwise.
+ * @note This method will return false if one or more of the supplied params is not supported by the
+ * protocol plugin that serves the Node.
+ */
+ public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier, Map<ConfigConstants, Object> params);
+
+ /**
+ * Returns Port Configurations
+ *
+ * @param node Node serving this configuration service
+ * @param bridgeIdentifier String representation of a Bridge Domain
+ * @param portIdentifier String representation of a Port.
+ * @return Map representation of Configuration Name (ConfigConstants) and Configuration value (represented as Object).
+ */
+ public Map<ConfigConstants, Object> getPortConfigs(Node node, String bridgeIdentifier, String portIdentifier);
+
+
+ /**
+ * Returns a NodeConnector mapped to a Port (if available) that is created using addPort.
+ * @param configNode Node serving this configuration service.
+ * @param bridgeIdentifier Name of the bridge domain that would map to a dedicated Node
+ * @param portIdentifier String representation of a Port.
+ * @return NodeConnector that is mapped to a port created using addPort.
+ * returns null if there is no such nodeConnector is available or mapped.
+ */
+ public NodeConnector getNodeConnector(Node configNode, String bridgeIdentifier, String portIdentifier);
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+ <modelVersion>4.0.0</modelVersion>\r
+ <parent>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>commons.opendaylight</artifactId>\r
+ <version>1.4.0-SNAPSHOT</version>\r
+ <relativePath>../../../commons/opendaylight</relativePath>\r
+ </parent>\r
+\r
+ <artifactId>sal.networkconfiguration.implementation</artifactId>\r
+ <version>0.0.1-SNAPSHOT</version>\r
+ <packaging>bundle</packaging>\r
+\r
+ <build>\r
+ <plugins>\r
+ <plugin>\r
+ <groupId>org.apache.felix</groupId>\r
+ <artifactId>maven-bundle-plugin</artifactId>\r
+ <version>2.3.6</version>\r
+ <extensions>true</extensions>\r
+ <configuration>\r
+ <instructions>\r
+ <Import-Package>\r
+ org.slf4j,\r
+ org.opendaylight.controller.sal.core,\r
+ org.opendaylight.controller.sal.utils,\r
+ org.opendaylight.controller.sal.networkconfig.bridgedomain,\r
+ org.apache.felix.dm,\r
+ org.osgi.framework\r
+ </Import-Package>\r
+ <Export-Package>\r
+ </Export-Package>\r
+ <Bundle-Activator>\r
+ org.opendaylight.controller.sal.networkconfig.internal.Activator\r
+ </Bundle-Activator>\r
+ </instructions>\r
+ <manifestLocation>${project.basedir}/META-INF</manifestLocation>\r
+ </configuration>\r
+ </plugin>\r
+ </plugins>\r
+ </build>\r
+ <dependencies>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>sal</artifactId>\r
+ <version>0.5.0-SNAPSHOT</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>sal.networkconfiguration</artifactId>\r
+ <version>0.0.1-SNAPSHOT</version>\r
+ </dependency>\r
+ </dependencies>\r
+</project>\r
--- /dev/null
+package org.opendaylight.controller.sal.networkconfig.bridgedomain.internal;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants;
+import org.opendaylight.controller.sal.networkconfig.bridgedomain.IBridgeDomainConfigService;
+import org.opendaylight.controller.sal.networkconfig.bridgedomain.IPluginInBridgeDomainConfigService;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BridgeDomainConfigService implements IBridgeDomainConfigService {
+ protected static final Logger logger = LoggerFactory
+ .getLogger(BridgeDomainConfigService.class);
+ private ConcurrentMap<String, IPluginInBridgeDomainConfigService> pluginService =
+ new ConcurrentHashMap<String, IPluginInBridgeDomainConfigService>();
+
+ void setPluginInService (Map props, IPluginInBridgeDomainConfigService s) {
+ String type = null;
+ Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
+ if (value instanceof String) {
+ type = (String) value;
+ }
+ if (type == null) {
+ logger.error("Received a PluginInConnectionService without any "
+ + "protocolPluginType provided");
+ } else {
+ this.pluginService.put(type, s);
+ }
+ }
+
+ void unsetPluginInService(Map props, IPluginInBridgeDomainConfigService s) {
+ String type = null;
+
+ Object value = props.get(GlobalConstants.PROTOCOLPLUGINTYPE.toString());
+ if (value instanceof String) {
+ type = (String) value;
+ }
+ if (type == null) {
+ logger.error("Received a PluginInConnectionService without any "
+ + "protocolPluginType provided");
+ } else if (this.pluginService.get(type).equals(s)) {
+ this.pluginService.remove(type);
+ }
+ }
+
+ /**
+ * Function called by the dependency manager when all the required
+ * dependencies are satisfied
+ *
+ */
+ void init() {
+ }
+
+ /**
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
+ */
+ void destroy() {
+ if (this.pluginService != null) {
+ this.pluginService.clear();
+ }
+ }
+
+ @Override
+ public Status createBridgeDomain(Node node, String bridgeIdentifier, Map<ConfigConstants, Object> params)
+ throws Throwable {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.createBridgeDomain(node, bridgeIdentifier, params);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Requested Plugin Service Not available");
+ }
+
+ @Override
+ public Status deleteBridgeDomain(Node node, String bridgeIdentifier) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.deleteBridgeDomain(node, bridgeIdentifier);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Requested Plugin Service Not available");
+ }
+
+ @Override
+ public List<String> getBridgeDomains(Node node) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.getBridgeDomains(node);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Status addBridgeDomainConfig(Node node, String bridgeIdentifier, Map<ConfigConstants, Object> params) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.addBridgeDomainConfig(node, bridgeIdentifier, params);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Requested Plugin Service Not available");
+ }
+
+ @Override
+ public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier, Map<ConfigConstants, Object> params) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.removeBridgeDomainConfig(node, bridgeIdentifier, params);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Requested Plugin Service Not available");
+ }
+
+ @Override
+ public Map<ConfigConstants, Object> getBridgeDomainConfigs(Node node, String bridgeIdentifier) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.getBridgeDomainConfigs(node, bridgeIdentifier);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Node getBridgeDomainNode(Node configNode, String bridgeIdentifier) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(configNode.getType());
+ if (plugin != null) {
+ return plugin.getBridgeDomainNode(configNode, bridgeIdentifier);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Status addPort(Node node, String bridgeIdentifier, String portIdentifier, Map<ConfigConstants, Object> params) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.addPort(node, bridgeIdentifier, portIdentifier, params);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Requested Plugin Service Not available");
+ }
+
+ @Override
+ public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.deletePort(node, bridgeIdentifier, portIdentifier);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Requested Plugin Service Not available");
+ }
+
+ @Override
+ public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier,
+ Map<ConfigConstants, Object> params) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.addPortConfig(node, bridgeIdentifier, portIdentifier, params);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Requested Plugin Service Not available");
+ }
+
+ @Override
+ public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier,
+ Map<ConfigConstants, Object> params) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.removePortConfig(node, bridgeIdentifier, portIdentifier, params);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Requested Plugin Service Not available");
+ }
+
+ @Override
+ public Map<ConfigConstants, Object> getPortConfigs(Node node, String bridgeIdentifier, String portIdentifier) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(node.getType());
+ if (plugin != null) {
+ return plugin.getPortConfigs(node, bridgeIdentifier, portIdentifier);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public NodeConnector getNodeConnector(Node configNode, String bridgeIdentifier, String portIdentifier) {
+ if (pluginService != null) {
+ IPluginInBridgeDomainConfigService plugin = this.pluginService.get(configNode.getType());
+ if (plugin != null) {
+ return plugin.getNodeConnector(configNode, bridgeIdentifier, portIdentifier);
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.networkconfig.internal;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+import org.opendaylight.controller.sal.networkconfig.bridgedomain.IBridgeDomainConfigService;
+import org.opendaylight.controller.sal.networkconfig.bridgedomain.IPluginInBridgeDomainConfigService;
+import org.opendaylight.controller.sal.networkconfig.bridgedomain.internal.BridgeDomainConfigService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Activator extends ComponentActivatorAbstractBase {
+ protected static final Logger logger = LoggerFactory
+ .getLogger(Activator.class);
+
+ /**
+ * Function called when the activator starts just after some initializations
+ * are done by the ComponentActivatorAbstractBase.
+ *
+ */
+ @Override
+ public void init() {
+
+ }
+
+ /**
+ * Function called when the activator stops just before the cleanup done by
+ * ComponentActivatorAbstractBase
+ *
+ */
+ @Override
+ public void destroy() {
+
+ }
+
+ /**
+ * Function that is used to communicate to dependency manager the list of
+ * known Global implementations
+ *
+ *
+ * @return An array containing all the CLASS objects that will be
+ * instantiated in order to get an fully working implementation
+ * Object
+ */
+ public Object[] getGlobalImplementations() {
+ Object[] res = { BridgeDomainConfigService.class};
+ return res;
+ }
+
+ /**
+ * Function that is called when configuration of the dependencies is required.
+ *
+ * @param c
+ * dependency manager Component object, used for configuring the
+ * dependencies exported and imported
+ * @param imp
+ * Implementation class that is being configured, needed as long
+ * as the same routine can configure multiple implementations
+ */
+ public void configureGlobalInstance(Component c, Object imp) {
+ if (imp.equals(BridgeDomainConfigService.class)) {
+ c.setInterface(
+ new String[] { IBridgeDomainConfigService.class.getName()},
+ null);
+
+ c.add(createServiceDependency()
+ .setService(IPluginInBridgeDomainConfigService.class)
+ .setCallbacks("setPluginInService", "unsetPluginInService")
+ .setRequired(false));
+ }
+ }
+}