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.Collections;
12 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.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
21 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
22 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
23 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.PhysicalLayers;
24 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.Links;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
26 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
27 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
28 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.Evc;
29 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.Unis;
30 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.Uni;
31 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.EvcUniCeVlans;
32 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;
33 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.VlanIdType;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
37 import org.opendaylight.yangtools.concepts.ListenerRegistration;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 import com.google.common.base.Objects;
43 import com.google.common.base.Optional;
44 import com.google.common.collect.Sets;
45 import com.google.common.util.concurrent.CheckedFuture;
47 public class EvcUniListener extends UnimgrDataTreeChangeListener<Uni> {
48 private static final Logger logger = LoggerFactory.getLogger(EvcUniListener.class);
50 private ListenerRegistration<EvcUniListener> uniListenerRegistration;
52 public EvcUniListener(final DataBroker dataBroker) {
59 public void add(DataTreeModification<Uni> newDataObject) {
60 if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
61 logger.info("uni {} created", newDataObject.getRootNode().getIdentifier());
62 addUni(newDataObject);
67 public void remove(DataTreeModification<Uni> removedDataObject) {
68 if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
69 logger.info("uni {} deleted", removedDataObject.getRootNode().getIdentifier());
70 removeUni(removedDataObject);
75 public void update(DataTreeModification<Uni> modifiedDataObject) {
76 if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
77 logger.info("uni {} updated", modifiedDataObject.getRootNode().getIdentifier());
78 updateUni(modifiedDataObject);
82 protected void removeUni(DataTreeModification<Uni> removedDataObject) {
84 Uni data = removedDataObject.getRootNode().getDataBefore();
86 String uniId = data.getUniId().getValue();
87 WriteTransaction tx = createTransaction();
88 logger.info("Removing trunk {}", uniId);
91 Optional<List<EvcUniCeVlan>> ceVlansOptional = getCeVlans(data);
92 if (!ceVlansOptional.isPresent()) {
96 removeTrunkMemberInterfaces(uniId, ceVlansOptional.get(), tx);
97 commitTransaction(tx);
98 } catch (final Exception e) {
99 logger.error("Remove uni failed !", e);
103 protected void updateUni(DataTreeModification<Uni> modifiedDataObject) {
105 Uni original = modifiedDataObject.getRootNode().getDataBefore();
106 Uni update = modifiedDataObject.getRootNode().getDataAfter();
108 String uniId = update.getUniId().getValue();
109 WriteTransaction tx = createTransaction();
110 String origTrunkParentName = getTrunkParentName(original);
111 String updatedTrunkParentName = getTrunkParentName(update);
113 if (!Objects.equal(origTrunkParentName, updatedTrunkParentName)) {
114 addTrunkInterface(uniId, updatedTrunkParentName, tx);
117 Set<EvcUniCeVlan> origCeVlans = Sets.newHashSet(getCeVlans(original).or(Collections.emptyList()));
118 Set<EvcUniCeVlan> updatedCeVlans = Sets.newHashSet(getCeVlans(update).or(Collections.emptyList()));
119 Iterable<EvcUniCeVlan> removedCeVlans = Sets.difference(origCeVlans, updatedCeVlans);
120 Iterable<EvcUniCeVlan> addedCeVlans = Sets.difference(updatedCeVlans, origCeVlans);
121 removeTrunkMemberInterfaces(uniId, removedCeVlans, tx);
122 addTrunkMemberInterfaces(uniId, addedCeVlans, tx);
123 commitTransaction(tx);
124 } catch (final Exception e) {
125 logger.error("Update uni failed !", e);
130 protected void addUni(DataTreeModification<Uni> newDataObject) {
132 Uni data = newDataObject.getRootNode().getDataAfter();
134 String uniId = data.getUniId().getValue();
135 WriteTransaction tx = createTransaction();
136 addTrunkInterface(uniId, getTrunkParentName(data), tx);
138 Optional<List<EvcUniCeVlan>> ceVlansOptional = getCeVlans(data);
139 if (ceVlansOptional.isPresent()) {
140 addTrunkMemberInterfaces(uniId, ceVlansOptional.get(), tx);
143 commitTransaction(tx);
144 } catch (final Exception e) {
145 logger.error("Add uni failed !", e);
150 private void addTrunkInterface(String interfaceName, String parentInterfaceName, WriteTransaction tx) {
151 logger.info("Adding VLAN trunk {} ParentRef {}", interfaceName, parentInterfaceName);
152 Interface trunkInterface = NetvirtUtils.createTrunkInterface(interfaceName, parentInterfaceName);
153 write(trunkInterface, tx);
156 private void addTrunkMemberInterfaces(String parentInterfaceName, Iterable<EvcUniCeVlan> ceVlans,
157 WriteTransaction tx) {
158 for (EvcUniCeVlan ceVlan : ceVlans) {
159 Long vlanId = ((VlanIdType) ceVlan.getVid()).getValue();
160 String interfaceName = NetvirtUtils.getInterfaceNameForVlan(parentInterfaceName, vlanId.toString());
161 logger.info("Adding VLAN trunk-member {} ParentRef {}", interfaceName, parentInterfaceName);
162 Interface trunkMemberInterface = NetvirtUtils.createTrunkMemberInterface(interfaceName, parentInterfaceName,
164 write(trunkMemberInterface, tx);
168 private void removeTrunkMemberInterfaces(String parentInterfaceName, Iterable<EvcUniCeVlan> ceVlans,
169 WriteTransaction tx) {
170 for (EvcUniCeVlan ceVlan : ceVlans) {
171 Long vlanId = ((VlanIdType) ceVlan.getVid()).getValue();
172 String interfaceName = NetvirtUtils.getInterfaceNameForVlan(parentInterfaceName, vlanId.toString());
173 logger.info("Removing VLAN trunk-member {}", interfaceName);
174 delete(interfaceName, tx);
178 private InstanceIdentifier<Interface> createInterfaceIdentifier(String interfaceName) {
179 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
183 private WriteTransaction createTransaction() {
184 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
188 private void commitTransaction(WriteTransaction tx) {
190 CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
192 } catch (Exception e) {
193 logger.error("failed to commit transaction due to exception ", e);
197 private void write(Interface iface, WriteTransaction tx) {
198 String interfaceName = iface.getName();
199 InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
200 tx.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, iface, true);
203 private void delete(String interfaceName, WriteTransaction tx) {
204 InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
205 tx.delete(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
208 private String getTrunkParentName(Uni evcUni) {
210 Optional<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni> optional = MdsalUtils
211 .read(dataBroker, LogicalDatastoreType.CONFIGURATION,
212 MefUtils.getUniInstanceIdentifier(evcUni.getUniId().getValue()));
214 if (!optional.isPresent()) {
215 logger.error("A matching Uni doesn't exist for EvcUni {}", evcUni.getUniId());
219 org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = optional
222 PhysicalLayers physicalLayers = uni.getPhysicalLayers();
223 if (physicalLayers == null) {
224 logger.warn("Uni {} is missing PhysicalLayers", evcUni.getUniId());
228 Links links = physicalLayers.getLinks();
229 if (links == null || links.getLink() == null) {
230 logger.warn("Uni {} is has no links", evcUni.getUniId());
234 Link link = links.getLink().get(0);
235 String deviceName = link.getDevice().getValue();
236 String interfaceName = link.getInterface().toString();
237 return getDeviceInterfaceName(deviceName, interfaceName);
240 private String getDeviceInterfaceName(String deviceName, String interfaceName) {
241 return deviceName + IfmConstants.OF_URI_SEPARATOR + interfaceName;
244 private Optional<List<EvcUniCeVlan>> getCeVlans(Uni uni) {
245 EvcUniCeVlans ceVlans = uni.getEvcUniCeVlans();
246 if (ceVlans == null) {
247 return Optional.absent();
250 return Optional.fromNullable(ceVlans.getEvcUniCeVlan());
253 private void registerListener() {
255 final DataTreeIdentifier<Uni> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
256 getUniTopologyPath());
257 uniListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
258 logger.info("UniDataTreeChangeListener created and registered");
259 } catch (final Exception e) {
260 logger.error("Uni DataChange listener registration failed !", e);
261 throw new IllegalStateException("Uni registration Listener failed.", e);
265 private InstanceIdentifier<Uni> getUniTopologyPath() {
266 return InstanceIdentifier.create(MefServices.class).child(MefService.class).child(Evc.class).child(Unis.class)
271 public void close() throws Exception {
272 // TODO Auto-generated method stub