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.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
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);
94 Log.info("Number of UNI's: " + data.getUnis().getUni().size());
97 // Create elan interfaces
98 for (Uni uni : data.getUnis().getUni()) {
99 createInterfaces(vpnName, uni);
101 } catch (final Exception e) {
102 Log.error("Add ipvc failed !", e);
106 private void updateIpvc(DataTreeModification<Ipvc> modifiedDataObject) {
108 Ipvc original = modifiedDataObject.getRootNode().getDataBefore();
109 Ipvc update = modifiedDataObject.getRootNode().getDataAfter();
111 String instanceName = original.getIpvcId().getValue();
112 final String vpnName = NetvirtVpnUtils.getUUidFromString(instanceName);
114 Log.info("Updating elan instance: " + instanceName);
116 if (original == null || original.getUnis() == null || original.getUnis().getUni() == null) {
117 addIpvc(modifiedDataObject);
121 List<Uni> originalUni = original.getUnis().getUni();
122 List<Uni> updateUni = update.getUnis().getUni();
123 if (updateUni != null && !updateUni.isEmpty()) {
124 List<Uni> existingClonedUni = new ArrayList<>();
125 if (originalUni != null && !originalUni.isEmpty()) {
126 existingClonedUni.addAll(0, originalUni);
127 originalUni.removeAll(updateUni);
128 updateUni.removeAll(existingClonedUni);
129 // removing the Uni which are not presented in the updated
131 for (Uni uni : originalUni) {
132 removeElanInterface(vpnName, uni);
136 // Adding the new Uni which are presented in the updated List
137 if (updateUni.size() > 0) {
138 for (Uni uni : updateUni) {
139 createInterfaces(vpnName, uni);
142 } else if (originalUni != null && !originalUni.isEmpty()) {
143 for (Uni uni : originalUni) {
144 removeElanInterface(vpnName, uni);
147 } catch (final Exception e) {
148 Log.error("Update ipvc failed !", e);
152 private void removeIpvc(DataTreeModification<Ipvc> removedDataObject) {
154 Ipvc data = removedDataObject.getRootNode().getDataBefore();
156 String instanceName = data.getIpvcId().getValue();
158 for (Uni uni : data.getUnis().getUni()) {
159 removeElanInterface(instanceName, uni);
162 Log.info("Removing elan instance: " + instanceName);
163 NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
164 } catch (final Exception e) {
165 Log.error("Remove ipvc failed !", e);
169 private void createInterfaces(Ipvc ipvc, Uni uni) {
170 String instanceName = ipvc.getIpvcId().getValue();
171 createInterfaces(instanceName, uni);
174 private void createInterfaces(String vpnName, Uni uniInService) {
175 String uniId = uniInService.getUniId().getValue();
176 String ipUniId = uniInService.getIpUniId().getValue();
178 Log.info("Adding/updating elan instance: " + uniId);
180 org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = IpvcUniUtils
181 .getUni(dataBroker, uniId);
183 Log.error("Couldn't find uni {} for ipvc-uni", uniId);
184 throw new UnsupportedOperationException();
186 IpUni ipUni = IpvcUniUtils.getIpUni(dataBroker, uniId, ipUniId);
187 Integer vlan = ipUni.getVlan() != null ? ipUni.getVlan().getValue() : null;
189 String elanName = NetvirtVpnUtils.getElanNameForVpnPort(uniId);
190 Log.info("Adding elan instance: " + elanName);
191 NetvirtUtils.updateElanInstance(dataBroker, elanName);
193 String interfaceName = NetvirtVpnUtils.getInterfaceNameForVlan(ipUniId, vlan);
194 Log.info("Adding trunk interface: " + interfaceName);
195 IpvcUniUtils.addUni(dataBroker, uniInService, interfaceName, vlan);
197 Log.info("Adding elan interface: " + interfaceName);
198 NetvirtUtils.createInterface(dataBroker, elanName, interfaceName, EtreeInterfaceType.Root, false);
200 Log.info("Adding vpn interface: " + interfaceName);
201 NetvirtVpnUtils.createUpdateVpnInterface(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
202 uni.getMacAddress(), true, null);
203 NetvirtVpnUtils.createVpnPortFixedIp(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
204 uni.getMacAddress());
206 Log.info("Adding connected network for interface : " + interfaceName);
207 NetvirtVpnUtils.addDirectSubnetToVpn(dataBroker, notificationPublishService, vpnName, elanName,
208 ipUni.getIpAddress(), interfaceName);
210 if (ipUni != null && ipUni.getSubnets() != null && ipUni.getSubnets().getSubnet() != null) {
211 for (Subnet subnet : ipUni.getSubnets().getSubnet()) {
212 Log.info("Resolving MAC address for gateway: " + subnet.getGateway());
213 MacAddress gwMacAddress = NetvirtVpnUtils.resolveGwMac(dataBroker, arpUtilService, vpnName,
214 ipUni.getIpAddress(), subnet.getGateway(), interfaceName); // trunk
215 if (gwMacAddress == null) {
218 Log.info("update vpn interface: " + interfaceName);
219 NetvirtVpnUtils.createUpdateVpnInterface(dataBroker, vpnName, interfaceName, subnet.getSubnet(),
220 gwMacAddress, false, ipUni.getIpAddress());
223 Log.info("Finished working on elan instance: " + uniId);
226 private void removeElanInterface(String instanceName, Uni uni) {
227 String uniId = uni.getIpUniId().getValue();
228 String interfaceName = uniId;
229 Log.info("Removing elan interface: " + uniId);
230 NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);