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.List;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
17 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
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.ip.unis.IpUni;
21 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.ip.uni.subnets.Subnet;
22 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.Ipvc;
23 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;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
27 import org.opendaylight.yangtools.concepts.ListenerRegistration;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
32 private static final Logger Log = LoggerFactory.getLogger(IpvcListener.class);
33 private ListenerRegistration<IpvcListener> ipvcListenerRegistration;
34 private final NotificationPublishService notificationPublishService;
35 private final OdlArputilService arpUtilService;
37 public IpvcListener(final DataBroker dataBroker, final NotificationPublishService notPublishService,
38 final OdlArputilService arputilService) {
40 this.notificationPublishService = notPublishService;
41 this.arpUtilService = arputilService;
45 public void registerListener() {
47 final DataTreeIdentifier<Ipvc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
48 MefUtils.getIpvcInstanceIdentifier());
49 ipvcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
50 Log.info("IpvcDataTreeChangeListener created and registered");
51 } catch (final Exception e) {
52 Log.error("Ipvc DataChange listener registration failed !", e);
53 throw new IllegalStateException("Ipvc registration Listener failed.", e);
58 public void close() throws Exception {
59 ipvcListenerRegistration.close();
63 public void add(DataTreeModification<Ipvc> newDataObject) {
64 if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
65 Log.info("ipvc {} created", newDataObject.getRootNode().getIdentifier());
66 addIpvc(newDataObject);
71 public void remove(DataTreeModification<Ipvc> removedDataObject) {
72 if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
73 Log.info("ipvc {} deleted", removedDataObject.getRootNode().getIdentifier());
74 removeIpvc(removedDataObject);
79 public void update(DataTreeModification<Ipvc> modifiedDataObject) {
80 if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
81 Log.info("ipvc {} updated", modifiedDataObject.getRootNode().getIdentifier());
82 updateIpvc(modifiedDataObject);
86 private void addIpvc(DataTreeModification<Ipvc> newDataObject) {
88 Ipvc data = newDataObject.getRootNode().getDataAfter();
89 String instanceName = data.getIpvcId().getValue();
90 final String vpnName = NetvirtVpnUtils.getUUidFromString(instanceName);
92 Log.info("Adding vpn instance: " + instanceName);
93 NetvirtVpnUtils.createVpnInstance(dataBroker, vpnName);
95 // Create elan interfaces
96 for (Uni uni : data.getUnis().getUni()) {
97 createInterfaces(vpnName, uni);
99 } catch (final Exception e) {
100 Log.error("Add ipvc failed !", e);
104 private void updateIpvc(DataTreeModification<Ipvc> modifiedDataObject) {
106 Ipvc original = modifiedDataObject.getRootNode().getDataBefore();
107 Ipvc update = modifiedDataObject.getRootNode().getDataAfter();
109 String instanceName = original.getIpvcId().getValue();
111 Log.info("Updating elan instance: " + instanceName);
113 List<Uni> originalUni = original.getUnis().getUni();
114 List<Uni> updateUni = update.getUnis().getUni();
115 if (updateUni != null && !updateUni.isEmpty()) {
116 List<Uni> existingClonedUni = new ArrayList<>();
117 if (originalUni != null && !originalUni.isEmpty()) {
118 existingClonedUni.addAll(0, originalUni);
119 originalUni.removeAll(updateUni);
120 updateUni.removeAll(existingClonedUni);
121 // removing the Uni which are not presented in the updated
123 for (Uni uni : originalUni) {
124 removeElanInterface(instanceName, uni);
128 // Adding the new Uni which are presented in the updated List
129 if (updateUni.size() > 0) {
130 for (Uni uni : updateUni) {
131 createInterfaces(original, uni);
134 } else if (originalUni != null && !originalUni.isEmpty()) {
135 for (Uni uni : originalUni) {
136 removeElanInterface(instanceName, uni);
139 } catch (final Exception e) {
140 Log.error("Update ipvc failed !", e);
144 private void removeIpvc(DataTreeModification<Ipvc> removedDataObject) {
146 Ipvc data = removedDataObject.getRootNode().getDataBefore();
148 String instanceName = data.getIpvcId().getValue();
150 for (Uni uni : data.getUnis().getUni()) {
151 removeElanInterface(instanceName, uni);
154 Log.info("Removing elan instance: " + instanceName);
155 NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
156 } catch (final Exception e) {
157 Log.error("Remove ipvc failed !", e);
161 private void createInterfaces(Ipvc ipvc, Uni uni) {
162 String instanceName = ipvc.getIpvcId().getValue();
163 createInterfaces(instanceName, uni);
166 private void createInterfaces(String vpnName, Uni uniInService) {
167 String uniId = uniInService.getUniId().getValue();
168 String ipUniId = uniInService.getIpUniId().getValue();
170 org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = IpvcUniUtils
171 .getUni(dataBroker, uniId);
173 Log.error("Couldn't find uni {} for ipvc-uni", uniId);
174 throw new UnsupportedOperationException();
176 IpUni ipUni = IpvcUniUtils.getIpUni(dataBroker, uniId, ipUniId);
177 Integer vlan = (ipUni.getVlan()) != null ? ipUni.getVlan().getValue() : null;
179 Log.info("Adding/updating elan instance: " + uniId);
180 String elanName = NetvirtVpnUtils.getElanNameForVpnPort(uniId);
181 Log.info("Adding elan instance: " + elanName);
182 NetvirtUtils.updateElanInstance(dataBroker, elanName);
184 String interfaceName = NetvirtVpnUtils.getInterfaceNameForVlan(ipUniId, vlan);
185 Log.info("Adding trunk interface: " + interfaceName);
186 IpvcUniUtils.addUni(dataBroker, uniInService, interfaceName, vlan);
188 Log.info("Adding elan interface: " + interfaceName);
189 NetvirtUtils.createInterface(dataBroker, elanName, interfaceName, EtreeInterfaceType.Root, false);
191 Log.info("Adding vpn interface: " + interfaceName);
192 NetvirtVpnUtils.createUpdateVpnInterface(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
193 uni.getMacAddress(), true, null);
194 NetvirtVpnUtils.createVpnPortFixedIp(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
195 uni.getMacAddress());
197 Log.info("Adding connected network for interface : " + interfaceName);
198 NetvirtVpnUtils.addDirectSubnetToVpn(dataBroker, notificationPublishService, vpnName, elanName,
199 ipUni.getIpAddress(), interfaceName);
201 if (ipUni.getSubnets() != null) {
202 for (Subnet subnet : ipUni.getSubnets().getSubnet()) {
203 MacAddress gwMacAddress = NetvirtVpnUtils.resolveGwMac(dataBroker, arpUtilService, vpnName,
204 ipUni.getIpAddress(), subnet.getGateway(), interfaceName); // trunk
205 if (gwMacAddress == null) {
208 NetvirtVpnUtils.createUpdateVpnInterface(dataBroker, vpnName, interfaceName, subnet.getSubnet(),
209 gwMacAddress, false, ipUni.getIpAddress());
214 private void removeElanInterface(String instanceName, Uni uni) {
215 String uniId = uni.getIpUniId().getValue();
216 String interfaceName = uniId;
217 Log.info("Removing elan interface: " + uniId);
218 NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);