Interfacemgr: Listener for NodeConnector events 69/19169/2
authorVishal Thapar <vishal.thapar@ericsson.com>
Mon, 27 Apr 2015 18:35:48 +0000 (00:05 +0530)
committerVishal Thapar <vishal.thapar@ericsson.com>
Mon, 27 Apr 2015 19:16:54 +0000 (00:46 +0530)
1. Added listener for NodeConnector DCNs
2. Added openflowplugin to features.xml
3. Corrected dependency for model-flow-service
4. Added code for interfaces update/delete

Change-Id: If2391f3ca96589870fbc33bd0b9d09e19daf09b1
Signed-off-by: Vishal Thapar <vishal.thapar@ericsson.com>
features/src/main/features/features.xml
interfacemgr/interfacemgr-impl/pom.xml
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java

index d87ef722a1bceefb59bbe5e3f630d410bf1c3564..d710d320418b322520133fd38dc86f00730b61fd 100644 (file)
@@ -18,7 +18,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <feature version='${yangtools.version}'>odl-yangtools-models</feature>
     <feature version='${openflowplugin.version}'>odl-openflowplugin-nsf-model</feature>
     <bundle>mvn:org.opendaylight.vpnservice/model-bgp/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/nexthopmgr-api/${nexthopmgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/idmanager-api/${idmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/fibmanager-api/${fibmanager.version}</bundle>
@@ -27,28 +27,30 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <feature name='odl-vpnservice-impl' version='${project.version}' description='OpenDaylight :: vpnservice :: impl '>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
     <feature version='${project.version}'>odl-vpnservice-api</feature>
+    <feature version="${openflowplugin.version}">odl-openflowplugin-southbound</feature>
+    <feature version="${openflowplugin.version}">odl-openflowplugin-flow-services</feature>
     <bundle>mvn:org.opendaylight.vpnservice/bgpmanager-api/${project.version}</bundle>
-       <bundle>mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}</bundle>
-       <bundle>mvn:org.opendaylight.vpnservice/mdsalutil-api/${interfacemgr.version}</bundle>
-       <bundle>mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/mdsalutil-api/${interfacemgr.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/interfacemgr-api/${interfacemgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/idmanager-impl/${idmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}</bundle>
-    
+
     <!--<bundle>mvn:org.opendaylight.vpnservice.third-party/org.apache.thriftlib/1.0.1-SNAPSHOT</bundle>-->
     <bundle>wrap:mvn:org.apache.thrift/libthrift/0.9.1$overwrite=merge&amp;Bundle-Version=0.9.1&amp;Export-Package=*;-noimport:=true;version="0.9.1"</bundle>
     <!--<bundle>wrap:mvn:javax.servlet/servlet-api/2.5</bundle>-->
-       <configfile finalname="bgpmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}/xml/config</configfile>
-       <configfile finalname="mdsalutil-impl-default-config.xml">mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}/xml/config</configfile>
+    <configfile finalname="bgpmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}/xml/config</configfile>
+    <configfile finalname="mdsalutil-impl-default-config.xml">mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}/xml/config</configfile>
     <configfile finalname="vpnmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}/xml/config</configfile>
     <configfile finalname="interfacemgr-impl-default-config.xml">mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}/xml/config</configfile>
     <configfile finalname="nexthopmgr-impl-default-config.xml">mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}/xml/config</configfile>
     <configfile finalname="idmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/idmanager-impl/${idmanager.version}/xml/config</configfile>
     <configfile finalname="fibmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}/xml/config</configfile>
-    
+
   </feature>
   <feature name='odl-vpnservice-impl-rest' version='${project.version}' description='OpenDaylight :: vpnservice :: impl :: REST '>
     <feature version="${project.version}">odl-vpnservice-impl</feature>
index 9c90c127004febacac5294c370534dc30a3034cb..6fcdf059deb68d621390e542ea6bcad42e850c5a 100644 (file)
@@ -27,8 +27,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.controller.model</groupId>
+      <groupId>org.opendaylight.openflowplugin.model</groupId>
       <artifactId>model-flow-service</artifactId>
+      <version>0.1.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools.model</groupId>
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java
new file mode 100644 (file)
index 0000000..ef3653e
--- /dev/null
@@ -0,0 +1,81 @@
+package org.opendaylight.vpnservice.interfacemgr;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+
+import java.util.Iterator;
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.opendaylight.vpnservice.AbstractDataChangeListener;
+
+public class IfmNodeConnectorListener extends AbstractDataChangeListener<NodeConnector> implements AutoCloseable{
+    private static final Logger LOG = LoggerFactory.getLogger(IfmNodeConnectorListener.class);
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private final DataBroker broker;
+    private InterfaceManager ifManager;
+
+    public IfmNodeConnectorListener(final DataBroker db) {
+        super(NodeConnector.class);
+        broker = db;
+        registerListener(db);
+    }
+
+    public IfmNodeConnectorListener(final DataBroker dataBroker, InterfaceManager interfaceManager) {
+        this(dataBroker);
+        ifManager = interfaceManager;
+    }
+
+    private void registerListener(final DataBroker db) {
+        try {
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+                    getWildCardPath(), IfmNodeConnectorListener.this, DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            LOG.error("IfmNodeConnectorListener: DataChange listener registration fail!", e);
+            throw new IllegalStateException("IfmNodeConnectorListener: registration Listener failed.", e);
+        }
+    }
+
+    private InstanceIdentifier<NodeConnector> getWildCardPath() {
+        return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up DataChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+        LOG.info("IfmNodeConnectorListener Closed");
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<NodeConnector> identifier, NodeConnector node) {
+        LOG.trace("NodeConnectorAdded: key: " + identifier + ", value=" + node );
+        ifManager.processPortAdd(node);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<NodeConnector> identifier, NodeConnector del) {
+        LOG.trace("NodeConnectorRemoved: key: " + identifier + ", value=" + del );
+        ifManager.processPortDelete(del);
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<NodeConnector> identifier, NodeConnector original, NodeConnector update) {
+        LOG.trace("NodeConnectorUpdated: key: " + identifier + ", original=" + original + ", update=" + update );
+        ifManager.processPortUpdate(original, update);
+    }
+
+}
index 3ba00f57b5891a180bcfc7b82ff0b11689efb7fd..768656d78f008ece4fdb44b046c2d4e24fd964d3 100644 (file)
@@ -7,8 +7,10 @@
  */
 package org.opendaylight.vpnservice.interfacemgr;
 
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
 import java.math.BigInteger;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
@@ -78,7 +80,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
         }
         LOG.info("Interface Manager Closed");
     }
-    
+
     private void registerListener(final DataBroker db) {
         try {
             listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
@@ -108,7 +110,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
 
     private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
         //TODO Make this generic and move to AbstractDataChangeListener or Utils.
-        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder = 
+        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
                 InstanceIdentifier.builder(InterfacesState.class)
                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
                                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
@@ -123,7 +125,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
         if(port.isPresent()) {
             Interface interf = port.get();
             NodeConnector nodeConn = getNodeConnectorFromInterface(interf);
-            updateInterfaceState(interf, nodeConn);
+            updateInterfaceState(identifier, interf, nodeConn);
             /* TODO:
              *  1. Get interface-id from id manager
              *  2. Update interface-state with following:
@@ -137,7 +139,8 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
         }
     }
 
-    private void updateInterfaceState(Interface interf, NodeConnector nodeConn) {
+    private void updateInterfaceState(InstanceIdentifier<Interface> identifier,
+                    Interface interf, NodeConnector nodeConn) {
         /* Update InterfaceState
          * 1. Get interfaces-state Identifier
          * 2. Add interface to interfaces-state/interface
@@ -152,8 +155,9 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
                         read(LogicalDatastoreType.OPERATIONAL, id);
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder =
+                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
         if(!stateIf.isPresent()) {
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
             // TODO: Get interface-id from IdManager
             ifaceBuilder.setAdminStatus((interf.isEnabled()) ?  org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Up :
                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Down);
@@ -162,11 +166,37 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
             ifaceBuilder.setKey(getStateInterfaceKeyFromName(interf.getName()));
             //ifaceBuilder.setStatistics(createStatistics(interf.getName(), nodeConn));
             stateIface = ifaceBuilder.build();
-            LOG.trace("updating OPERATIONAL data store with stateIface {} and id {}", stateIface, id);
+            LOG.trace("Adding stateIface {} and id {} to OPERATIONAL DS", stateIface, id);
             asyncWrite(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
+        } else {
+            if(interf.isEnabled() != null) {
+                ifaceBuilder.setAdminStatus((interf.isEnabled()) ?  org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Up :
+                    org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Down);
+            }
+            if(interf.getType() != null) {
+                ifaceBuilder.setType(interf.getType());
+            }
+
+            stateIface = ifaceBuilder.build();
+            LOG.trace("updating OPERATIONAL data store with stateIface {} and id {}", stateIface, id);
+            asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
         }
     }
 
+    /*
+    private void setAugmentations(
+                    org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder,
+                    InstanceIdentifier<Interface> identifier, Interface interf) {
+        // TODO Add code for all augmentations
+        InstanceIdentifier<IfL3tunnel> ifL3TunnelPath = identifier.augmentation(IfL3tunnel.class);
+        Optional<IfL3tunnel> l3Tunnel = read(LogicalDatastoreType.CONFIGURATION, ifL3TunnelPath);
+        String ifName = interf.getName();
+        if(l3Tunnel.isPresent()) {
+            l3Tunnel.get();
+        }
+    }
+    */
+
     private Statistics createStatistics(String name, NodeConnector nodeConn) {
         Counter64 init64 = new Counter64(new BigInteger("0000000000000000"));
         Counter32 init32 = new Counter32((long) 0);
@@ -186,6 +216,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
 
     private NodeConnector getNodeConnectorFromInterface(Interface interf) {
         NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
+        //TODO: Replace with MDSAL Util method
         NodeId nodeId = new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
         InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
                         .child(Node.class, new NodeKey(nodeId))
@@ -201,12 +232,14 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
     }
 
     private void delInterface(final InstanceIdentifier<Interface> identifier,
-                              final Interface del) {
-        InstanceIdentifier<Interface> id = buildId(identifier);
-        Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
-        if(port.isPresent()) {
-            Interface interf = port.get();
-            // TODO: Update operational data
+                              final Interface delInterface) {
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
+                        buildStateInterfaceId(delInterface.getName());
+        Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
+                        read(LogicalDatastoreType.OPERATIONAL, id);
+        if(!stateIf.isPresent()) {
+            LOG.trace("deleting interfaces:state OPERATIONAL data store with id {}", id);
+            asyncRemove(LogicalDatastoreType.OPERATIONAL, id, DEFAULT_CALLBACK);
         }
     }
 
@@ -257,4 +290,39 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
     tx.put(datastoreType, path, data, true);
     Futures.addCallback(tx.submit(), callback);
     }
+
+    private <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
+                    InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+    WriteTransaction tx = broker.newWriteOnlyTransaction();
+    tx.merge(datastoreType, path, data, true);
+    Futures.addCallback(tx.submit(), callback);
+    }
+
+    private <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
+                    InstanceIdentifier<T> path, FutureCallback<Void> callback) {
+    WriteTransaction tx = broker.newWriteOnlyTransaction();
+    tx.delete(datastoreType, path);
+    Futures.addCallback(tx.submit(), callback);
+    }
+
+    public void processPortAdd(NodeConnector port) {
+        String strPortId = port.getId().getValue();
+        FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
+        LOG.debug("PortAdd: PortId { "+strPortId+"} PortName {"+ofPort.getName()+"}");
+    }
+
+    public void processPortUpdate(NodeConnector oldPort, NodeConnector update) {
+        String oldPortId = oldPort.getId().getValue();
+        FlowCapableNodeConnector oldOfPort = oldPort.getAugmentation(FlowCapableNodeConnector.class);
+        String strPortId = update.getId().getValue();
+        FlowCapableNodeConnector ofPort = update.getAugmentation(FlowCapableNodeConnector.class);
+        LOG.debug("PortUpdate: { "+strPortId+", "+ofPort.getName()+"}");
+    }
+
+    public void processPortDelete(NodeConnector port) {
+        String strPortId = port.getId().getValue();
+        FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
+        LOG.debug("PortDelete: PortId { "+strPortId+"} PortName {"+ofPort.getName()+"}");
+    }
+
 }
index ab30a083bf94dd5aa17d389603eb0dbdbbad47cc..8127e92888450950f1d0e68faf26b49ccfe86400 100644 (file)
@@ -19,6 +19,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
     private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
 
     private InterfaceManager interfaceManager;
+    private IfmNodeConnectorListener ifmNcListener;
 
     @Override
     public void onSessionInitiated(ProviderContext session) {
@@ -26,15 +27,19 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
         try {
             final  DataBroker dataBroker = session.getSALService(DataBroker.class);
             interfaceManager = new InterfaceManager(dataBroker);
+            ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager);
         } catch (Exception e) {
             LOG.error("Error initializing services", e);
         }
+        //TODO: Make this debug
+        LOG.info("Interfacemgr services initiated");
     }
 
     @Override
     public void close() throws Exception {
         LOG.info("InterfacemgrProvider Closed");
         interfaceManager.close();
+        ifmNcListener.close();
     }
 
     @Override