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