2 * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
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
9 package org.opendaylight.unimgr.mef.netvirt;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
17 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
20 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
21 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.Evc;
22 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.Uni;
23 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.EvcUniCeVlans;
24 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;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcType;
26 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcUniRoleType;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
29 import org.opendaylight.yangtools.concepts.ListenerRegistration;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 import com.google.common.base.Optional;
35 public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
37 private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
38 private ListenerRegistration<EvcListener> evcListenerRegistration;
40 public EvcListener(final DataBroker dataBroker) {
46 public void registerListener() {
48 final DataTreeIdentifier<Evc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
49 MefUtils.getEvcInstanceIdentifier());
50 evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
51 log.info("EvcDataTreeChangeListener created and registered");
52 } catch (final Exception e) {
53 log.error("Evc DataChange listener registration failed !", e);
54 throw new IllegalStateException("Evc registration Listener failed.", e);
59 public void close() throws Exception {
60 evcListenerRegistration.close();
64 public void add(DataTreeModification<Evc> newDataObject) {
65 if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
66 log.info("evc {} created", newDataObject.getRootNode().getIdentifier());
67 addEvc(newDataObject);
72 public void remove(DataTreeModification<Evc> removedDataObject) {
73 if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
74 log.info("evc {} deleted", removedDataObject.getRootNode().getIdentifier());
75 removeEvc(removedDataObject);
80 public void update(DataTreeModification<Evc> modifiedDataObject) {
81 if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
82 log.info("evc {} updated", modifiedDataObject.getRootNode().getIdentifier());
83 updateEvc(modifiedDataObject);
87 private void addEvc(DataTreeModification<Evc> newDataObject) {
89 Evc data = newDataObject.getRootNode().getDataAfter();
90 String instanceName = data.getEvcId().getValue();
91 boolean isEtree = data.getEvcType() == EvcType.RootedMultipoint;
92 if (!data.isAdminStateEnabled()) {
93 log.info("add - evc {} AdminStateEnabled false", data.getEvcId().getValue());
95 log.info("Adding {} instance: {}", isEtree ? "etree" : "elan", instanceName);
96 NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree);
99 if (data.getUnis() == null) {
100 log.info("No UNI's in service {}, exiting", instanceName);
103 for (Uni uni : data.getUnis().getUni()) {
104 if (!uni.isAdminStateEnabled()) {
105 log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
107 createInterface(instanceName, uni, isEtree);
110 } catch (final Exception e) {
111 log.error("Add evc failed !", e);
115 private void updateEvc(DataTreeModification<Evc> modifiedDataObject) {
117 Evc original = modifiedDataObject.getRootNode().getDataBefore();
118 Evc update = modifiedDataObject.getRootNode().getDataAfter();
120 String instanceName = original.getEvcId().getValue();
121 boolean isEtree = update.getEvcType() == EvcType.RootedMultipoint;
123 if (!update.isAdminStateEnabled()) {
124 log.info("update - evc {} AdminStateEnabled false", update.getEvcId().getValue());
126 log.info("Updating {} instance: {}", isEtree ? "etree" : "elan", instanceName);
128 List<Uni> originalUni = original.getUnis() != null ? original.getUnis().getUni() : Collections.emptyList();
129 if (update == null || update.getUnis() == null) {
130 log.info("update uni is null");
132 List<Uni> updateUni = update.getUnis().getUni();
133 if (updateUni != null && !updateUni.isEmpty()) {
134 List<Uni> existingClonedUni = new ArrayList<>();
135 if (originalUni != null && !originalUni.isEmpty()) {
136 existingClonedUni.addAll(0, originalUni);
137 originalUni.removeAll(updateUni);
138 updateUni.removeAll(existingClonedUni);
139 // removing the Uni which are not presented in the updated
141 for (Uni uni : originalUni) {
142 if (!uni.isAdminStateEnabled()) {
143 log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
145 removeElanInterface(instanceName, uni);
150 // Adding the new Uni which are presented in the updated List
151 if (updateUni.size() > 0) {
152 for (Uni uni : updateUni) {
153 if (!uni.isAdminStateEnabled()) {
154 log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
156 createInterface(instanceName, uni, isEtree);
160 } else if (originalUni != null && !originalUni.isEmpty()) {
161 for (Uni uni : originalUni) {
162 if (!uni.isAdminStateEnabled()) {
163 log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
165 removeElanInterface(instanceName, uni);
169 } catch (final Exception e) {
170 log.error("Update evc failed !", e);
174 private void removeEvc(DataTreeModification<Evc> removedDataObject) {
176 Evc data = removedDataObject.getRootNode().getDataBefore();
177 if (!data.isAdminStateEnabled()) {
178 log.info("remove - evc {} AdminStateEnabled false", data.getEvcId().getValue());
181 String instanceName = data.getEvcId().getValue();
183 for (Uni uni : data.getUnis().getUni()) {
184 if (!uni.isAdminStateEnabled()) {
185 log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
188 removeElanInterface(instanceName, uni);
192 log.info("Removing elan instance: " + instanceName);
193 NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
194 } catch (final Exception e) {
195 log.error("Remove evc failed !", e);
199 private void createInterface(String instanceName, Uni uni, boolean isEtree) {
201 EvcUniUtils.addUni(dataBroker, uni);
203 String uniId = uni.getUniId().getValue();
205 Link link = EvcUniUtils.getLink(dataBroker, uni);
206 String interfaceName = uniId;
208 boolean result = waitForGeniusToUpdateInterface(interfaceName);
210 log.error("State interface {} is not configured (missing ifIndex)", interfaceName);
214 EvcUniRoleType role = uni.getRole();
216 EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
218 if (evcUniCeVlans != null && evcUniCeVlans.getEvcUniCeVlan() != null
219 && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
220 for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
222 interfaceName = NetvirtUtils.getInterfaceNameForVlan(interfaceName, x.getVid().toString());
224 log.info("Adding {} interface: {}", isEtree ? "etree" : "elan", interfaceName);
227 NetvirtUtils.createEtreeInterface(dataBroker, instanceName, interfaceName,
228 RoleToInterfaceType(role));
230 NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
234 log.info("Adding {} interface: {}", isEtree ? "etree" : "elan", interfaceName);
236 NetvirtUtils.createEtreeInterface(dataBroker, instanceName, interfaceName, RoleToInterfaceType(role));
238 NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
243 private boolean waitForGeniusToUpdateInterface(String interfaceName) {
246 while (retries > 0) {
247 Optional<Interface> optional = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
248 NetvirtUtils.getStateInterfaceIdentifier(interfaceName));
250 if (!optional.isPresent()) {
251 log.info("State interface {} doesn't exist", interfaceName);
255 Interface stateInterface = optional.get();
257 if (stateInterface.getIfIndex() != null) {
258 log.info("State interface configured with ifIndex {}", stateInterface.getIfIndex());
260 // Wait a bit, because if we continue too soon this will not
264 } catch (InterruptedException e) {
273 } catch (InterruptedException e) {
280 private static EtreeInterfaceType RoleToInterfaceType(EvcUniRoleType role) {
281 if (role == EvcUniRoleType.Root) {
282 return EtreeInterfaceType.Root;
284 return EtreeInterfaceType.Leaf;
288 private void removeElanInterface(String instanceName, Uni uni) {
289 EvcUniUtils.removeUni(dataBroker, uni);
291 String uniId = uni.getUniId().getValue();
292 EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
294 Link link = EvcUniUtils.getLink(dataBroker, uni);
295 String interfaceName = uniId;
297 if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
298 for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
300 interfaceName = NetvirtUtils.getInterfaceNameForVlan(uniId, x.getVid().toString());
301 log.info("Removing elan interface: " + interfaceName);
302 NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
305 log.info("Removing elan interface: " + uniId);
306 NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);