Reconnect port support 07/50207/1
authorKonsta Pozdeev <konsta.pozdeev@hpe.com>
Tue, 3 Jan 2017 08:12:36 +0000 (10:12 +0200)
committerDavid Goldberg <gdavid@hpe.com>
Tue, 10 Jan 2017 16:09:15 +0000 (18:09 +0200)
Change-Id: I9fd0bf6bccb6ee89c4025797d45122540d451a94
Signed-off-by: Konsta Pozdeev <konsta.pozdeev@hpe.com>
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/EvcListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/IUniAwareService.java [new file with mode: 0644]
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/IUniPortManager.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/IpvcListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/MefServicesUtils.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NodeConnectorListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/SubnetListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/UniAwareListener.java [new file with mode: 0644]
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/UniPortManager.java
netvirt/src/main/resources/org/opendaylight/blueprint/netvirt-driver.xml

index a513af5e9531526e5db2db2ed4b9ff4be3cd9099..66002adc9a3fc3c43b67544293713842a4ef526e 100644 (file)
@@ -30,6 +30,7 @@ import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.serv
 
 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.http.metroethernetforum.org.ns.yang.mef.types.rev150526.RetailSvcIdType;
 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;
@@ -40,18 +41,21 @@ import com.google.common.base.Optional;
 
 import jline.internal.Log;
 
-public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
+public class EvcListener extends UnimgrDataTreeChangeListener<Evc> implements IUniAwareService {
 
     private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
     private ListenerRegistration<EvcListener> evcListenerRegistration;
     private final IUniPortManager uniPortManager;
     private final UniQosManager uniQosManager;
+    @SuppressWarnings("unused")
+    private final UniAwareListener uniAwareListener;
 
     public EvcListener(final DataBroker dataBroker, final UniPortManager uniPortManager,
             final UniQosManager uniQosManager) {
         super(dataBroker);
         this.uniPortManager = uniPortManager;
         this.uniQosManager = uniQosManager;
+        this.uniAwareListener = new UniAwareListener(dataBroker, this);
         registerListener();
     }
 
@@ -96,6 +100,89 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
         }
     }
 
+    @Override
+    public void connectUni(String uniId) {
+        List<RetailSvcIdType> allEvcs = MefServicesUtils.getAllEvcsServiceIds(dataBroker);
+        allEvcs = (allEvcs != null) ? allEvcs : Collections.emptyList();
+
+        for (RetailSvcIdType evcSerId : allEvcs) {
+            InstanceIdentifier<Evc> evcId = MefServicesUtils.getEvcInstanceIdentifier(evcSerId);
+            Evc evc = MefServicesUtils.getEvc(dataBroker, evcId);
+            if (evc == null) {
+                Log.error("Inconsistent data for svcId {}", evcSerId);
+                continue;
+            }
+
+            String instanceName = evc.getEvcId().getValue();
+            boolean isEtree = evc.getEvcType() == EvcType.RootedMultipoint;
+
+            List<Uni> toConnect = new ArrayList<>();
+            List<Uni> unis = (evc.getUnis() != null) ? evc.getUnis().getUni() : null;
+            unis = (unis != null) ? unis : Collections.emptyList();
+            for (Uni uni : unis) {
+                if (uni.getUniId().getValue().equals(uniId)) {
+                    Log.info("Connecting Uni {} to svc id {}", uniId, evcSerId);
+                    toConnect.add(uni);
+                    break;
+                }
+            }
+
+            EvcElan evcElan = getOperEvcElan(evcId);
+            if (evcElan == null) {
+                NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree, evc.getSegmentationId());
+                evcElan = getOperEvcElan(evcId);
+                if (evcElan == null) {
+                    log.error("Evc {} has not been created as required. Nothing to reconnect", evcId);
+                    return;
+                }
+            }
+
+            for (Uni uni : toConnect) {
+                createUniElanInterfaces(evcId, instanceName, uni, isEtree);
+            }
+            updateQos(toConnect);
+        }
+    }
+
+    @Override
+    public void disconnectUni(String uniId) {
+        List<RetailSvcIdType> allEvcs = MefServicesUtils.getAllEvcsServiceIds(dataBroker);
+        allEvcs = (allEvcs != null) ? allEvcs : Collections.emptyList();
+
+        for (RetailSvcIdType evcSerId : allEvcs) {
+            InstanceIdentifier<Evc> evcId = MefServicesUtils.getEvcInstanceIdentifier(evcSerId);
+            Evc evc = MefServicesUtils.getEvc(dataBroker, evcId);
+            if (evc == null) {
+                Log.error("Inconsistent data for svcId {}", evcSerId);
+                continue;
+            }
+
+            String instanceName = evc.getEvcId().getValue();
+            List<Uni> toDisconnect = new ArrayList<>();
+            List<Uni> unis = (evc.getUnis() != null) ? evc.getUnis().getUni() : null;
+            unis = (unis != null) ? unis : Collections.emptyList();
+            for (Uni uni : unis) {
+                if (uni.getUniId().getValue().equals(uniId)) {
+                    Log.info("Disconnecting Uni {} from svc id {}", uniId, evcSerId);
+                    toDisconnect.add(uni);
+                    break;
+                }
+            }
+
+            EvcElan evcElan = getOperEvcElan(evcId);
+            if (evcElan == null) {
+                log.error("Evc {} has not been created as required. Nothing to disconnect", evcId);
+                return;
+            }
+
+            updateQos(toDisconnect);
+            for (Uni uni : toDisconnect) {
+                removeUniElanInterfaces(evcId, instanceName, uni);
+            }
+        }
+
+    }
+
     private void addEvc(DataTreeModification<Evc> newDataObject) {
         try {
             Evc data = newDataObject.getRootNode().getDataAfter();
@@ -253,31 +340,31 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
                 && !evcUniCeVlans.getEvcUniCeVlan().isEmpty() ? evcUniCeVlans.getEvcUniCeVlan()
                         : Collections.emptyList();
 
-        for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
-            Long vlan = safeCastVlan(ceVlan.getVid());
-            uniPortManager.removeCeVlan(uni.getUniId().getValue(), vlan);
-        }
-
         if (evcUniCeVlan.isEmpty()) {
             String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), Long.valueOf(0));
-            if (!isOperEvcElanPort(evcId, interfaceName)) {
+            if (interfaceName == null || !isOperEvcElanPort(evcId, interfaceName)) {
                 log.info("elan interface for elan {} vlan {} is not operational, nothing to remove", instanceName, 0,
                         interfaceName);
-                return;
+                interfaceName = uniPortManager.getUniVlanInterfaceName(uni.getUniId().getValue(), null);
             }
             removeElanInterface(evcId, uni.getUniId().getValue(), interfaceName);
         } else {
             for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
                 Long vlan = safeCastVlan(ceVlan.getVid());
                 String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), vlan);
-                if (!isOperEvcElanPort(evcId, interfaceName)) {
+                if (interfaceName == null || !isOperEvcElanPort(evcId, interfaceName)) {
                     log.info("elan interface for elan {} vlan {} is not operational, nothing to remove", instanceName,
                             vlan, interfaceName);
-                    return;
+                    interfaceName = uniPortManager.getUniVlanInterfaceName(uni.getUniId().getValue(), vlan);
                 }
                 removeElanInterface(evcId, uni.getUniId().getValue(), interfaceName);
             }
         }
+
+        for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
+            Long vlan = safeCastVlan(ceVlan.getVid());
+            uniPortManager.removeCeVlan(uni.getUniId().getValue(), vlan);
+        }
     }
 
     private void removeElanInterface(InstanceIdentifier<Evc> identifier, String uniId, String interfaceName) {
diff --git a/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/IUniAwareService.java b/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/IUniAwareService.java
new file mode 100644 (file)
index 0000000..efa90c1
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+public interface IUniAwareService {
+
+    void connectUni(String uniId);
+
+    void disconnectUni(String uniId);
+}
index 270f01ac9881397fedceb0bf0b0f51c3e39e0162..6ce6406b17a53aeeda4b65ac1a7eaa2f7bf4ecc9 100644 (file)
@@ -24,4 +24,5 @@ public interface IUniPortManager {
 
     String getUniVlanInterface(String uniId, Long vlanId);
 
+    String getUniVlanInterfaceName(String uniId, Long vlanId);
 }
index f11ea929e9d972de7fded6005db59c0228cd51b6..79b2a64efb3527fdbea75e3ef31df6cc33f1eb24 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.serv
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.VpnElans;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.unis.Uni;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.RetailSvcIdType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
@@ -40,12 +41,14 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
+public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements IUniAwareService {
     private static final Logger Log = LoggerFactory.getLogger(IpvcListener.class);
     private final IUniPortManager uniPortManager;
     private final ISubnetManager subnetManager;
     private final UniQosManager uniQosManager;
     private ListenerRegistration<IpvcListener> ipvcListenerRegistration;
+    @SuppressWarnings("unused")
+    private final UniAwareListener uniAwareListener;
 
     public IpvcListener(final DataBroker dataBroker, final IUniPortManager uniPortManager,
             final ISubnetManager subnetManager, final UniQosManager uniQosManager) {
@@ -53,6 +56,7 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
         this.uniPortManager = uniPortManager;
         this.subnetManager = subnetManager;
         this.uniQosManager = uniQosManager;
+        this.uniAwareListener = new UniAwareListener(dataBroker, this);
         registerListener();
     }
 
@@ -97,48 +101,132 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
         }
     }
 
+    @Override
+    public void connectUni(String uniId) {
+        List<RetailSvcIdType> allIpvcs = MefServicesUtils.getAllIpvcsServiceIds(dataBroker);
+        allIpvcs = (allIpvcs != null) ? allIpvcs : Collections.emptyList();
+
+        for (RetailSvcIdType ipvcSerId : allIpvcs) {
+            InstanceIdentifier<Ipvc> ipvcId = MefServicesUtils.getIpvcInstanceIdentifier(ipvcSerId);
+            Ipvc ipvc = MefServicesUtils.getIpvc(dataBroker, ipvcId);
+            if (ipvc == null) {
+                Log.error("Inconsistent data for svcId {}", ipvcSerId);
+                continue;
+            }
+            List<Uni> toConnect = new ArrayList<>();
+
+            List<Uni> unis = (ipvc.getUnis() != null) ? ipvc.getUnis().getUni() : null;
+            unis = (unis != null) ? unis : Collections.emptyList();
+            for (Uni uni : unis) {
+                if (uni.getUniId().getValue().equals(uniId)) {
+                    Log.info("Connecting Uni {} to svc id {}", uniId, ipvcSerId);
+                    toConnect.add(uni);
+                    break;
+                }
+            }
+
+            IpvcVpn operIpvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
+            if (operIpvcVpn == null) {
+                String instanceName = ipvc.getIpvcId().getValue();
+                final String vpnName = NetvirtVpnUtils.getUUidFromString(instanceName);
+                createVpnInstance(vpnName, ipvcId);
+                operIpvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
+                if (operIpvcVpn == null) {
+                    Log.error("Ipvc {} hasn't been created as required, Nothing to reconnect", ipvcSerId);
+                    return;
+                }
+            }
+            String vpnName = operIpvcVpn.getVpnId();
+            String rd = waitForRd(vpnName);
+            createUnis(vpnName, ipvcId, toConnect, rd);
+        }
+    }
+
+    @Override
+    public void disconnectUni(String uniId) {
+
+        List<RetailSvcIdType> allIpvcs = MefServicesUtils.getAllIpvcsServiceIds(dataBroker);
+        allIpvcs = (allIpvcs != null) ? allIpvcs : Collections.emptyList();
+
+        for (RetailSvcIdType ipvcSerId : allIpvcs) {
+            InstanceIdentifier<Ipvc> ipvcId = MefServicesUtils.getIpvcInstanceIdentifier(ipvcSerId);
+            Ipvc ipvc = MefServicesUtils.getIpvc(dataBroker, ipvcId);
+            if (ipvc == null) {
+                Log.error("Inconsistent data for svcId {}", ipvcSerId);
+                continue;
+            }
+            List<Uni> toRemove = new ArrayList<>();
+
+            List<Uni> unis = (ipvc.getUnis() != null) ? ipvc.getUnis().getUni() : null;
+            unis = (unis != null) ? unis : Collections.emptyList();
+            for (Uni uni : unis) {
+                if (uni.getUniId().getValue().equals(uniId)) {
+                    Log.info("Disconnecting Uni {} from svc id {}", uniId, ipvcSerId);
+                    toRemove.add(uni);
+                    break;
+                }
+            }
+
+            IpvcVpn operIpvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
+            if (operIpvcVpn == null) {
+                Log.error("Ipvc {} hasn't been created as required, Nothing to disconnect", ipvcSerId);
+                return;
+            }
+            String vpnName = operIpvcVpn.getVpnId();
+
+            synchronized (vpnName.intern()) {
+                WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+                removeUnis(ipvcId, operIpvcVpn, toRemove, tx);
+                MdsalUtils.commitTransaction(tx);
+            }
+        }
+    }
+
     private void addIpvc(DataTreeModification<Ipvc> newDataObject) {
         try {
             Ipvc ipvc = newDataObject.getRootNode().getDataAfter();
             String instanceName = ipvc.getIpvcId().getValue();
             final String vpnName = NetvirtVpnUtils.getUUidFromString(instanceName);
             InstanceIdentifier<Ipvc> ipvcId = newDataObject.getRootPath().getRootIdentifier();
-            List<Uni> unis = new ArrayList<>();
-            String rd = null;
-            synchronized (vpnName.intern()) {
-                WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
-                Log.info("Adding vpn instance: " + instanceName);
-                NetvirtVpnUtils.createVpnInstance(vpnName, tx);
-                MefServicesUtils.addOperIpvcVpnElan(ipvcId, vpnName, tx);
-                MdsalUtils.commitTransaction(tx);
-
-                InstanceIdentifier<VpnInstance> vpnId = NetvirtVpnUtils.getVpnInstanceToVpnIdIdentifier(vpnName);
-                DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId, 10,
-                        LogicalDatastoreType.CONFIGURATION, vpn -> vpn.getVrfId());
-                if (!vpnInstanceWaiter.waitForData()) {
-                    String errorMessage = String.format("Fail to wait for vrfId for vpn %s", vpnName);
-                    Log.error(errorMessage);
-                    throw new UnsupportedOperationException(errorMessage);
-                }
-                rd = (String) vpnInstanceWaiter.getData();
-            }
+            createVpnInstance(vpnName, ipvcId);
+            String rd = waitForRd(vpnName);
 
+            List<Uni> unis = new ArrayList<>();
             if (ipvc.getUnis() != null && ipvc.getUnis() != null) {
                 unis = ipvc.getUnis().getUni();
             }
             Log.info("Number of UNI's: " + unis.size());
 
-            // Create elan/vpn interfaces
-            for (Uni uni : unis) {
-                createInterfaces(vpnName, uni, ipvcId, rd);
-            }
-
-            createUnis(ipvcId, unis);
+            createUnis(vpnName, ipvcId, unis, rd);
         } catch (final Exception e) {
             Log.error("Add ipvc failed !", e);
         }
     }
 
+    private void createVpnInstance(final String vpnName, InstanceIdentifier<Ipvc> ipvcId) {
+        synchronized (vpnName.intern()) {
+            WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+            Log.info("Adding vpn instance: " + vpnName);
+            NetvirtVpnUtils.createVpnInstance(vpnName, tx);
+            MefServicesUtils.addOperIpvcVpnElan(ipvcId, vpnName, tx);
+            MdsalUtils.commitTransaction(tx);
+        }
+    }
+
+    private String waitForRd(final String vpnName) {
+        InstanceIdentifier<VpnInstance> vpnId = NetvirtVpnUtils.getVpnInstanceToVpnIdIdentifier(vpnName);
+        @SuppressWarnings("resource")
+        DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<VpnInstance>(dataBroker, vpnId, 5,
+                LogicalDatastoreType.CONFIGURATION, vpn -> vpn.getVrfId());
+        if (!vpnInstanceWaiter.waitForData()) {
+            String errorMessage = String.format("Fail to wait for vrfId for vpn %s", vpnName);
+            Log.error(errorMessage);
+            throw new UnsupportedOperationException(errorMessage);
+        }
+        String rd = (String) vpnInstanceWaiter.getData();
+        return rd;
+    }
+
     private void removeIpvc(DataTreeModification<Ipvc> removedDataObject) {
         try {
             Ipvc ipvc = removedDataObject.getRootNode().getDataBefore();
@@ -192,7 +280,12 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
         updateQos(uniToRemove);
     }
 
-    private void createUnis(InstanceIdentifier<Ipvc> ipvcId, List<Uni> uniToCreate) {
+    private void createUnis(String vpnName, InstanceIdentifier<Ipvc> ipvcId, List<Uni> uniToCreate, String rd) {
+        // Create elan/vpn interfaces
+        for (Uni uni : uniToCreate) {
+            createInterfaces(vpnName, uni, ipvcId, rd);
+        }
+
         for (Uni uni : uniToCreate) {
             IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uni.getUniId(), uni.getIpUniId(),
                     LogicalDatastoreType.CONFIGURATION);
@@ -213,17 +306,7 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
                 return;
             }
             String vpnName = operIpvcVpn.getVpnId();
-            InstanceIdentifier<VpnInstance> vpnId = NetvirtVpnUtils.getVpnInstanceToVpnIdIdentifier(vpnName);
-            @SuppressWarnings("resource")
-            DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId, 10,
-                    LogicalDatastoreType.CONFIGURATION, vpn -> vpn.getVrfId());
-            if (!vpnInstanceWaiter.waitForData()) {
-                String errorMessage = String.format("Fail to wait for vrfId for vpn %s", vpnName);
-                Log.error(errorMessage);
-                throw new UnsupportedOperationException(errorMessage);
-            }
-            String rd = (String) vpnInstanceWaiter.getData();
-
+            String rd = (String) waitForRd(vpnName);
             List<Uni> originalUni = origIpvc.getUnis() != null && origIpvc.getUnis().getUni() != null
                     ? origIpvc.getUnis().getUni() : Collections.emptyList();
             List<Uni> updateUni = updateIpvc.getUnis() != null && updateIpvc.getUnis().getUni() != null
@@ -238,19 +321,13 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
             }
             List<Uni> uniToCreate = new ArrayList<>(updateUni);
             uniToCreate.removeAll(originalUni);
-
-            for (Uni uni : uniToCreate) {
-                createInterfaces(vpnName, uni, ipvcId, rd);
-            }
-            createUnis(ipvcId, uniToCreate);
-
+            createUnis(vpnName, ipvcId, uniToCreate, rd);
         } catch (final Exception e) {
             Log.error("Update ipvc failed !", e);
         }
     }
 
     private void createInterfaces(String vpnName, Uni uniInService, InstanceIdentifier<Ipvc> ipvcId, String rd) {
-
         WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
         String uniId = uniInService.getUniId().getValue();
         String ipUniId = uniInService.getIpUniId().getValue();
@@ -368,19 +445,12 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
     private void removeInterfaces(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn ipvcVpn, Uni uniInService, IpUni ipUni,
             WriteTransaction tx) {
         String uniId = uniInService.getUniId().getValue();
-        org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = MefInterfaceUtils
-                .getUni(dataBroker, uniId, LogicalDatastoreType.OPERATIONAL);
-        if (uni == null) {
-            String errorMessage = String.format("Couldn't find uni %s for ipvc", uniId);
-            Log.error(errorMessage);
-            throw new UnsupportedOperationException(errorMessage);
-        }
-
         String vpnName = ipvcVpn.getVpnId();
         VpnElans vpnElans = MefServicesUtils.findVpnElanForNetwork(new Identifier45(uniId), ipUni.getIpUniId(),
                 ipvcVpn);
         if (vpnElans == null) {
             Log.error("Trying to remome non-operational vpn/elan for Uni {} Ip-UNi {}", uniId, ipUni.getIpUniId());
+            return;
         }
 
         NetvirtVpnUtils.removeVpnInterfaceAdjacencies(dataBroker, vpnName, vpnElans.getElanPort());
index 0438618a053bf57d31b8d0260ecafb1b5d51b509..3c01deac33fd1b9aa571ced76daee27c0b5fe2cf 100644 (file)
@@ -22,6 +22,8 @@ import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.serv
 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.MefServiceKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.EvcChoice;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.IpvcChoice;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.Evc;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.Ipvc;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.Unis;
@@ -46,6 +48,11 @@ public class MefServicesUtils {
         return getMefServiceInstanceIdentifier().child(Evc.class);
     }
 
+    public static InstanceIdentifier<Evc> getEvcInstanceIdentifier(RetailSvcIdType svcId) {
+        return InstanceIdentifier.create(MefServices.class).child(MefService.class, new MefServiceKey(svcId))
+                .child(Evc.class);
+    }
+
     public static InstanceIdentifier<MefService> getMefServiceInstanceIdentifier() {
         return InstanceIdentifier.create(MefServices.class).child(MefService.class);
     }
@@ -55,10 +62,10 @@ public class MefServicesUtils {
     }
 
     public static InstanceIdentifier<Ipvc> getIpvcsInstanceIdentifier() {
-        return InstanceIdentifier.create(MefServices.class).child(MefService.class).child(Ipvc.class);
+        return getMefServiceInstanceIdentifier().child(Ipvc.class);
     }
 
-    public static InstanceIdentifier<Ipvc> getIpvcsInstanceIdentifier(RetailSvcIdType svcId) {
+    public static InstanceIdentifier<Ipvc> getIpvcInstanceIdentifier(RetailSvcIdType svcId) {
         return InstanceIdentifier.create(MefServices.class).child(MefService.class, new MefServiceKey(svcId))
                 .child(Ipvc.class);
     }
@@ -93,6 +100,24 @@ public class MefServicesUtils {
         return null;
     }
 
+    public static Ipvc getIpvc(DataBroker dataBroker, InstanceIdentifier<Ipvc> identifier) {
+        Optional<Ipvc> ipvcVpn = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, identifier);
+        if (ipvcVpn.isPresent()) {
+            return ipvcVpn.get();
+        } else {
+            return null;
+        }
+    }
+
+    public static Evc getEvc(DataBroker dataBroker, InstanceIdentifier<Evc> identifier) {
+        Optional<Evc> evcVpn = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, identifier);
+        if (evcVpn.isPresent()) {
+            return evcVpn.get();
+        } else {
+            return null;
+        }
+    }
+
     public static IpvcVpn getOperIpvcVpn(DataBroker dataBroker, InstanceIdentifier<Ipvc> identifier) {
         InstanceIdentifier<IpvcVpn> path = identifier.augmentation(IpvcVpn.class);
         Optional<IpvcVpn> ipvcVpn = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
@@ -200,4 +225,36 @@ public class MefServicesUtils {
         MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, path, ipvcVpnBuilder.build());
     }
 
+    public static List<RetailSvcIdType> getAllIpvcsServiceIds(DataBroker dataBroker) {
+        List<RetailSvcIdType> toReturn = new ArrayList<>();
+
+        InstanceIdentifier<MefServices> path = MefServicesUtils.getMefServicesInstanceIdentifier();
+        Optional<MefServices> mefServices = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
+        if (!mefServices.isPresent() || mefServices.get() == null) {
+            return toReturn;
+        }
+        for (MefService service : mefServices.get().getMefService()) {
+            if (service.getMefServiceChoice() instanceof IpvcChoice) {
+                toReturn.add(service.getSvcId());
+            }
+        }
+        return toReturn;
+    }
+
+    public static List<RetailSvcIdType> getAllEvcsServiceIds(DataBroker dataBroker) {
+        List<RetailSvcIdType> toReturn = new ArrayList<>();
+
+        InstanceIdentifier<MefServices> path = MefServicesUtils.getMefServicesInstanceIdentifier();
+        Optional<MefServices> mefServices = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
+        if (!mefServices.isPresent() || mefServices.get() == null) {
+            return toReturn;
+        }
+        for (MefService service : mefServices.get().getMefService()) {
+            if (service.getMefServiceChoice() instanceof EvcChoice) {
+                toReturn.add(service.getSvcId());
+            }
+        }
+        return toReturn;
+    }
+
 }
index 0b2136a77d6868d0a1f9112c43e6f3a843621bfa..be5f97601d55756e9cdce91485c55c9f5f5626af 100644 (file)
@@ -48,12 +48,15 @@ public class NodeConnectorListener extends UnimgrDataTreeChangeListener<FlowCapa
     private static final String BRIDGE_PREFIX = "br-";
     private static final String TUNNEL_PREFIX = "tun";
     private static final Logger log = LoggerFactory.getLogger(NodeConnectorListener.class);
+    private static boolean generateMac = false;
     private final UniPortManager uniPortManager;
     private ListenerRegistration<NodeConnectorListener> nodeConnectorListenerRegistration;
 
-    public NodeConnectorListener(final DataBroker dataBroker, final UniPortManager uniPortManager) {
+    public NodeConnectorListener(final DataBroker dataBroker, final UniPortManager uniPortManager,
+            final boolean generateMac) {
         super(dataBroker);
         this.uniPortManager = uniPortManager;
+        NodeConnectorListener.generateMac = generateMac;
         registerListener();
     }
 
@@ -63,6 +66,8 @@ public class NodeConnectorListener extends UnimgrDataTreeChangeListener<FlowCapa
                     LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
             nodeConnectorListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
             log.info("NodeConnectorListener created and registered");
+
+            configIntegrationBridge();
         } catch (final Exception e) {
             log.error("Node connector listener registration failed !", e);
             throw new IllegalStateException("Node connector listener registration failed.", e);
@@ -237,4 +242,16 @@ public class NodeConnectorListener extends UnimgrDataTreeChangeListener<FlowCapa
         String[] splits = interfaceName.split(":");
         return splits.length > 1 && (splits[1].startsWith(TUNNEL_PREFIX) || splits[1].startsWith(BRIDGE_PREFIX));
     }
+
+    private void configIntegrationBridge() {
+        if (generateMac == true) {// default for netvirt
+            return;
+        }
+
+        ElanConfigBuilder elanConfigBuilder = new ElanConfigBuilder();
+        elanConfigBuilder.setIntBridgeGenMac(false);
+        InstanceIdentifier<ElanConfig> id = InstanceIdentifier.builder(ElanConfig.class).build();
+
+        MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, id, elanConfigBuilder.build());
+    }
 }
index e4bbd8045e3097aa8b1156adc5c5f8ebf2d043b4..c403a79ff8c0ad1e4fb2dda1a4e40857ec9c0350 100644 (file)
@@ -317,7 +317,7 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
                 for (Uni uni : unis) {
                     if (uni.getUniId().equals(uniId) && uni.getIpUniId().equals(ipUniId)) {
                         Log.info("Find service {} for uni {} ipuni {}", service.getSvcId(), uniId, ipUniId);
-                        return MefServicesUtils.getIpvcsInstanceIdentifier(service.getSvcId());
+                        return MefServicesUtils.getIpvcInstanceIdentifier(service.getSvcId());
                     }
                 }
             }
diff --git a/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/UniAwareListener.java b/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/UniAwareListener.java
new file mode 100644 (file)
index 0000000..3e03ae6
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+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.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;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UniAwareListener extends UnimgrDataTreeChangeListener<Uni> {
+    private static final Logger Log = LoggerFactory.getLogger(UniAwareListener.class);
+    private ListenerRegistration<UniAwareListener> uniListenerRegistration;
+    IUniAwareService serviceSubscribe;
+
+    public UniAwareListener(final DataBroker dataBroker, final IUniAwareService serviceSubscribe) {
+        super(dataBroker);
+        this.serviceSubscribe = serviceSubscribe;
+        registerListener();
+    }
+
+    public void registerListener() {
+        try {
+            final DataTreeIdentifier<Uni> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                    MefInterfaceUtils.getUniListInstanceIdentifier());
+            uniListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
+            Log.info("UniAwareListener created and registered for service {}", serviceSubscribe);
+        } catch (final Exception e) {
+            Log.error("UniAwareListener registration failed !", e);
+            throw new IllegalStateException("UniAwareListener failed.", e);
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        uniListenerRegistration.close();
+    }
+
+    @Override
+    public void add(DataTreeModification<Uni> newDataObject) {
+        if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
+            Log.info("Uni {} is operational", newDataObject.getRootNode().getIdentifier());
+            // Uni Id is same in interface and service
+            serviceSubscribe.connectUni(newDataObject.getRootNode().getDataAfter().getUniId().getValue());
+        }
+    }
+
+    @Override
+    public void remove(DataTreeModification<Uni> removedDataObject) {
+        if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
+            Log.info("Remove Uni {} from operational", removedDataObject.getRootNode().getIdentifier());
+            // Uni Id is same in interface and service
+            serviceSubscribe.disconnectUni(removedDataObject.getRootNode().getDataBefore().getUniId().getValue());
+        }
+    }
+
+    @Override
+    public void update(DataTreeModification<Uni> modifiedDataObject) {
+    }
+}
index 15f204426ada5e8b71708ba5547627d79a2b8cf4..1bfc599853c31faade4deb3b9e31dc77a4a1490d 100644 (file)
@@ -333,7 +333,7 @@ public class UniPortManager extends UnimgrDataTreeChangeListener<Uni> implements
     @Override
     public void removeCeVlan(String uniId, Long vlanId) {
         if (getUniVlanInterfaceNoRetry(uniId, vlanId) == null) {
-            log.debug("No UNI {} Port for vlan {} exists already, nothing to delete", uniId, vlanId);
+            log.debug("No UNI {} Port for vlan {} dosn't exist already, nothing to delete", uniId, vlanId);
             return;
         }
         synchronized (uniId.intern()) {
@@ -400,4 +400,9 @@ public class UniPortManager extends UnimgrDataTreeChangeListener<Uni> implements
             return getUniVlanInterfaceRetry(uniId, vlanId, ++retries);
         }
     }
+
+    @Override
+    public String getUniVlanInterfaceName(String uniId, Long vlanId) {
+        return MefInterfaceUtils.getInterfaceNameForVlan(uniId, null);
+    }
 }
index 5d259018db137fa2193af059f42260156090b36b..51c330b0e351902165fb140b3959b25bfc7275b2 100644 (file)
@@ -23,6 +23,7 @@
                class="org.opendaylight.unimgr.mef.netvirt.NodeConnectorListener">
                <argument ref="dataBroker" />
                <argument ref="uniPortManager" />
+               <argument value="true" />
        </bean>
 
        <bean id="evcListener" class="org.opendaylight.unimgr.mef.netvirt.EvcListener">