Update profile listener 18/52818/1
authorKonsta Pozdeev <konsta.pozdeev@hpe.com>
Sun, 8 Jan 2017 15:59:56 +0000 (17:59 +0200)
committerKonsta Pozdeev <konsta.pozdeev@hpe.com>
Sun, 5 Mar 2017 09:37:44 +0000 (11:37 +0200)
Change-Id: I9f1a7aa09320a1c03707c773606c2ba04ed87f5e
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/IpvcListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/UniQosManager.java

index ee5dcab5a94fd803e9791f24f712729ad2c5cc87..2a5ef802bb8abf92811928a9692337435d5f00b8 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.Identifier45;
 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;
@@ -191,7 +192,8 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> implements IU
             InstanceIdentifier<Evc> evcId = newDataObject.getRootPath().getRootIdentifier();
 
             synchronized (instanceName.intern()) {
-                NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree, data.getSegmentationId(), data.getMacTimeout());
+                NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree, data.getSegmentationId(),
+                        data.getMacTimeout());
 
                 // Create interfaces
                 if (data.getUnis() == null) {
@@ -247,8 +249,11 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> implements IU
 
             List<Uni> originalUni = original.getUnis() != null && original.getUnis().getUni() != null
                     ? original.getUnis().getUni() : Collections.emptyList();
+            List<Identifier45> originalUniIds = originalUni.stream().map(u -> u.getUniId())
+                    .collect(Collectors.toList());
             List<Uni> updateUni = update.getUnis() != null && update.getUnis().getUni() != null
                     ? update.getUnis().getUni() : Collections.emptyList();
+            List<Identifier45> updateUniIds = updateUni.stream().map(u -> u.getUniId()).collect(Collectors.toList());
 
             synchronized (original.getEvcId().getValue().intern()) {
 
@@ -258,18 +263,23 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> implements IU
 
                 // Changed Uni will be deleted / recreated
                 List<Uni> uniToRemove = new ArrayList<>(originalUni);
-                uniToRemove.removeAll(updateUni);
+                uniToRemove.removeIf(u -> updateUniIds.contains(u.getUniId()));
                 for (Uni uni : uniToRemove) {
                     removeUniElanInterfaces(evcId, instanceName, uni);
                 }
                 updateQos(uniToRemove);
 
                 List<Uni> uniToCreate = new ArrayList<>(updateUni);
+                uniToCreate.removeIf(u -> originalUniIds.contains(u.getUniId()));
                 uniToCreate.removeAll(originalUni);
                 for (Uni uni : uniToCreate) {
                     createUniElanInterfaces(evcId, instanceName, uni, isEtree);
                 }
                 updateQos(uniToCreate);
+
+                List<Uni> uniToUpdate = new ArrayList<>(updateUni);
+                uniToUpdate.removeIf(u -> !originalUniIds.contains(u.getUniId()));
+                updateUnis(uniToUpdate);
             }
         } catch (final Exception e) {
             log.error("Update evc failed !", e);
@@ -459,4 +469,8 @@ public class EvcListener extends UnimgrDataTreeChangeListener<Evc> implements IU
         uniToUpdate.forEach(u -> uniQosManager.setUniBandwidthLimits(u.getUniId()));
     }
 
+    private void updateUnis(List<Uni> uniToUpdate) {
+        uniToUpdate.forEach(u -> uniQosManager.updateUni(u.getUniId(), u.getIngressBwProfile()));
+        updateQos(uniToUpdate);
+    }
 }
index 9c8a773f0efb4a19866fd3362f571a45ded2c318..6e8a7fee7d983c98140665fac76c841d06efb6c6 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.unimgr.mef.netvirt;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
@@ -317,19 +318,27 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
             String rd = waitForRd(vpnName);
             List<Uni> originalUni = origIpvc.getUnis() != null && origIpvc.getUnis().getUni() != null
                     ? origIpvc.getUnis().getUni() : Collections.emptyList();
+            List<Identifier45> originalUniIds = originalUni.stream().map(u -> u.getUniId())
+                    .collect(Collectors.toList());
             List<Uni> updateUni = updateIpvc.getUnis() != null && updateIpvc.getUnis().getUni() != null
                     ? updateIpvc.getUnis().getUni() : Collections.emptyList();
+            List<Identifier45> updateUniIds = updateUni.stream().map(u -> u.getUniId()).collect(Collectors.toList());
 
             synchronized (vpnName.intern()) {
                 WriteTransaction txRemove = MdsalUtils.createTransaction(dataBroker);
                 List<Uni> uniToRemove = new ArrayList<>(originalUni);
-                uniToRemove.removeAll(updateUni);
+                uniToRemove.removeIf(u -> updateUniIds.contains(u.getUniId()));
                 removeUnis(ipvcId, operIpvcVpn, uniToRemove, txRemove);
                 MdsalUtils.commitTransaction(txRemove);
             }
             List<Uni> uniToCreate = new ArrayList<>(updateUni);
-            uniToCreate.removeAll(originalUni);
+            uniToCreate.removeIf(u -> originalUniIds.contains(u.getUniId()));
             createUnis(vpnName, ipvcId, uniToCreate, rd);
+
+            List<Uni> uniToUpdate = new ArrayList<>(updateUni);
+            uniToUpdate.removeIf(u -> !originalUniIds.contains(u.getUniId()));
+            updateUnis(uniToUpdate);
+
         } catch (final Exception e) {
             Log.error("Update ipvc failed !", e);
         }
@@ -481,4 +490,9 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
     private void updateQos(List<Uni> uniToUpdate) {
         uniToUpdate.forEach(u -> uniQosManager.setUniBandwidthLimits(u.getUniId()));
     }
+
+    private void updateUnis(List<Uni> uniToUpdate) {
+        uniToUpdate.forEach(u -> uniQosManager.updateUni(u.getUniId(), u.getIngressBwProfile()));
+        updateQos(uniToUpdate);
+    }
 }
index 511aeed51f42017bb4d448306f02658ef506ea1b..19751bb1a43374f47ab303313bbf2231ee77200a 100644 (file)
@@ -10,17 +10,21 @@ package org.opendaylight.unimgr.mef.netvirt;
 
 import com.google.common.base.Optional;
 
-import jline.internal.Log;
-
 import java.math.BigInteger;
 import java.util.Iterator;
+import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+
 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.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
+import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.global.rev150526.MefGlobal;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.global.rev150526.mef.global.Profiles;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.global.rev150526.mef.global.bwp.flows.group.BwpFlow;
@@ -45,62 +49,142 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class UniQosManager {
-    private static final Logger LOG = LoggerFactory.getLogger(UniQosManager.class);
+public class UniQosManager extends UnimgrDataTreeChangeListener<BwpFlow> {
+    private static final Logger Log = LoggerFactory.getLogger(UniQosManager.class);
     private OdlInterfaceRpcService odlInterfaceRpcService;
     private DataBroker dataBroker;
     private final Long noLimit = 0l;
+    private final static String noProfile = "";
+    private ListenerRegistration<UniQosManager> bwListenerRegistration;
+
 
     // key in first map is uniId, key in second map is logical portId
     private ConcurrentHashMap<String, ConcurrentHashMap<String, BandwidthLimits>> uniPortBandwidthLimits;
 
     // map of current values per uni
     private ConcurrentHashMap<String, BandwidthLimits> uniBandwidthLimits;
-    
+
     private ConcurrentHashMap<String, BigInteger> uniToDpn;
 
     public UniQosManager(final DataBroker dataBroker, OdlInterfaceRpcService odlInterfaceRpcService) {
+        super(dataBroker);
+
         this.dataBroker = dataBroker;
         this.odlInterfaceRpcService = odlInterfaceRpcService;
         this.uniPortBandwidthLimits = new ConcurrentHashMap<>();
         this.uniBandwidthLimits = new ConcurrentHashMap<>();
         this.uniToDpn = new ConcurrentHashMap<>();
+        registerListener();
     }
 
-    public void mapUniPortBandwidthLimits(String uniId, String portId, Long maxKbps, Long maxBurstKb) {
-        Log.info("Record rate limits for Uni {} port {} maxKbps {} maxBurstKb {}", uniId, portId, maxKbps, maxBurstKb);
-        uniPortBandwidthLimits.putIfAbsent(uniId, new ConcurrentHashMap<>());
-        ConcurrentHashMap<String, BandwidthLimits> uniMap = uniPortBandwidthLimits.get(uniId);
-        uniMap.put(portId, new BandwidthLimits(maxKbps, maxBurstKb));
+    public void registerListener() {
+        try {
+            final DataTreeIdentifier<BwpFlow> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+                    getBwFlowsInstanceIdentifier());
+            bwListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
+            Log.info("UniQosManager created and registered");
+        } catch (final Exception e) {
+            Log.error("UniQosManager DataChange listener registration failed !", e);
+            throw new IllegalStateException("UniQosManager registration Listener failed.", e);
+        }
     }
 
-    public void mapUniPortBandwidthLimits(String uniId, String portId, Identifier45 bwProfile) {
+    public synchronized void mapUniPortBandwidthLimits(String uniId, String portId, Identifier45 bwProfile) {
         Long maxKbps = noLimit;
         Long maxBurstKb = noLimit;
         if (bwProfile != null) {
-
             Optional<BwpFlow> bwFlowOp = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
                     getBwFlowInstanceIdentifier(bwProfile));
             if (!bwFlowOp.isPresent()) {
                 Log.trace("Can't read bw profile {} for Uni {}", bwProfile, uniId);
-                return;
+            } else {
+                // Kb per second
+                maxKbps = bwFlowOp.get().getCir().getValue();
+                // burst in bytes, ovs requires in Kb
+                maxBurstKb = bwFlowOp.get().getCbs().getValue() * 8 / 1024;
+                Log.info("Record rate limits for Uni {} Profile {}", uniId, bwProfile);
             }
-            // Kb per second
-            maxKbps = bwFlowOp.get().getCir().getValue();
-            // burst in bytes, ovs requires in Kb
-            maxBurstKb = bwFlowOp.get().getCbs().getValue() * 8 / 1024;
-            Log.info("Record rate limits for Uni {} Profile {}", uniId, bwProfile);
         }
-        mapUniPortBandwidthLimits(uniId, portId, maxKbps, maxBurstKb);
+
+        mapUniPortBandwidthLimits(uniId, portId, maxKbps, maxBurstKb, replaceNull(bwProfile));
     }
 
-    public void unMapUniPortBandwidthLimits(String uniId, String portId) {
-        Log.debug("Delete rate limits for Uni {} port {}", uniId, portId);
+    private synchronized void mapUniPortBandwidthLimits(String uniId, String portId, Long maxKbps, Long maxBurstKb,
+            String profileName) {
+        Log.info("Record rate limits for Uni {} port {} maxKbps {} maxBurstKb {}", uniId, portId, maxKbps, maxBurstKb);
+        uniPortBandwidthLimits.putIfAbsent(uniId, new ConcurrentHashMap<>());
+        ConcurrentHashMap<String, BandwidthLimits> uniMap = uniPortBandwidthLimits.get(uniId);
+        uniMap.put(portId, new BandwidthLimits(maxKbps, maxBurstKb, profileName));
+    }
+
+    public void updateUni(Identifier45 uniId, Identifier45 bwProfile) {
+        String bwProfileSafe = replaceNull(bwProfile);
+        Log.info("Update rate limits for Uni {}", uniId.getValue());
+        ConcurrentHashMap<String, BandwidthLimits> uniMap = uniPortBandwidthLimits.get(uniId.getValue());
+        if (uniMap == null) {
+            Log.error("Trying to update limits for non-exsting uni {}", uniId.getValue());
+            return;
+        }
+        for (String portName : uniMap.keySet()) {
+            if (uniMap.get(portName).getProfileName().equals(bwProfileSafe)) {
+                continue;
+            }
+            if (bwProfile != null) {
+                mapUniPortBandwidthLimits(uniId.getValue(), portName, new Identifier45(bwProfileSafe));
+            } else {
+                unMapUniPortBandwidthLimits(uniId.getValue(), portName);
+            }
+        }
+    }
+
+    private void updateProfile(Identifier45 bwProfile) {
+        Log.info("Update rate limits for profile {}", bwProfile);
+        List<String> unisWithProfile = uniBandwidthLimits.entrySet().stream()
+                .filter(m -> m.getValue().profileName.equals(bwProfile.getValue())).map(m -> m.getKey())
+                .collect(Collectors.toList());
+
+        for (String uniId : unisWithProfile) {
+            ConcurrentHashMap<String, BandwidthLimits> uniMap = uniPortBandwidthLimits.get(uniId);
+            uniMap.forEach((k, v) -> {
+                mapUniPortBandwidthLimits(uniId, k, bwProfile);
+            });
+        }
+
+        for (String uniId : unisWithProfile) {
+            setUniBandwidthLimits(uniId);
+        }
+    }
+
+    public void deleteProfile(Identifier45 bwProfile) {
+        Log.info("Delete rate limits for profile {}", bwProfile);
+        List<String> unisWithProfile = uniBandwidthLimits.entrySet().stream()
+                .filter(m -> m.getValue().profileName.equals(bwProfile.getValue())).map(m -> m.getKey())
+                .collect(Collectors.toList());
+
+        for (String uniId : unisWithProfile) {
+            ConcurrentHashMap<String, BandwidthLimits> uniMap = uniPortBandwidthLimits.get(uniId);
+            uniMap.forEach((k, v) -> {
+                unMapUniPortBandwidthLimits(uniId, k, bwProfile.getValue());
+            });
+        }
+
+        for (String uniId : unisWithProfile) {
+            setUniBandwidthLimits(uniId);
+        }
+    }
+
+    public synchronized void unMapUniPortBandwidthLimits(String uniId, String portId) {
+        unMapUniPortBandwidthLimits(uniId, portId, noProfile);
+    }
+
+    public synchronized void unMapUniPortBandwidthLimits(String uniId, String portId, String profileTosave) {
+        Log.info("Delete rate limits for Uni {} port {}", uniId, portId);
         ConcurrentHashMap<String, BandwidthLimits> uniMap = uniPortBandwidthLimits.get(uniId);
         if (uniMap == null) {
             Log.error("Trying to delete limits for non-exsting uni {}", uniId);
@@ -108,12 +192,16 @@ public class UniQosManager {
         }
         uniMap.remove(portId);
         if (uniMap.isEmpty()) {
-            uniMap.put(portId, new BandwidthLimits(noLimit, noLimit));
+            uniMap.put(portId, new BandwidthLimits(noLimit, noLimit, profileTosave));
         }
     }
 
     public void setUniBandwidthLimits(Identifier45 uniIden) {
         String uniId = uniIden.getValue();
+        setUniBandwidthLimits(uniId);
+    }
+
+    private synchronized void setUniBandwidthLimits(String uniId) {
         if (!uniPortBandwidthLimits.containsKey(uniId)) {
             Log.debug("Uni {} doesn't have rate limits configured", uniId);
             return;
@@ -139,11 +227,12 @@ public class UniQosManager {
             ConcurrentHashMap<String, BandwidthLimits> uniLimits) {
         Long sumOfRate = noLimit;
         Long sumOfBurst = noLimit;
+        String profileName = noProfile;
         Boolean hasNullRate = false;
         Boolean hasNullBurst = false;
 
         if (uniLimits == null || uniLimits.keySet() == null) {
-            return new BandwidthLimits(sumOfRate, sumOfBurst);
+            return new BandwidthLimits(sumOfRate, sumOfBurst, profileName);
         }
 
         for (BandwidthLimits v : uniLimits.values()) {
@@ -156,7 +245,7 @@ public class UniQosManager {
             }
             sumOfRate = sumOfRate + v.maxKbps;
             sumOfBurst = sumOfBurst + v.maxBurstKb;
-
+            profileName = v.profileName;
         }
         if (hasNullRate) {
             sumOfRate = noLimit;
@@ -164,21 +253,21 @@ public class UniQosManager {
         } else if (hasNullBurst) {
             sumOfBurst = noLimit;
         }
-        return new BandwidthLimits(sumOfRate, sumOfBurst);
+        return new BandwidthLimits(sumOfRate, sumOfBurst, profileName);
     }
 
     private void setPortBandwidthLimits(String uniId, String logicalPortId, Long maxKbps, Long maxBurstKb) {
-        LOG.trace("Setting bandwidth limits {} {} on Port {}", maxKbps, maxBurstKb, logicalPortId);
+        Log.info("Setting bandwidth limits {} {} on Port {}", maxKbps, maxBurstKb, logicalPortId);
 
         BigInteger dpId = BigInteger.ZERO;
-        if(uniToDpn.containsKey(uniId)) {
+        if (uniToDpn.containsKey(uniId)) {
             dpId = uniToDpn.get(uniId);
-        } else {        
+        } else {
             dpId = getDpnForInterface(odlInterfaceRpcService, logicalPortId);
             uniToDpn.put(uniId, dpId);
         }
         if (dpId.equals(BigInteger.ZERO)) {
-            LOG.error("DPN ID for interface {} not found", logicalPortId);
+            Log.error("DPN ID for interface {} not found", logicalPortId);
             return;
         }
 
@@ -186,19 +275,19 @@ public class UniQosManager {
         Optional<Node> bridgeNode = MDSALUtil.read(LogicalDatastoreType.OPERATIONAL,
                 bridgeRefEntry.getValue().firstIdentifierOf(Node.class), dataBroker);
         if (bridgeNode == null) {
-            LOG.error("Bridge ref for interface {} not found", logicalPortId);
+            Log.error("Bridge ref for interface {} not found", logicalPortId);
             return;
         }
 
         String physicalPort = getPhysicalPortForUni(dataBroker, uniId);
         if (physicalPort == null) {
-            LOG.error("Physical port for interface {} not found", logicalPortId);
+            Log.error("Physical port for interface {} not found", logicalPortId);
             return;
         }
 
         TerminationPoint tp = getTerminationPoint(bridgeNode.get(), physicalPort);
         if (tp == null) {
-            LOG.error("Termination point for port {} not found", physicalPort);
+            Log.error("Termination point for port {} not found", physicalPort);
             return;
         }
 
@@ -238,10 +327,10 @@ public class UniQosManager {
             if (dpIdResult.isSuccessful()) {
                 nodeId = dpIdResult.getResult().getDpid();
             } else {
-                LOG.error("Could not retrieve DPN Id for interface {}", ifName);
+                Log.error("Could not retrieve DPN Id for interface {}", ifName);
             }
         } catch (NullPointerException | InterruptedException | ExecutionException e) {
-            LOG.error("Exception when getting dpn for interface {}", ifName, e);
+            Log.error("Exception when getting dpn for interface {}", ifName, e);
         }
         return nodeId;
     }
@@ -253,7 +342,7 @@ public class UniQosManager {
             String parentInterfaceName = MefInterfaceUtils.getTrunkParentName(link);
             return parentInterfaceName.split(":")[1];
         } catch (Exception e) {
-            LOG.error("Exception when getting physical port for Uni {}", uniId, e);
+            Log.error("Exception when getting physical port for Uni {}", uniId, e);
         }
         return nodeId;
     }
@@ -288,13 +377,21 @@ public class UniQosManager {
         return bwProfileInstanceIdentifierBuilder.build();
     }
 
+    private static InstanceIdentifier<BwpFlow> getBwFlowsInstanceIdentifier() {
+        InstanceIdentifier.InstanceIdentifierBuilder<BwpFlow> bwProfileInstanceIdentifierBuilder = InstanceIdentifier
+                .builder(MefGlobal.class).child(Profiles.class).child(IngressBwpFlows.class).child(BwpFlow.class);
+        return bwProfileInstanceIdentifierBuilder.build();
+    }
+
     private class BandwidthLimits {
         private final Long maxKbps;
         private final Long maxBurstKb;
+        private final String profileName;
 
-        public BandwidthLimits(Long maxKbps, Long maxBurstKb) {
+        public BandwidthLimits(Long maxKbps, Long maxBurstKb, String profileName) {
             this.maxKbps = replaceNull(maxKbps);
             this.maxBurstKb = replaceNull(maxBurstKb);
+            this.profileName = profileName;
         }
 
         public Long getMaxKbps() {
@@ -305,6 +402,10 @@ public class UniQosManager {
             return maxBurstKb;
         }
 
+        public String getProfileName() {
+            return profileName;
+        }
+
         private Long replaceNull(Long value) {
             return (value == null) ? Long.valueOf(0) : value;
         }
@@ -342,4 +443,37 @@ public class UniQosManager {
             return UniQosManager.this;
         }
     }
+
+    private static String replaceNull(Identifier45 value) {
+        return (value == null) ? noProfile : value.getValue();
+    }
+
+    @Override
+    public void close() throws Exception {
+        bwListenerRegistration.close();
+    }
+
+    @Override
+    public void add(DataTreeModification<BwpFlow> newDataObject) {
+        if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
+            Log.info("bw profile {} created", newDataObject.getRootNode().getIdentifier());
+            updateProfile(newDataObject.getRootNode().getDataAfter().getBwProfile());
+        }
+    }
+
+    @Override
+    public void remove(DataTreeModification<BwpFlow> removedDataObject) {
+        if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
+            Log.info("bw profile {} deleted", removedDataObject.getRootNode().getIdentifier());
+            deleteProfile(removedDataObject.getRootNode().getDataBefore().getBwProfile());
+        }
+    }
+
+    @Override
+    public void update(DataTreeModification<BwpFlow> modifiedDataObject) {
+        if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
+            Log.info("bw profile {} modified", modifiedDataObject.getRootNode().getIdentifier());
+            updateProfile(modifiedDataObject.getRootNode().getDataAfter().getBwProfile());
+        }
+    }
 }