2 * Copyright (c) 2015, 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.vpnservice.itm.listeners;
11 import java.math.BigInteger;
13 import java.util.concurrent.ConcurrentHashMap;
15 import com.google.common.base.Optional;
16 import com.google.common.util.concurrent.CheckedFuture;
17 import com.google.common.util.concurrent.ListenableFuture;
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.rev100924.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.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;
48 * This class listens for interface creation/removal/update in Configuration DS.
49 * This is used to handle interfaces for base of-ports.
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;
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);
65 public void setItmManager(ITMManager itmManager) {
66 this.itmManager = itmManager;
69 public void setMdsalManager(IMdsalApiManager mdsalManager) {
70 this.mdsalManager = mdsalManager;
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);
79 if (!tzones.get().isPresent()) {
80 TransportZonesBuilder tzb = new TransportZonesBuilder();
81 transaction.put(LogicalDatastoreType.CONFIGURATION,path,tzb.build());
86 } catch (Exception e) {
87 LOG.error("Error initializing TransportZones {}",e);
92 public void close() throws Exception {
93 LOG.info("tzChangeListener Closed");
96 protected InstanceIdentifier<TransportZone> getWildCardPath() {
97 return InstanceIdentifier.create(TransportZones.class).child(TransportZone.class);
101 protected TransportZoneListener getDataTreeChangeListener() {
102 return TransportZoneListener.this;
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);
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))) {
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();
138 oldDpnTepsList.removeAll(newDpnTepsListcopy);
139 newDpnTepsList.removeAll(oldDpnTepsListcopy);
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);
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);
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);
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);
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);
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);
206 private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone){
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);
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);
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);
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<>();
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);
284 if (hwVtepsList != null) {
285 LOG.trace("Existing hwVteps");
286 hwVtepsList.add(hwVtep);
288 LOG.trace("Adding new HwVtep {} info ", hwVtep.getHwIp());
289 hwVtepsList.add(hwVtep);
295 LOG.trace("returning hwvteplist {}", hwVtepsList);