257bad8c305595a0f745b179394fdb848a8f622c
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / listeners / TransportZoneListener.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.genius.itm.listeners;
10
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;
40
41 import java.math.BigInteger;
42 import java.util.*;
43 import java.util.concurrent.ConcurrentHashMap;
44
45 /**
46  * This class listens for interface creation/removal/update in Configuration DS.
47  * This is used to handle interfaces for base of-ports.
48  */
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;
55
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);
61     }
62
63     public void setItmManager(ITMManager itmManager) {
64         this.itmManager = itmManager;
65     }
66
67     public void setMdsalManager(IMdsalApiManager mdsalManager) {
68         this.mdsalManager = mdsalManager;
69     }
70
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);
76         try {
77             if (!tzones.get().isPresent()) {
78                 TransportZonesBuilder tzb = new TransportZonesBuilder();
79                 transaction.put(LogicalDatastoreType.CONFIGURATION,path,tzb.build());
80                 transaction.submit();
81             } else {
82                 transaction.cancel();
83             }
84         } catch (Exception e) {
85             LOG.error("Error initializing TransportZones {}",e);
86         }
87     }
88
89     @Override
90     public void close() throws Exception {
91         LOG.info("tzChangeListener Closed");
92     }
93     @Override
94     protected InstanceIdentifier<TransportZone> getWildCardPath() {
95         return InstanceIdentifier.create(TransportZones.class).child(TransportZone.class);
96     }
97
98     @Override
99     protected TransportZoneListener getDataTreeChangeListener() {
100         return TransportZoneListener.this;
101     }
102
103     @Override
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);
117         }
118     }
119
120     @Override
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))) {
124         //add(key, 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();
136
137         oldDpnTepsList.removeAll(newDpnTepsListcopy);
138         newDpnTepsList.removeAll(oldDpnTepsListcopy);
139
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);
150         }
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);
156         }
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);
167
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);
178         }
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);
184         }
185
186     }
187
188     @Override
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);
201         }
202     }
203
204     private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone){
205
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);
234                         } else {
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);
239                         }
240                     }
241                 }
242             }
243         }
244         //}
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);
251             }
252         }
253         return dpnTepInfo;
254     }
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<>();
261
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);
281
282                         if (hwVtepsList != null) {
283                             LOG.trace("Existing hwVteps");
284                             hwVtepsList.add(hwVtep);
285                         } else {
286                             LOG.trace("Adding new HwVtep {} info ", hwVtep.getHwIp());
287                             hwVtepsList.add(hwVtep);
288                         }
289                     }
290                 }
291             }
292         }
293         LOG.trace("returning hwvteplist {}", hwVtepsList);
294         return hwVtepsList;
295     }
296 }