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 java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
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.itm.validator.TransportZoneNameAllowed;
32 import org.opendaylight.genius.itm.validator.TransportZoneValidator;
33 import org.opendaylight.genius.itm.validator.ValidatorErrorCode;
34 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVteps;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
53 * This class listens for interface creation/removal/update in Configuration DS.
54 * This is used to handle interfaces for base of-ports.
56 public class TransportZoneListener extends AsyncDataTreeChangeListenerBase<TransportZone, TransportZoneListener>
57 implements AutoCloseable {
58 private static final Logger LOG = LoggerFactory.getLogger(TransportZoneListener.class);
59 private final DataBroker dataBroker;
60 private final IdManagerService idManagerService;
61 private IMdsalApiManager mdsalManager;
62 private ITMManager itmManager;
64 public TransportZoneListener(final DataBroker dataBroker, final IdManagerService idManagerService) {
65 super(TransportZone.class, TransportZoneListener.class);
66 this.dataBroker = dataBroker;
67 this.idManagerService = idManagerService;
68 initializeTZNode(dataBroker);
71 public void setItmManager(ITMManager itmManager) {
72 this.itmManager = itmManager;
75 public void setMdsalManager(IMdsalApiManager mdsalManager) {
76 this.mdsalManager = mdsalManager;
79 private void initializeTZNode(DataBroker db) {
80 ReadWriteTransaction transaction = db.newReadWriteTransaction();
81 InstanceIdentifier<TransportZones> path = InstanceIdentifier.create(TransportZones.class);
82 CheckedFuture<Optional<TransportZones>, ReadFailedException> tzones = transaction
83 .read(LogicalDatastoreType.CONFIGURATION, path);
85 if (!tzones.get().isPresent()) {
86 TransportZonesBuilder tzb = new TransportZonesBuilder();
87 transaction.put(LogicalDatastoreType.CONFIGURATION, path, tzb.build());
92 } catch (Exception e) {
93 LOG.error("Error initializing TransportZones {}", e);
98 public void close() throws Exception {
99 LOG.info("tzChangeListener Closed");
103 protected InstanceIdentifier<TransportZone> getWildCardPath() {
104 return InstanceIdentifier.create(TransportZones.class).child(TransportZone.class);
108 protected TransportZoneListener getDataTreeChangeListener() {
109 return TransportZoneListener.this;
113 protected void remove(InstanceIdentifier<TransportZone> key, TransportZone tzOld) {
114 LOG.debug("Received Transport Zone Remove Event: {}, {}", key, tzOld);
115 if(validateTransportZoneParam(tzOld)){
116 //TODO : DPList code can be refactor with new specific class
117 // which implement TransportZoneValidator
118 List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzOld);
119 List<HwVtep> hwVtepList = createhWVteps(tzOld);
120 LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
121 if(!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
122 LOG.trace("Delete: Invoking ItmManager with hwVtep List {} " , hwVtepList);
123 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
124 ItmTepRemoveWorker removeWorker =
125 new ItmTepRemoveWorker(opDpnList, hwVtepList, tzOld, dataBroker, idManagerService, mdsalManager);
126 coordinator.enqueueJob(tzOld.getZoneName(), removeWorker);
132 protected void update(InstanceIdentifier<TransportZone> key, TransportZone tzOld, TransportZone tzNew) {
133 LOG.debug("Received Transport Zone Update Event: Key - {}, Old - {}, Updated - {}", key, tzOld, tzNew);
134 List<DPNTEPsInfo> oldDpnTepsList = createDPNTepInfo(tzOld);
135 List<DPNTEPsInfo> newDpnTepsList = createDPNTepInfo(tzNew);
136 List<DPNTEPsInfo> oldDpnTepsListcopy = new ArrayList<>();
137 oldDpnTepsListcopy.addAll(oldDpnTepsList);
138 LOG.trace("oldcopy0" + oldDpnTepsListcopy);
139 List<DPNTEPsInfo> newDpnTepsListcopy = new ArrayList<>();
140 newDpnTepsListcopy.addAll(newDpnTepsList);
141 LOG.trace("newcopy0" + newDpnTepsListcopy);
142 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
144 oldDpnTepsList.removeAll(newDpnTepsListcopy);
145 newDpnTepsList.removeAll(oldDpnTepsListcopy);
147 LOG.trace("oldDpnTepsList" + oldDpnTepsList);
148 LOG.trace("newDpnTepsList" + newDpnTepsList);
149 LOG.trace("oldcopy" + oldDpnTepsListcopy);
150 LOG.trace("newcopy" + newDpnTepsListcopy);
151 LOG.trace("oldcopy Size " + oldDpnTepsList.size());
152 LOG.trace("newcopy Size " + newDpnTepsList.size());
153 if (!newDpnTepsList.isEmpty()) {
154 LOG.trace("Adding TEPs ");
155 ItmTepAddWorker addWorker = new ItmTepAddWorker(newDpnTepsList, Collections.emptyList(), dataBroker,
156 idManagerService, mdsalManager);
157 coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
159 if (!oldDpnTepsList.isEmpty()) {
160 LOG.trace("Removing TEPs ");
161 ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(oldDpnTepsList, Collections.emptyList(),
162 tzOld, dataBroker, idManagerService, mdsalManager);
163 coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
165 List<HwVtep> oldHwList = createhWVteps(tzOld);
166 List<HwVtep> newHwList = createhWVteps(tzNew);
167 List<HwVtep> oldHwListcopy = new ArrayList<>();
168 oldHwListcopy.addAll(oldHwList);
169 LOG.trace("oldHwListcopy0" + oldHwListcopy);
170 List<HwVtep> newHwListcopy = new ArrayList<>();
171 newHwListcopy.addAll(newHwList);
172 LOG.trace("newHwListcopy0" + newHwListcopy);
174 oldHwList.removeAll(newHwListcopy);
175 newHwList.removeAll(oldHwListcopy);
176 LOG.trace("oldHwList" + oldHwList);
177 LOG.trace("newHwList" + newHwList);
178 LOG.trace("oldHwListcopy" + oldHwListcopy);
179 LOG.trace("newHwListcopy" + newHwListcopy);
180 if (!newHwList.isEmpty()) {
181 LOG.trace("Adding HW TEPs ");
182 ItmTepAddWorker addWorker = new ItmTepAddWorker(Collections.emptyList(), newHwList, dataBroker,
183 idManagerService, mdsalManager);
184 coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
186 if (!oldHwList.isEmpty()) {
187 LOG.trace("Removing HW TEPs ");
188 ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(Collections.emptyList(), oldHwList,
189 tzOld, dataBroker, idManagerService, mdsalManager);
190 coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
195 protected void add(InstanceIdentifier<TransportZone> key, TransportZone tzNew) {
196 LOG.debug("Received Transport Zone Add Event: {}, {}", key, tzNew);
197 List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzNew);
198 List<HwVtep> hwVtepList = createhWVteps(tzNew);
199 LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList);
200 if (!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
201 LOG.trace("Add: Invoking ItmManager with DPN List {} ", opDpnList);
202 LOG.trace("Add: Invoking ItmManager with hwVtep List {} ", hwVtepList);
203 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
204 ItmTepAddWorker addWorker = new ItmTepAddWorker(opDpnList, hwVtepList, dataBroker, idManagerService,
206 coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
210 private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone) {
211 Map<BigInteger, List<TunnelEndPoints>> mapDPNToTunnelEndpt = new ConcurrentHashMap<>();
212 List<DPNTEPsInfo> dpnTepInfo = new ArrayList<>();
213 List<TzMembership> zones = ItmUtils.createTransportZoneMembership(transportZone.getZoneName());
214 Class<? extends TunnelTypeBase> tunnelType = transportZone.getTunnelType();
215 LOG.trace("Transport Zone_name: {}", transportZone.getZoneName());
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 boolean useOfTunnel = ItmUtils.falseIfNull(vteps.isOptionOfTunnel());
230 LOG.trace("DpnID: {}, port: {}, ipAddress: {}", dpnID, port, ipAddress);
231 TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port,
232 useOfTunnel, vlanID, ipPrefix, gatewayIP, zones, tunnelType);
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);
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);
248 if (!mapDPNToTunnelEndpt.isEmpty()) {
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);
259 private List<HwVtep> createhWVteps(TransportZone transportZone) {
260 List<HwVtep> hwVtepsList = new ArrayList<>();
262 String zoneName = transportZone.getZoneName();
263 Class<? extends TunnelTypeBase> tunnelType = transportZone.getTunnelType();
264 LOG.trace("Transport Zone_name: {}", zoneName);
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 topologyId = vteps.getTopologyId();
276 String nodeId = vteps.getNodeId();
277 IpAddress ipAddress = vteps.getIpAddress();
278 LOG.trace("topo-id: {}, node-id: {}, ipAddress: {}", topologyId, nodeId, ipAddress);
279 HwVtep hwVtep = ItmUtils.createHwVtepObject(topologyId, nodeId, ipAddress, ipPrefix, gatewayIP,
280 vlanID, tunnelType, 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);
297 private boolean validateTransportZoneParam(TransportZone transportZone) {
298 boolean validateParam = true;
299 ArrayList<TransportZoneValidator> tzValidatorList = new ArrayList<>();
300 tzValidatorList.add(new TransportZoneNameAllowed());
301 for(TransportZoneValidator tzValidator :tzValidatorList){
302 if(tzValidator.validate(transportZone) == ValidatorErrorCode.ERROR){
303 validateParam = false;
307 return validateParam;