2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.genius.itm.listeners;
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
17 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
18 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
19 import org.opendaylight.genius.itm.confighelpers.HwVtep;
20 import org.opendaylight.genius.itm.confighelpers.ItmTepAddWorker;
21 import org.opendaylight.genius.itm.confighelpers.ItmTepRemoveWorker;
22 import org.opendaylight.genius.itm.impl.ITMManager;
23 import org.opendaylight.genius.itm.impl.ItmUtils;
24 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVteps;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 import java.math.BigInteger;
43 import java.util.concurrent.ConcurrentHashMap;
46 * This class listens for interface creation/removal/update in Configuration DS.
47 * This is used to handle interfaces for base of-ports.
49 public class TransportZoneListener extends AsyncDataTreeChangeListenerBase<TransportZone, TransportZoneListener> implements AutoCloseable{
50 private static final Logger LOG = LoggerFactory.getLogger(TransportZoneListener.class);
51 private DataBroker dataBroker;
52 private IdManagerService idManagerService;
53 private IMdsalApiManager mdsalManager;
54 private ITMManager itmManager;
56 public TransportZoneListener(final DataBroker dataBroker, final IdManagerService idManagerService) {
57 super(TransportZone.class, TransportZoneListener.class);
58 this.dataBroker = dataBroker;
59 this.idManagerService = idManagerService;
60 initializeTZNode(dataBroker);
63 public void setItmManager(ITMManager itmManager) {
64 this.itmManager = itmManager;
67 public void setMdsalManager(IMdsalApiManager mdsalManager) {
68 this.mdsalManager = mdsalManager;
71 private void initializeTZNode(DataBroker db) {
72 ReadWriteTransaction transaction = db.newReadWriteTransaction();
73 InstanceIdentifier<TransportZones> path = InstanceIdentifier.create(TransportZones.class);
74 CheckedFuture<Optional<TransportZones>, ReadFailedException> tzones =
75 transaction.read(LogicalDatastoreType.CONFIGURATION,path);
77 if (!tzones.get().isPresent()) {
78 TransportZonesBuilder tzb = new TransportZonesBuilder();
79 transaction.put(LogicalDatastoreType.CONFIGURATION,path,tzb.build());
84 } catch (Exception e) {
85 LOG.error("Error initializing TransportZones {}",e);
90 public void close() throws Exception {
91 LOG.info("tzChangeListener Closed");
94 protected InstanceIdentifier<TransportZone> getWildCardPath() {
95 return InstanceIdentifier.create(TransportZones.class).child(TransportZone.class);
99 protected TransportZoneListener getDataTreeChangeListener() {
100 return TransportZoneListener.this;
104 protected void remove(InstanceIdentifier<TransportZone> key, TransportZone tzOld) {
105 LOG.debug("Received Transport Zone Remove Event: {}, {}", key, tzOld);
106 List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzOld);
107 List<HwVtep> hwVtepList = createhWVteps(tzOld);
108 LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
109 if(opDpnList.size()>0 || hwVtepList.size()>0) {
110 LOG.trace("Delete: Invoking ItmManager");
111 LOG.trace("Delete: Invoking ItmManager with hwVtep List {} " , hwVtepList);
112 // itmManager.deleteTunnels(opDpnList);
113 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
114 ItmTepRemoveWorker removeWorker =
115 new ItmTepRemoveWorker(opDpnList, hwVtepList, tzOld, dataBroker, idManagerService, mdsalManager);
116 coordinator.enqueueJob(tzOld.getZoneName(), removeWorker);
121 protected void update(InstanceIdentifier<TransportZone> key, TransportZone tzOld, TransportZone tzNew) {
122 LOG.debug("Received Transport Zone Update Event: Key - {}, Old - {}, Updated - {}", key, tzOld, tzNew);
123 //if( !(tzOld.equals(tzNew))) {
125 List<DPNTEPsInfo> oldDpnTepsList = new ArrayList<DPNTEPsInfo>();
126 oldDpnTepsList = createDPNTepInfo(tzOld);
127 List<DPNTEPsInfo> newDpnTepsList = new ArrayList<DPNTEPsInfo>();
128 newDpnTepsList = createDPNTepInfo(tzNew);
129 List<DPNTEPsInfo> oldDpnTepsListcopy = new ArrayList<DPNTEPsInfo>();
130 oldDpnTepsListcopy.addAll(oldDpnTepsList);
131 LOG.trace("oldcopy0" + oldDpnTepsListcopy);
132 List<DPNTEPsInfo> newDpnTepsListcopy = new ArrayList<DPNTEPsInfo>();
133 newDpnTepsListcopy.addAll(newDpnTepsList);
134 LOG.trace("newcopy0" + newDpnTepsListcopy);
135 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
137 oldDpnTepsList.removeAll(newDpnTepsListcopy);
138 newDpnTepsList.removeAll(oldDpnTepsListcopy);
140 LOG.trace("oldDpnTepsList" + oldDpnTepsList);
141 LOG.trace("newDpnTepsList" + newDpnTepsList);
142 LOG.trace("oldcopy"+oldDpnTepsListcopy);
143 LOG.trace("newcopy"+newDpnTepsListcopy);
144 LOG.trace("oldcopy Size "+oldDpnTepsList.size());
145 LOG.trace("newcopy Size "+newDpnTepsList.size());
146 if(newDpnTepsList.size() > 0) {
147 LOG.trace( "Adding TEPs " );
148 ItmTepAddWorker addWorker = new ItmTepAddWorker(newDpnTepsList, Collections.<HwVtep>emptyList(), dataBroker, idManagerService, mdsalManager);
149 coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
151 if(oldDpnTepsList.size() > 0) {
152 LOG.trace( "Removing TEPs " );
153 ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(oldDpnTepsList, Collections.<HwVtep>emptyList(),
154 tzOld, dataBroker, idManagerService, mdsalManager);
155 coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
157 List<HwVtep> oldHwList = new ArrayList<HwVtep>();
158 oldHwList = createhWVteps(tzOld);
159 List<HwVtep> newHwList = new ArrayList<HwVtep>();
160 newHwList = createhWVteps(tzNew);
161 List<HwVtep> oldHwListcopy = new ArrayList<HwVtep>();
162 oldHwListcopy.addAll(oldHwList);
163 LOG.trace("oldHwListcopy0" + oldHwListcopy);
164 List<HwVtep> newHwListcopy = new ArrayList<HwVtep>();
165 newHwListcopy.addAll(newHwList);
166 LOG.trace("newHwListcopy0" + newHwListcopy);
168 oldHwList.removeAll(newHwListcopy);
169 newHwList.removeAll(oldHwListcopy);
170 LOG.trace("oldHwList" + oldHwList);
171 LOG.trace("newHwList" + newHwList);
172 LOG.trace("oldHwListcopy" + oldHwListcopy);
173 LOG.trace("newHwListcopy" + newHwListcopy);
174 if(newHwList.size() > 0) {
175 LOG.trace( "Adding HW TEPs " );
176 ItmTepAddWorker addWorker = new ItmTepAddWorker(Collections.<DPNTEPsInfo>emptyList(), newHwList, dataBroker, idManagerService, mdsalManager);
177 coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
179 if (oldHwList.size() > 0) {
180 LOG.trace("Removing HW TEPs ");
181 ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(Collections.<DPNTEPsInfo>emptyList(), oldHwList,
182 tzOld, dataBroker, idManagerService, mdsalManager);
183 coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
189 protected void add(InstanceIdentifier<TransportZone> key, TransportZone tzNew) {
190 LOG.debug("Received Transport Zone Add Event: {}, {}", key, tzNew);
191 List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzNew);
192 List<HwVtep> hwVtepList = createhWVteps(tzNew);
193 LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList);
194 if(opDpnList.size()>0 || hwVtepList.size()>0) {
195 LOG.trace("Add: Invoking ItmManager with DPN List {} " , opDpnList);
196 LOG.trace("Add: Invoking ItmManager with hwVtep List {} " , hwVtepList);
197 //itmManager.build_all_tunnels(opDpnList);
198 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
199 ItmTepAddWorker addWorker = new ItmTepAddWorker(opDpnList, hwVtepList, dataBroker, idManagerService, mdsalManager);
200 coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
204 private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone){
206 Map<BigInteger, List<TunnelEndPoints>> mapDPNToTunnelEndpt = new ConcurrentHashMap<>();
207 List<DPNTEPsInfo> dpnTepInfo = new ArrayList<DPNTEPsInfo>();
208 // List<TransportZone> transportZoneList = transportZones.getTransportZone();
209 // for(TransportZone transportZone : transportZoneList) {
210 String zone_name = transportZone.getZoneName();
211 Class<? extends TunnelTypeBase> tunnel_type = transportZone.getTunnelType();
212 LOG.trace("Transport Zone_name: {}", zone_name);
213 List<Subnets> subnetsList = transportZone.getSubnets();
214 if(subnetsList!=null){
215 for (Subnets subnet : subnetsList) {
216 IpPrefix ipPrefix = subnet.getPrefix();
217 IpAddress gatewayIP = subnet.getGatewayIp();
218 int vlanID = subnet.getVlanId();
219 LOG.trace("IpPrefix: {}, gatewayIP: {}, vlanID: {} ", ipPrefix, gatewayIP, vlanID);
220 List<Vteps> vtepsList = subnet.getVteps();
221 if(vtepsList!=null && !vtepsList.isEmpty()) {
222 for (Vteps vteps : vtepsList) {
223 BigInteger dpnID = vteps.getDpnId();
224 String port = vteps.getPortname();
225 IpAddress ipAddress = vteps.getIpAddress();
226 LOG.trace("DpnID: {}, port: {}, ipAddress: {}", dpnID, port, ipAddress);
227 TunnelEndPoints tunnelEndPoints =
228 ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, vlanID, ipPrefix,
229 gatewayIP, zone_name, tunnel_type);
230 List<TunnelEndPoints> tunnelEndPointsList = mapDPNToTunnelEndpt.get(dpnID);
231 if (tunnelEndPointsList != null) {
232 LOG.trace("Existing DPN info list in the Map: {} ", dpnID);
233 tunnelEndPointsList.add(tunnelEndPoints);
235 LOG.trace("Adding new DPN info list to the Map: {} ", dpnID);
236 tunnelEndPointsList = new ArrayList<TunnelEndPoints>();
237 tunnelEndPointsList.add(tunnelEndPoints);
238 mapDPNToTunnelEndpt.put(dpnID, tunnelEndPointsList);
245 if(mapDPNToTunnelEndpt.size()>0){
246 Set<BigInteger> keys = mapDPNToTunnelEndpt.keySet();
247 LOG.trace("List of dpns in the Map: {} ", keys);
248 for(BigInteger key: keys){
249 DPNTEPsInfo newDpnTepsInfo = ItmUtils.createDPNTepInfo(key, mapDPNToTunnelEndpt.get(key));
250 dpnTepInfo.add(newDpnTepsInfo);
255 private List<HwVtep> createhWVteps(TransportZone transportZone) {
256 //creating hwVtepsList to pass
257 //Inventory model would deprecate Eventually, so not creating hWvtepslist under createDpnTepInfo();
258 List<HwVtep> hwVtepsList = new ArrayList<HwVtep>();
259 //currently the list has only one object always since we are adding L2Gws one by one and only to One TransportZone.
260 //Map<BigInteger, List<TunnelEndPoints>> mapDPNToTunnelEndpt = new ConcurrentHashMap<>();
262 String zone_name = transportZone.getZoneName();
263 Class<? extends TunnelTypeBase> tunnel_type = transportZone.getTunnelType();
264 LOG.trace("Transport Zone_name: {}", zone_name);
265 List<Subnets> subnetsList = transportZone.getSubnets();
266 if (subnetsList != null) {
267 for (Subnets subnet : subnetsList) {
268 IpPrefix ipPrefix = subnet.getPrefix();
269 IpAddress gatewayIP = subnet.getGatewayIp();
270 int vlanID = subnet.getVlanId();
271 LOG.trace("IpPrefix: {}, gatewayIP: {}, vlanID: {} ", ipPrefix, gatewayIP, vlanID);
272 List<DeviceVteps> deviceVtepsList = subnet.getDeviceVteps();
273 if (deviceVtepsList != null) {
274 for (DeviceVteps vteps : deviceVtepsList) {
275 String topo_id = vteps.getTopologyId();
276 String node_id = vteps.getNodeId();
277 IpAddress ipAddress = vteps.getIpAddress();
278 LOG.trace("topo-id: {}, node-id: {}, ipAddress: {}", topo_id, node_id, ipAddress);
279 //TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, vlanID, ipPrefix, gatewayIP, zone_name, tunnel_type);
280 HwVtep hwVtep = ItmUtils.createHwVtepObject(topo_id, node_id, ipAddress, ipPrefix, gatewayIP, vlanID, tunnel_type, transportZone);
282 if (hwVtepsList != null) {
283 LOG.trace("Existing hwVteps");
284 hwVtepsList.add(hwVtep);
286 LOG.trace("Adding new HwVtep {} info ", hwVtep.getHwIp());
287 hwVtepsList.add(hwVtep);
293 LOG.trace("returning hwvteplist {}", hwVtepsList);