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