Bug 6498 - Fix etree 38/44838/1
authorYakir Dorani <yakir.dorani@hpe.com>
Mon, 22 Aug 2016 13:48:12 +0000 (16:48 +0300)
committerYakir Dorani <yakir.dorani@hpe.com>
Tue, 30 Aug 2016 09:50:32 +0000 (12:50 +0300)
Change-Id: I7fd8901471e38cce7ebf8f31873dfe40bd9e3c95
Signed-off-by: Yakir Dorani <yakir.dorani@hpe.com>
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/EvcListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtUtils.java

index 02d4bd85ca29076cbe83c55560d8eff4f4ed4a34..287f08a6c20b000512de6e707b2b13f8cee19a60 100644 (file)
@@ -14,20 +14,24 @@ import java.util.List;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.Evc;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.Uni;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.EvcUniCeVlans;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.evc.uni.ce.vlans.EvcUniCeVlan;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcType;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcUniRoleType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+
 public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
 
     private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
@@ -85,12 +89,14 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
             Evc data = newDataObject.getRootNode().getDataAfter();
             String instanceName = data.getEvcId().getValue();
 
-            log.info("Adding elan instance: " + instanceName);
-            NetvirtUtils.createElanInstance(dataBroker, instanceName);
+            boolean isEtree = data.getEvcType() == EvcType.RootedMultipoint;
+
+            log.info("Adding {} instance: {}", isEtree ? "etree" : "elan", instanceName);
+            NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree);
 
-            // Create elan interfaces
+            // Create interfaces
             for (Uni uni : data.getUnis().getUni()) {
-                createElanInterface(instanceName, uni);
+                createInterface(instanceName, uni, isEtree);
             }
         } catch (final Exception e) {
             log.error("Add evc failed !", e);
@@ -103,8 +109,9 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
             Evc update = modifiedDataObject.getRootNode().getDataAfter();
 
             String instanceName = original.getEvcId().getValue();
+            boolean isEtree = update.getEvcType() == EvcType.RootedMultipoint;
 
-            log.info("Updating elan instance: " + instanceName);
+            log.info("Updating {} instance: {}", isEtree ? "etree" : "elan", instanceName);
 
             List<Uni> originalUni = original.getUnis().getUni();
             List<Uni> updateUni = update.getUnis().getUni();
@@ -124,7 +131,7 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
                 // Adding the new Uni which are presented in the updated List
                 if (updateUni.size() > 0) {
                     for (Uni uni : updateUni) {
-                        createElanInterface(instanceName, uni);
+                        createInterface(instanceName, uni, isEtree);
                     }
                 }
             } else if (originalUni != null && !originalUni.isEmpty()) {
@@ -154,7 +161,7 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
         }
     }
 
-    private void createElanInterface(String instanceName, Uni uni) {
+    private void createInterface(String instanceName, Uni uni, boolean isEtree) {
         EvcUniUtils.addUni(dataBroker, uni);
 
         String uniId = uni.getUniId().getValue();
@@ -162,6 +169,14 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
         Link link = EvcUniUtils.getLink(dataBroker, uni);
         String interfaceName = EvcUniUtils.getInterfaceName(link, uniId);
 
+        boolean result = waitForGeniusToUpdateInterface(interfaceName);
+        if (!result) {
+            log.error("State interface {} is missing ifIndex", interfaceName);
+            return;
+        }
+
+        EvcUniRoleType role = uni.getRole();
+
         EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
 
         if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
@@ -169,12 +184,59 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
 
                 interfaceName = NetvirtUtils.getInterfaceNameForVlan(interfaceName, x.getVid().toString());
 
-                log.info("Adding elan interface: " + interfaceName);
-                NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
+                log.info("Adding {} interface: {}", isEtree ? "etree" : "elan", interfaceName);
+
+                if (isEtree) {
+                    NetvirtUtils.createEtreeInterface(dataBroker, instanceName, interfaceName,
+                            RoleToInterfaceType(role));
+                } else {
+                    NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
+                }
+
             }
         } else {
-            log.info("Adding elan interface: " + interfaceName);
-            NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
+            log.info("Adding {} interface: {}", isEtree ? "etree" : "elan", interfaceName);
+            NetvirtUtils.createEtreeInterface(dataBroker, instanceName, interfaceName, RoleToInterfaceType(role));
+        }
+    }
+
+    private boolean waitForGeniusToUpdateInterface(String interfaceName) {
+        int retries = 10;
+
+        while (retries > 0) {
+            Optional<Interface> optional = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                    NetvirtUtils.getStateInterfaceIdentifier(interfaceName));
+
+            Interface stateInterface = optional.get();
+
+            if (stateInterface != null && stateInterface.getIfIndex() != null) {
+                log.info("State interface configured with ifIndex {}", stateInterface.getIfIndex());
+
+                // Wait a bit, because if we continue too soon this will not
+                // work.
+                try {
+                    Thread.sleep(3000);
+                } catch (InterruptedException e) {
+                }
+
+                return true;
+            }
+
+            retries -= 1;
+            try {
+                Thread.sleep(1500);
+            } catch (InterruptedException e) {
+            }
+        }
+
+        return false;
+    }
+
+    private static EtreeInterfaceType RoleToInterfaceType(EvcUniRoleType role) {
+        if (role == EvcUniRoleType.Root) {
+            return EtreeInterfaceType.Root;
+        } else {
+            return EtreeInterfaceType.Leaf;
         }
     }
 
index b5b51d2b55f9fc2e40ce8f35029dbe0f1d1e6873..a154ae901f603baa982631bee42ceb4c30315ac8 100644 (file)
@@ -10,7 +10,16 @@ package org.opendaylight.unimgr.mef.netvirt;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.MefTopology;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.Devices;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.Device;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.DeviceKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.Interfaces;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.IetfInterfacesData;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 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.genius.interfacemanager.rev160406.IfL2vlan;
@@ -18,6 +27,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
@@ -26,14 +40,21 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 
 public class NetvirtUtils {
     public final static String VLAN_SEPARATOR = ".";
 
-    public static void createElanInstance(DataBroker dataBroker, String instanceName) {
+    public static void createElanInstance(DataBroker dataBroker, String instanceName, boolean isEtree) {
         ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
 
+        if (isEtree) {
+            EtreeInstance etreeInstance = new EtreeInstanceBuilder().build();
+            einstBuilder.addAugmentation(EtreeInstance.class, etreeInstance).build();
+        }
+
         MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
                 getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
     }
@@ -45,6 +66,14 @@ public class NetvirtUtils {
                 getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
     }
 
+    public static void createEtreeInterface(DataBroker dataBroker, String instanceName, String interfaceName,
+            EtreeInterfaceType type) {
+        ElanInterfaceBuilder einterfaceBuilder = createEtreeInterface(instanceName, interfaceName, type);
+
+        MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+    }
+
     public static void updateElanInstance(DataBroker dataBroker, String instanceName) {
 
         ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
@@ -108,6 +137,16 @@ public class NetvirtUtils {
         return einterfaceBuilder;
     }
 
+    private static ElanInterfaceBuilder createEtreeInterface(String instanceName, String interfaceName,
+            EtreeInterfaceType interfaceType) {
+        ElanInterfaceBuilder einterfaceBuilder = new ElanInterfaceBuilder();
+        einterfaceBuilder.setElanInstanceName(instanceName);
+        einterfaceBuilder.setName(interfaceName);
+        EtreeInterface etreeInterface = new EtreeInterfaceBuilder().setEtreeInterfaceType(interfaceType).build();
+        einterfaceBuilder.addAugmentation(EtreeInterface.class, etreeInterface);
+        return einterfaceBuilder;
+    }
+
     private static InstanceIdentifier<ElanInstance> getElanInstanceInstanceIdentifier(String instanceName) {
         return InstanceIdentifier.builder(ElanInstances.class)
                 .child(ElanInstance.class, new ElanInstanceKey(instanceName)).build();
@@ -117,4 +156,16 @@ public class NetvirtUtils {
         return InstanceIdentifier.builder(ElanInterfaces.class)
                 .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
     }
+
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> getStateInterfaceIdentifier(
+            String interfaceName) {
+        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));
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder
+                .build();
+        return id;
+    }
 }