Interfacemgr: Added APIs 15/19315/1
authorVishal Thapar <vishal.thapar@ericsson.com>
Wed, 29 Apr 2015 15:37:24 +0000 (21:07 +0530)
committerVishal Thapar <vishal.thapar@ericsson.com>
Wed, 29 Apr 2015 15:37:24 +0000 (21:07 +0530)
1. Added APIs needed by NextHop and VPNManager
 a. getPortForInterface
 b. getDpnForInterface
 c. getEndpointIpForDpn
 d. getInterfaceIngressRule
2. Cleaned up some dead code

Pending:
1. Add more types to getInterfaceIngressRule
2. Add getInterfaceEgressAction API
3. JUnits
4. Resolve Sonar issues.
5. Refactoring code to MDSALUtil.

Change-Id: I0262ae767b0ca3e4eb3b3dfd0aa0844d59e26882
Signed-off-by: Vishal Thapar <vishal.thapar@ericsson.com>
interfacemgr/interfacemgr-api/pom.xml
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/interfaces/IInterfaceManager.java
interfacemgr/interfacemgr-impl/pom.xml
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java
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 84f0c09cbd06d7d8f6e957f4b0c5d3f50a55a58c..4cfdfcf6919de45a345c3371e1ab999adb0061d0 100644 (file)
@@ -27,6 +27,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <yang.ext.version>2013.09.07.7-SNAPSHOT</yang.ext.version>
     <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
     <mdsal.version>1.2.0-SNAPSHOT</mdsal.version>
+    <vpns.mdsalutil.version>0.0.1-SNAPSHOT</vpns.mdsalutil.version>
   </properties>
   <dependencies>
     <dependency>
@@ -69,5 +70,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>model-inventory</artifactId>
       <version>${mdsal.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>mdsalutil-api</artifactId>
+      <version>${vpns.mdsalutil.version}</version>
+    </dependency>
   </dependencies>
 </project>
\ No newline at end of file
index bda2d8c0c0757b9d088d5c2154b6bf543a324c49..95d1323bbb41411bcb95d3828f4c19576ca5586b 100644 (file)
@@ -1,7 +1,13 @@
 package org.opendaylight.vpnservice.interfacemgr.interfaces;
 
+import java.util.List;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+
 public interface IInterfaceManager {
 
-    public void testApi();
+    public Long getPortForInterface(String ifName);
+    public long getDpnForInterface(String ifName);
+    public String getEndpointIpForDpn(long dpnId);
+    public List<MatchInfo> getInterfaceIngressRule(String ifName);
 
 }
\ No newline at end of file
index 6fcdf059deb68d621390e542ea6bcad42e850c5a..eba9fc5a9bfd7d0710e62381e1bb4c0b2b1f1f97 100644 (file)
@@ -40,6 +40,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>vpnmanager-impl</artifactId>
       <version>1.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>mdsalutil-api</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
     <!-- Testing Dependencies -->
     <dependency>
       <groupId>junit</groupId>
index 58717bcaab74a4f57edd7aebb388853a57c78dff..fe0a8be8989393bd482ab77b979d8bbb6e47ba7b 100644 (file)
@@ -2,8 +2,6 @@ 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;
index 533484012d4ffdd6e6ee37a9b35448e67216b8a2..4d7e509b6f0126c7b4cb37dcfb6921016fe59464 100644 (file)
@@ -7,18 +7,18 @@
  */
 package org.opendaylight.vpnservice.interfacemgr;
 
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+
+import java.util.ArrayList;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
 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;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state._interface.StatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state._interface.Statistics;
 import com.google.common.util.concurrent.Futures;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
@@ -32,6 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.vpnservice.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
@@ -48,11 +49,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import com.google.common.base.Optional;
 
-public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable{
+public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManager.class);
     private ListenerRegistration<DataChangeListener> listenerRegistration;
     private final DataBroker broker;
     private final Map<NodeConnectorId, String> mapNcToInterfaceName = new ConcurrentHashMap<>();
+    private final Map<NodeId, String> dbDpnEndpoints = new ConcurrentHashMap<>();
 
     private static final FutureCallback<Void> DEFAULT_CALLBACK =
                     new FutureCallback<Void>() {
@@ -97,7 +99,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
     @Override
     protected void add(final InstanceIdentifier<Interface> identifier,
             final Interface imgrInterface) {
-        LOG.trace("key: " + identifier + ", value=" + imgrInterface );
+        LOG.trace("Adding interface key: " + identifier + ", value=" + imgrInterface );
         addInterface(identifier, imgrInterface);
     }
 
@@ -126,28 +128,20 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
     }
 
     private void addInterface(final InstanceIdentifier<Interface> identifier,
-                              final Interface imgrInterface) {
-        InstanceIdentifier<Interface> id = buildId(identifier);
-        Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
-        if(port.isPresent()) {
-            Interface interf = port.get();
-            NodeConnector nodeConn = getNodeConnectorFromDataStore(interf);
-            updateInterfaceState(identifier, interf, nodeConn);
-            if(nodeConn == null) {
-                mapNcToInterfaceName.put(this.getNodeConnectorIdFromInterface(interf) , interf.getName());
-            } else {
-                mapNcToInterfaceName.put(nodeConn.getId(), interf.getName());
-            }
-            /* TODO:
-             *  1. Get interface-id from id manager
-             *  2. Update interface-state with following:
-             *    admin-status = set to enable value
-             *    oper-status = Down [?]
-             *    if-index = interface-id
-             * FIXME:
-             *  1. Get operational data from node-connector-id?
-             *
-             */
+                              final Interface interf) {
+        NodeConnector nodeConn = getNodeConnectorFromDataStore(interf);
+        NodeConnectorId ncId = null;
+        updateInterfaceState(identifier, interf, nodeConn);
+        if (nodeConn == null) {
+            ncId = getNodeConnectorIdFromInterface(interf);
+        } else {
+            ncId = nodeConn.getId();
+        }
+        mapNcToInterfaceName.put(ncId, interf.getName());
+        if(interf.getType().getClass().isInstance(L3tunnel.class)) {
+            NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
+            IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
+            this.dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
         }
     }
 
@@ -219,18 +213,6 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
         }
     }
 
-    private Statistics createStatistics(String name, NodeConnector nodeConn) {
-        Counter64 init64 = new Counter64(new BigInteger("0000000000000000"));
-        Counter32 init32 = new Counter32((long) 0);
-        StatisticsBuilder statBuilder = new StatisticsBuilder();
-        statBuilder.setDiscontinuityTime(new DateAndTime("2015-04-04T00:00:00Z"))
-        .setInBroadcastPkts(init64).setInDiscards(init32).setInErrors(init32).setInMulticastPkts(init64)
-        .setInOctets(init64).setInUnicastPkts(init64).setInUnknownProtos(init32).setOutBroadcastPkts(init64)
-        .setOutDiscards(init32).setOutErrors(init32).setOutMulticastPkts(init64).setOutOctets(init64)
-        .setOutUnicastPkts(init64);
-        return statBuilder.build();
-    }
-
     private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
                     String name) {
         return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
@@ -239,7 +221,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
     private NodeConnector getNodeConnectorFromDataStore(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(":")));
+        NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
         InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
                         .child(Node.class, new NodeKey(nodeId))
                         .child(NodeConnector.class, new NodeConnectorKey(ncId)).build();
@@ -269,10 +251,32 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
             NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface);
             if(ncId != null) {
                 mapNcToInterfaceName.remove(ncId);
+                if(delInterface.getType().getClass().isInstance(L3tunnel.class)) {
+                    Node node = getNodeFromDataStore(delInterface);
+                    if(node.getNodeConnector().isEmpty()) {
+                        this.dbDpnEndpoints.remove(node.getId());
+                    }
+                }
             }
         }
     }
 
+    private Node getNodeFromDataStore(Interface interf) {
+        NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
+        //TODO: Replace with MDSAL Util method
+        NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
+        InstanceIdentifier<Node> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
+                        .child(Node.class, new NodeKey(nodeId)).build();
+
+        Optional<Node> dpn = read(LogicalDatastoreType.OPERATIONAL, ncIdentifier);
+        if(dpn.isPresent()) {
+            Node node = dpn.get();
+            LOG.trace("node: {}",node);
+            return node;
+        }
+        return null;
+    }
+
     private void updateInterface(final InstanceIdentifier<Interface> identifier,
                               final Interface original, final Interface update) {
         InstanceIdentifier<Interface> id = buildId(identifier);
@@ -287,8 +291,12 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
             if(nc != null) {
                 // Name doesn't change. Is it present in update?
                 mapNcToInterfaceName.put(nc.getId(), original.getName());
+                if(interf.getType().getClass().isInstance(L3tunnel.class)) {
+                    NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId());
+                    IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
+                    this.dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+                }
             }
-            //TODO: Update operational data
         }
     }
 
@@ -354,7 +362,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
 
     void processPortUpdate(NodeConnector oldPort, NodeConnector update) {
         //TODO: Currently nothing to do here.
-        //LOG.trace("map: {}", this.mapNcToInterfaceName);
+        LOG.trace("ifMap: {}, dpnMap: {}", mapNcToInterfaceName, dbDpnEndpoints);
     }
 
     void processPortDelete(NodeConnector port) {
@@ -382,4 +390,83 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
         }
     }
 
+    private Interface getInterfaceByIfName(String ifName) {
+        InstanceIdentifier<Interface> id = buildId(ifName);
+        Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
+        if(port.isPresent()) {
+            return port.get();
+        }
+        return null;
+    }
+
+    Long getPortForInterface(String ifName) {
+        Interface iface = getInterfaceByIfName(ifName);
+        return getPortNumForInterface(iface);
+    }
+
+    long getDpnForInterface(String ifName) {
+        Interface iface = getInterfaceByIfName(ifName);
+        try {
+            NodeConnector port = getNodeConnectorFromDataStore(iface);
+            //TODO: This should be an MDSAL Util method
+            return Long.parseLong(getDpnFromNodeConnectorId(port.getId()));
+        } catch (NullPointerException e) {
+            LOG.error("OFPort for Interface {} not found", ifName);
+        }
+        return 0L;
+    }
+
+    String getEndpointIpForDpn(long dpnId) {
+        //TODO: This should be MDSAL Util function
+        NodeId dpnNodeId = buildDpnNodeId(dpnId);
+        return dbDpnEndpoints.get(dpnNodeId);
+    }
+
+    List<MatchInfo> getInterfaceIngressRule(String ifName){
+        Interface iface = getInterfaceByIfName(ifName);
+        List<MatchInfo> matches = new ArrayList<MatchInfo>();
+        Class<? extends Class> ifType = iface.getType().getClass();
+        long dpn = this.getDpnForInterface(ifName);
+        long portNo = this.getPortNumForInterface(iface).longValue();
+        matches.add(new MatchInfo(MatchFieldType.in_port, new long[] {dpn, portNo}));
+        if(ifType.isInstance(L2vlan.class)) {
+            IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
+            matches.add(new MatchInfo(MatchFieldType.vlan_vid, 
+                            new long[] {vlanIface.getVlanId().longValue()}));
+            return matches;
+        } else if (ifType.isInstance(L3tunnel.class)) {
+            //TODO: Handle different tunnel types
+            return matches;
+        }
+        return null;
+    }
+
+    private String getDpnFromNodeConnectorId(NodeConnectorId portId) {
+        /*
+         * NodeConnectorId is of form 'openflow:dpnid:portnum'
+         */
+        String[] split = portId.getValue().split(":");
+        return split[1];
+    }
+
+    private NodeId buildDpnNodeId(long dpnId) {
+        // TODO Auto-generated method stub
+        return new NodeId("openflow:" + dpnId);
+    }
+
+    private NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
+        return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
+    }
+
+    private Long getPortNumForInterface(Interface iface) {
+        try {
+            NodeConnector port = getNodeConnectorFromDataStore(iface);
+            FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
+            return ofPort.getPortNumber().getUint32();
+        } catch (Exception e) {
+            LOG.error("OFPort for Interface {} not found", iface.getName());
+        }
+        return null;
+    }
 }
index 8127e92888450950f1d0e68faf26b49ccfe86400..8a267a2415f947012918f45e57260bf024eb28cb 100644 (file)
@@ -7,12 +7,18 @@
  */
 package org.opendaylight.vpnservice.interfacemgr;
 
+import java.util.List;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
 
 public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable, IInterfaceManager {
 
@@ -43,7 +49,22 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
     }
 
     @Override
-    public void testApi() {
-        LOG.debug("Testing interface mgr api");
+    public Long getPortForInterface(String ifName) {
+        return interfaceManager.getPortForInterface(ifName);
+    }
+
+    @Override
+    public long getDpnForInterface(String ifName) {
+        return interfaceManager.getDpnForInterface(ifName);
+    }
+
+    @Override
+    public String getEndpointIpForDpn(long dpnId) {
+        return interfaceManager.getEndpointIpForDpn(dpnId);
+    }
+
+    @Override
+    public List<MatchInfo> getInterfaceIngressRule(String ifName) {
+        return interfaceManager.getInterfaceIngressRule(ifName);
     }
-}
\ No newline at end of file
+}