add acl support to unimgr
[unimgr.git] / netvirt / src / main / java / org / opendaylight / unimgr / mef / netvirt / EvcListener.java
1 /*
2  * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.unimgr.mef.netvirt;
10
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.stream.Collectors;
15
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
18 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
19 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
22 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
23 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.Evc;
24 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.UniKey;
26 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.uni.EvcUniCeVlans;
27 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.uni.evc.uni.ce.vlans.EvcUniCeVlan;
28 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.EvcElan;
29 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.EvcElanBuilder;
30 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.ElanPorts;
31 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.ElanPortsBuilder;
32
33 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcType;
34 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcUniRoleType;
35 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
36 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.RetailSvcIdType;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
38 import org.opendaylight.yangtools.concepts.ListenerRegistration;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 import com.google.common.base.Optional;
44
45 import jline.internal.Log;
46
47 public class EvcListener extends UnimgrDataTreeChangeListener<Evc> implements IUniAwareService {
48
49     private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
50     private ListenerRegistration<EvcListener> evcListenerRegistration;
51     private final IUniPortManager uniPortManager;
52     private final UniQosManager uniQosManager;
53     @SuppressWarnings("unused")
54     private final UniAwareListener uniAwareListener;
55
56     public EvcListener(final DataBroker dataBroker, final UniPortManager uniPortManager,
57             final UniQosManager uniQosManager) {
58         super(dataBroker);
59         this.uniPortManager = uniPortManager;
60         this.uniQosManager = uniQosManager;
61         this.uniAwareListener = new UniAwareListener(dataBroker, this);
62         registerListener();
63     }
64
65     public void registerListener() {
66         try {
67             final DataTreeIdentifier<Evc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
68                     MefServicesUtils.getEvcsInstanceIdentifier());
69             evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
70             log.info("EvcDataTreeChangeListener created and registered");
71         } catch (final Exception e) {
72             log.error("Evc DataChange listener registration failed !", e);
73             throw new IllegalStateException("Evc registration Listener failed.", e);
74         }
75     }
76
77     @Override
78     public void close() throws Exception {
79         evcListenerRegistration.close();
80     }
81
82     @Override
83     public void add(DataTreeModification<Evc> newDataObject) {
84         if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
85             log.info("evc {} created", newDataObject.getRootNode().getIdentifier());
86             addEvc(newDataObject);
87         }
88     }
89
90     @Override
91     public void remove(DataTreeModification<Evc> removedDataObject) {
92         if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
93             log.info("evc {} deleted", removedDataObject.getRootNode().getIdentifier());
94             removeEvc(removedDataObject);
95         }
96     }
97
98     @Override
99     public void update(DataTreeModification<Evc> modifiedDataObject) {
100         if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
101             log.info("evc {} updated", modifiedDataObject.getRootNode().getIdentifier());
102             updateEvc(modifiedDataObject);
103         }
104     }
105
106     @Override
107     public void connectUni(String uniId) {
108         List<RetailSvcIdType> allEvcs = MefServicesUtils.getAllEvcsServiceIds(dataBroker);
109         allEvcs = allEvcs != null ? allEvcs : Collections.emptyList();
110
111         for (RetailSvcIdType evcSerId : allEvcs) {
112             InstanceIdentifier<Evc> evcId = MefServicesUtils.getEvcInstanceIdentifier(evcSerId);
113             Evc evc = MefServicesUtils.getEvc(dataBroker, evcId);
114             if (evc == null) {
115                 Log.error("Inconsistent data for svcId {}", evcSerId);
116                 continue;
117             }
118
119             String instanceName = evc.getEvcId().getValue();
120             boolean isEtree = evc.getEvcType() == EvcType.RootedMultipoint;
121
122             List<Uni> toConnect = new ArrayList<>();
123             List<Uni> unis = evc.getUnis() != null ? evc.getUnis().getUni() : null;
124             unis = unis != null ? unis : Collections.emptyList();
125             for (Uni uni : unis) {
126                 if (uni.getUniId().getValue().equals(uniId)) {
127                     Log.info("Connecting Uni {} to svc id {}", uniId, evcSerId);
128                     toConnect.add(uni);
129                     break;
130                 }
131             }
132
133             EvcElan evcElan = getOperEvcElan(evcId);
134             if (evcElan == null) {
135                 NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree, evc.getSegmentationId());
136                 evcElan = getOperEvcElan(evcId);
137                 if (evcElan == null) {
138                     log.error("Evc {} has not been created as required. Nothing to reconnect", evcId);
139                     return;
140                 }
141             }
142
143             for (Uni uni : toConnect) {
144                 createUniElanInterfaces(evcId, instanceName, uni, isEtree);
145             }
146             updateQos(toConnect);
147         }
148     }
149
150     @Override
151     public void disconnectUni(String uniId) {
152         List<RetailSvcIdType> allEvcs = MefServicesUtils.getAllEvcsServiceIds(dataBroker);
153         allEvcs = allEvcs != null ? allEvcs : Collections.emptyList();
154
155         for (RetailSvcIdType evcSerId : allEvcs) {
156             InstanceIdentifier<Evc> evcId = MefServicesUtils.getEvcInstanceIdentifier(evcSerId);
157             Evc evc = MefServicesUtils.getEvc(dataBroker, evcId);
158             if (evc == null) {
159                 Log.error("Inconsistent data for svcId {}", evcSerId);
160                 continue;
161             }
162
163             String instanceName = evc.getEvcId().getValue();
164             List<Uni> toDisconnect = new ArrayList<>();
165             List<Uni> unis = evc.getUnis() != null ? evc.getUnis().getUni() : null;
166             unis = unis != null ? unis : Collections.emptyList();
167             for (Uni uni : unis) {
168                 if (uni.getUniId().getValue().equals(uniId)) {
169                     Log.info("Disconnecting Uni {} from svc id {}", uniId, evcSerId);
170                     toDisconnect.add(uni);
171                     break;
172                 }
173             }
174
175             EvcElan evcElan = getOperEvcElan(evcId);
176             if (evcElan == null) {
177                 log.error("Evc {} has not been created as required. Nothing to disconnect", evcId);
178                 return;
179             }
180
181             updateQos(toDisconnect);
182             for (Uni uni : toDisconnect) {
183                 removeUniElanInterfaces(evcId, instanceName, uni);
184             }
185         }
186
187     }
188
189     private void addEvc(DataTreeModification<Evc> newDataObject) {
190         try {
191             Evc data = newDataObject.getRootNode().getDataAfter();
192             String instanceName = data.getEvcId().getValue();
193             boolean isEtree = data.getEvcType() == EvcType.RootedMultipoint;
194             InstanceIdentifier<Evc> evcId = newDataObject.getRootPath().getRootIdentifier();
195
196             synchronized (instanceName.intern()) {
197                 NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree, data.getSegmentationId(),
198                         data.getMacTimeout());
199
200                 // Create interfaces
201                 if (data.getUnis() == null) {
202                     log.info("No UNI's in service {}, exiting", instanceName);
203                     return;
204                 }
205                 for (Uni uni : data.getUnis().getUni()) {
206                     createUniElanInterfaces(evcId, instanceName, uni, isEtree);
207                 }
208                 updateQos(data.getUnis().getUni());
209             }
210         } catch (final Exception e) {
211             log.error("Add evc failed !", e);
212         }
213     }
214
215     private void removeEvc(DataTreeModification<Evc> removedDataObject) {
216         try {
217             Evc data = removedDataObject.getRootNode().getDataBefore();
218             InstanceIdentifier<Evc> evcId = removedDataObject.getRootPath().getRootIdentifier();
219             List<Uni> uniToRemove = data.getUnis() != null && data.getUnis().getUni() != null ? data.getUnis().getUni()
220                     : Collections.emptyList();
221
222             synchronized (data.getEvcId().getValue().intern()) {
223                 updateQos(uniToRemove);
224                 EvcElan evcElan = getOperEvcElan(evcId);
225                 if (evcElan == null) {
226                     log.error("Evc {} has not been created as required. Nothing to remove", data.getEvcId().getValue());
227                     return;
228                 }
229
230                 String instanceName = evcElan.getElanId();
231
232                 for (Uni uni : uniToRemove) {
233                     removeUniElanInterfaces(evcId, instanceName, uni);
234                 }
235
236                 log.info("Removing elan instance: " + instanceName);
237                 NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
238                 removeOperEvcElan(evcId);
239             }
240         } catch (final Exception e) {
241             log.error("Remove evc failed !", e);
242         }
243     }
244
245     private void updateEvc(DataTreeModification<Evc> modifiedDataObject) {
246         InstanceIdentifier<Evc> evcId = modifiedDataObject.getRootPath().getRootIdentifier();
247
248         try {
249             Evc original = modifiedDataObject.getRootNode().getDataBefore();
250             Evc update = modifiedDataObject.getRootNode().getDataAfter();
251
252             List<Uni> originalUni = original.getUnis() != null && original.getUnis().getUni() != null
253                     ? original.getUnis().getUni() : Collections.emptyList();
254             List<UniKey> originalUniIds = originalUni.stream().map(u -> u.getKey())
255                     .collect(Collectors.toList());
256             List<Uni> updateUni = update.getUnis() != null && update.getUnis().getUni() != null
257                     ? update.getUnis().getUni() : Collections.emptyList();
258             List<UniKey> updateUniIds = updateUni.stream().map(u -> u.getKey()).collect(Collectors.toList());
259
260             synchronized (original.getEvcId().getValue().intern()) {
261
262                 String instanceName = original.getEvcId().getValue();
263                 boolean isEtree = update.getEvcType() == EvcType.RootedMultipoint;
264                 log.info("Updating {} instance: {}", isEtree ? "etree" : "elan", instanceName);
265
266                 // Changed Uni will be deleted / recreated
267                 List<Uni> uniToRemove = new ArrayList<>(originalUni);
268                 uniToRemove.removeIf(u -> updateUniIds.contains(u.getKey()));
269                 for (Uni uni : uniToRemove) {
270                     removeUniElanInterfaces(evcId, instanceName, uni);
271                 }
272                 updateQos(uniToRemove);
273
274                 List<Uni> uniToCreate = new ArrayList<>(updateUni);
275                 uniToCreate.removeIf(u -> originalUniIds.contains(u.getKey()));
276                 uniToCreate.removeAll(originalUni);
277                 for (Uni uni : uniToCreate) {
278                     createUniElanInterfaces(evcId, instanceName, uni, isEtree);
279                 }
280                 updateQos(uniToCreate);
281
282                 List<Uni> uniToUpdate = new ArrayList<>(updateUni);
283                 uniToUpdate.removeIf(u -> !originalUniIds.contains(u.getKey()));
284                 updateUnis(uniToUpdate);
285             }
286         } catch (final Exception e) {
287             log.error("Update evc failed !", e);
288         }
289     }
290
291     private void createUniElanInterfaces(InstanceIdentifier<Evc> evcId, String instanceName, Uni uni, boolean isEtree) {
292         EvcUniRoleType role = uni.getRole();
293         EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
294
295         List<EvcUniCeVlan> evcUniCeVlan = evcUniCeVlans != null && evcUniCeVlans.getEvcUniCeVlan() != null
296                 && !evcUniCeVlans.getEvcUniCeVlan().isEmpty() ? evcUniCeVlans.getEvcUniCeVlan()
297                         : Collections.emptyList();
298
299         for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
300             Long vlan = safeCastVlan(ceVlan.getVid());
301             uniPortManager.addCeVlan(uni.getUniId().getValue(), vlan);
302         }
303
304         if (evcUniCeVlan.isEmpty()) {
305             String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), Long.valueOf(0));
306             if (interfaceName == null) {
307                 String errorMessage = String.format("Uni %s Interface for vlan %d is not operational ", uni.getUniId(),
308                         0);
309                 Log.error(errorMessage);
310                 throw new UnsupportedOperationException(errorMessage);
311             }
312             if (isOperEvcElanPort(evcId, interfaceName)) {
313                 log.info("elan interface for elan {} vlan {} interface {} exists already", instanceName, 0,
314                         interfaceName);
315                 return;
316             }
317             log.info("Creting elan interface for elan {} vlan {} interface {}", instanceName, 0, interfaceName);
318             NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName, roleToInterfaceType(role),
319                     isEtree);
320             if (uni.isPortSecurityEnabled() && uni.getSecurityGroups() != null && !uni.getSecurityGroups().isEmpty()) {
321                 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
322                 NetvirtUtils.addAclToInterface(interfaceName, uni.getSecurityGroups(), tx);
323                 MdsalUtils.commitTransaction(tx);
324             }
325             uniQosManager.mapUniPortBandwidthLimits(uni.getUniId().getValue(), interfaceName,
326                     uni.getIngressBwProfile());
327             setOperEvcElanPort(evcId, instanceName, interfaceName);
328         } else {
329             for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
330                 Long vlan = safeCastVlan(ceVlan.getVid());
331                 String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), vlan);
332                 if (interfaceName == null) {
333                     String errorMessage = String.format("Uni %s Interface for vlan %d is not operational ",
334                             uni.getUniId(), 0);
335                     Log.error(errorMessage);
336                     throw new UnsupportedOperationException(errorMessage);
337                 }
338                 if (isOperEvcElanPort(evcId, interfaceName)) {
339                     log.info("elan interface for elan {} vlan {} interface {} exists already", instanceName, 0,
340                             interfaceName);
341                     return;
342                 }
343                 log.info("Creting elan interface for elan {} vlan {} interface {}", instanceName, 0, interfaceName);
344                 NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName, roleToInterfaceType(role),
345                         isEtree);
346                 if (uni.isPortSecurityEnabled() && uni.getSecurityGroups() != null && !uni.getSecurityGroups().isEmpty()) {
347                     WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
348                     NetvirtUtils.addAclToInterface(interfaceName, uni.getSecurityGroups(), tx);
349                     MdsalUtils.commitTransaction(tx);                }
350                 uniQosManager.mapUniPortBandwidthLimits(uni.getUniId().getValue(), interfaceName,
351                         uni.getIngressBwProfile());
352                 setOperEvcElanPort(evcId, instanceName, interfaceName);
353             }
354         }
355     }
356
357     private void removeUniElanInterfaces(InstanceIdentifier<Evc> evcId, String instanceName, Uni uni) {
358         EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
359
360         List<EvcUniCeVlan> evcUniCeVlan = evcUniCeVlans != null && evcUniCeVlans.getEvcUniCeVlan() != null
361                 && !evcUniCeVlans.getEvcUniCeVlan().isEmpty() ? evcUniCeVlans.getEvcUniCeVlan()
362                         : Collections.emptyList();
363
364         if (evcUniCeVlan.isEmpty()) {
365             String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), Long.valueOf(0));
366             if (interfaceName == null || !isOperEvcElanPort(evcId, interfaceName)) {
367                 log.info("elan interface for elan {} vlan {} is not operational, nothing to remove", instanceName, 0,
368                         interfaceName);
369                 interfaceName = uniPortManager.getUniVlanInterfaceName(uni.getUniId().getValue(), null);
370             }
371             removeElanInterface(evcId, uni.getUniId().getValue(), interfaceName);
372         } else {
373             for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
374                 Long vlan = safeCastVlan(ceVlan.getVid());
375                 String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), vlan);
376                 if (interfaceName == null || !isOperEvcElanPort(evcId, interfaceName)) {
377                     log.info("elan interface for elan {} vlan {} is not operational, nothing to remove", instanceName,
378                             vlan, interfaceName);
379                     interfaceName = uniPortManager.getUniVlanInterfaceName(uni.getUniId().getValue(), vlan);
380                 }
381                 removeElanInterface(evcId, uni.getUniId().getValue(), interfaceName);
382             }
383         }
384
385         for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
386             Long vlan = safeCastVlan(ceVlan.getVid());
387             uniPortManager.removeCeVlan(uni.getUniId().getValue(), vlan);
388         }
389     }
390
391     private void removeElanInterface(InstanceIdentifier<Evc> identifier, String uniId, String interfaceName) {
392         log.info("Removing elan interface: " + interfaceName);
393         uniQosManager.unMapUniPortBandwidthLimits(uniId, interfaceName);
394         NetvirtUtils.deleteElanInterface(dataBroker, interfaceName);
395
396         EvcElan evcElan = getOperEvcElan(identifier);
397         if (evcElan == null) {
398             log.error("Removing non-operational Elan interface {}", interfaceName);
399         }
400
401         deleteOperEvcElanPort(identifier, interfaceName);
402     }
403
404     // Expected from API is Long
405     private Long safeCastVlan(Object vid) {
406         if (!(vid instanceof Long)) {
407             String errorMessage = String.format("vlan id %s cannot be cast to Long", vid);
408             log.error(errorMessage);
409             throw new UnsupportedOperationException(errorMessage);
410         }
411         return (Long) vid;
412     }
413
414     private static EtreeInterfaceType roleToInterfaceType(EvcUniRoleType role) {
415         if (role == EvcUniRoleType.Root) {
416             return EtreeInterfaceType.Root;
417         } else {
418             return EtreeInterfaceType.Leaf;
419         }
420     }
421
422     private EvcElan getOperEvcElan(InstanceIdentifier<Evc> identifier) {
423         InstanceIdentifier<EvcElan> path = identifier.augmentation(EvcElan.class);
424         Optional<EvcElan> evcElan = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
425         if (evcElan.isPresent()) {
426             return evcElan.get();
427         } else {
428             return null;
429         }
430     }
431
432     private void removeOperEvcElan(InstanceIdentifier<Evc> identifier) {
433         final InstanceIdentifier<MefService> serviceId = identifier.firstIdentifierOf(MefService.class);
434         MdsalUtils.delete(dataBroker, LogicalDatastoreType.OPERATIONAL, serviceId);
435     }
436
437     private boolean isOperEvcElanPort(InstanceIdentifier<Evc> identifier, String elanPort) {
438         EvcElan evcElan = getOperEvcElan(identifier);
439         if (evcElan == null || evcElan.getElanPorts() == null) {
440             return false;
441         }
442         List<ElanPorts> exPorts = evcElan.getElanPorts();
443         return exPorts.stream().anyMatch(p -> p.getPortId().equals(elanPort));
444     }
445
446     private void setOperEvcElanPort(InstanceIdentifier<Evc> identifier, String elanName, String elanPort) {
447         InstanceIdentifier<EvcElan> path = identifier.augmentation(EvcElan.class);
448         EvcElan evcElan = getOperEvcElan(identifier);
449         EvcElanBuilder evcElanBuilder = evcElan != null ? new EvcElanBuilder(evcElan) : new EvcElanBuilder();
450         List<ElanPorts> exPorts = evcElan != null && evcElan.getElanPorts() != null ? evcElan.getElanPorts()
451                 : new ArrayList<>();
452
453         ElanPortsBuilder portB = new ElanPortsBuilder();
454         portB.setPortId(elanPort);
455         exPorts.add(portB.build());
456         evcElanBuilder.setElanId(elanName);
457         evcElanBuilder.setElanPorts(exPorts);
458         MdsalUtils.write(dataBroker, LogicalDatastoreType.OPERATIONAL, path, evcElanBuilder.build());
459     }
460
461     private void deleteOperEvcElanPort(InstanceIdentifier<Evc> identifier, String elanPort) {
462         InstanceIdentifier<EvcElan> path = identifier.augmentation(EvcElan.class);
463         EvcElan evcElan = getOperEvcElan(identifier);
464         EvcElanBuilder evcElanBuilder = null;
465         List<ElanPorts> exPorts = Collections.emptyList();
466         if (evcElan != null) {
467             evcElanBuilder = new EvcElanBuilder(evcElan);
468             exPorts = evcElan.getElanPorts() != null ? evcElan.getElanPorts() : Collections.emptyList();
469         } else {
470             Log.error("Deleting non-operational Elan port {}", elanPort);
471             return;
472         }
473         List<ElanPorts> newList = exPorts.stream().filter(p -> !p.getPortId().equals(elanPort))
474                 .collect(Collectors.toList());
475         evcElanBuilder.setElanPorts(newList);
476         MdsalUtils.write(dataBroker, LogicalDatastoreType.OPERATIONAL, path, evcElanBuilder.build());
477     }
478
479     private void updateQos(List<Uni> uniToUpdate) {
480         uniToUpdate.forEach(u -> uniQosManager.setUniBandwidthLimits(u.getUniId()));
481     }
482
483     private void updateUnis(List<Uni> uniToUpdate) {
484         uniToUpdate.forEach(u -> uniQosManager.updateUni(u.getUniId(), u.getIngressBwProfile()));
485         updateQos(uniToUpdate);
486     }
487 }