X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=itm%2Fitm-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgenius%2Fitm%2Frecovery%2Fimpl%2FItmTepInstanceRecoveryHandler.java;h=8a9cdf236c3dc1ce021c419389644f68ae8104f9;hb=868ec032398b8ba71fe1643c7a91f8e3c881ea0f;hp=7be41f6c25e233e83e58c59d83a8733d8c75293d;hpb=07d4963f56ec994d53a2f3a8e8584f371ede44c7;p=genius.git diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/recovery/impl/ItmTepInstanceRecoveryHandler.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/recovery/impl/ItmTepInstanceRecoveryHandler.java index 7be41f6c2..8a9cdf236 100644 --- a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/recovery/impl/ItmTepInstanceRecoveryHandler.java +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/recovery/impl/ItmTepInstanceRecoveryHandler.java @@ -7,14 +7,23 @@ */ package org.opendaylight.genius.itm.recovery.impl; +import java.time.Duration; import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; import javax.inject.Inject; import javax.inject.Singleton; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar; +import org.opendaylight.genius.infra.ManagedNewTransactionRunner; +import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl; import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache; import org.opendaylight.genius.itm.cache.DpnTepStateCache; +import org.opendaylight.genius.itm.cache.OfEndPointCache; import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache; import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache; import org.opendaylight.genius.itm.cache.TunnelStateCache; @@ -28,19 +37,24 @@ import org.opendaylight.genius.itm.impl.ItmUtils; import org.opendaylight.genius.itm.impl.TunnelMonitoringConfig; import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils; import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; -import org.opendaylight.genius.srm.ServiceRecoveryInterface; -import org.opendaylight.genius.srm.ServiceRecoveryRegistry; import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils; import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; +import org.opendaylight.serviceutils.srm.ServiceRecoveryInterface; +import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTeps; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpns; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.srm.types.rev170711.GeniusItmTep; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps; +import org.opendaylight.yang.gen.v1.urn.opendaylight.serviceutils.srm.types.rev180626.GeniusItmTep; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,8 +72,10 @@ public class ItmTepInstanceRecoveryHandler implements ServiceRecoveryInterface { private final ItmConfig itmConfig; private final EntityOwnershipUtils entityOwnershipUtils; private final IMdsalApiManager imdsalApiManager; - private String tzName; - private TransportZone transportZone; + private final DataTreeEventCallbackRegistrar eventCallbacks; + private final ManagedNewTransactionRunner txRunner; + private final IInterfaceManager interfaceManager; + private final DpnTepStateCache dpnTepStateCache; @Inject public ItmTepInstanceRecoveryHandler(DataBroker dataBroker, @@ -73,22 +89,28 @@ public class ItmTepInstanceRecoveryHandler implements ServiceRecoveryInterface { OvsBridgeRefEntryCache ovsBridgeRefEntryCache, IInterfaceManager interfaceManager, ServiceRecoveryRegistry serviceRecoveryRegistry, - EntityOwnershipUtils entityOwnershipUtils) { + EntityOwnershipUtils entityOwnershipUtils, + OfEndPointCache ofEndPointCache, + DataTreeEventCallbackRegistrar eventCallbacks) { this.dataBroker = dataBroker; this.itmConfig = itmConfig; this.imdsalApiManager = imdsalApiMgr; this.jobCoordinator = jobCoordinator; this.dpntePsInfoCache = dpntePsInfoCache; this.entityOwnershipUtils = entityOwnershipUtils; + this.eventCallbacks = eventCallbacks; + this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker); this.itmInternalTunnelAddWorker = new ItmInternalTunnelAddWorker(dataBroker, jobCoordinator, - tunnelMonitoringConfig, itmConfig, directTunnelUtils, interfaceManager, ovsBridgeRefEntryCache); - this.itmExternalTunnelAddWorker = new ItmExternalTunnelAddWorker(dataBroker, itmConfig, + tunnelMonitoringConfig, itmConfig, directTunnelUtils, interfaceManager, + ovsBridgeRefEntryCache, ofEndPointCache, eventCallbacks); + this.itmExternalTunnelAddWorker = new ItmExternalTunnelAddWorker(itmConfig, dpntePsInfoCache); this.itmInternalTunnelDeleteWorker = new ItmInternalTunnelDeleteWorker(dataBroker, jobCoordinator, tunnelMonitoringConfig, interfaceManager, dpnTepStateCache, ovsBridgeEntryCache, - ovsBridgeRefEntryCache, tunnelStateCache, - directTunnelUtils); + ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils, ofEndPointCache, itmConfig); serviceRecoveryRegistry.registerServiceRecoveryRegistry(getServiceRegistryKey(), this); + this.interfaceManager = interfaceManager; + this.dpnTepStateCache = dpnTepStateCache; } private String getServiceRegistryKey() { @@ -110,72 +132,115 @@ public class ItmTepInstanceRecoveryHandler implements ServiceRecoveryInterface { private void recoverTep(String entityId) throws InterruptedException { List tepsToRecover = new ArrayList<>(); - DPNTEPsInfo dpnTepsToRecover = extractDPNTepsInfo(entityId); + String[] params = entityId.split(":"); + if (params.length < 2) { + LOG.error("Not enough arguments..Exiting..."); + } else if (params.length > 2) { + LOG.info("Ignoring extra parameter and proceeding..."); + } + String tzName = params[0]; + String ipAddress = params[1]; + TransportZone oldTz = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker); + DPNTEPsInfo dpnTepsToRecover = extractDPNTepsInfo(tzName, ipAddress, oldTz); if (dpnTepsToRecover == null) { LOG.error("Please Enter appropriate arguments for Tep Recovery."); return; } else { tepsToRecover.add(dpnTepsToRecover); - // Delete the transportZone and re create it - // Get the transport zone from the transport zone name - TransportZone oldTz = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker); + //List of Internel tunnels + List tunnelList = ItmUtils.getInternalTunnelsFromCache(dataBroker); + List interfaceListToRecover = new ArrayList<>(); + LOG.debug("List of tunnel interfaces: {}" , tunnelList); + if (oldTz != null) { - ItmTepRemoveWorker tepRemoveWorker = new ItmTepRemoveWorker(tepsToRecover, null, oldTz, - dataBroker, imdsalApiManager, itmInternalTunnelDeleteWorker, dpntePsInfoCache); LOG.trace("Deleting transportzone {}", tzName); + ItmTepRemoveWorker tepRemoveWorker = new ItmTepRemoveWorker(tepsToRecover, null, oldTz, + imdsalApiManager, itmInternalTunnelDeleteWorker, dpntePsInfoCache, txRunner, itmConfig); jobCoordinator.enqueueJob(tzName, tepRemoveWorker); - ItmTepAddWorker tepAddWorker = new ItmTepAddWorker(tepsToRecover, null, dataBroker, - imdsalApiManager, itmConfig, itmInternalTunnelAddWorker, itmExternalTunnelAddWorker, - dpntePsInfoCache); - LOG.trace("Re-creating transportzone {}", tzName); - jobCoordinator.enqueueJob(tzName, tepAddWorker); + AtomicInteger eventCallbackCount = new AtomicInteger(0); + AtomicInteger eventRegistrationCount = new AtomicInteger(0); + if (interfaceManager.isItmDirectTunnelsEnabled()) { + Collection dpnsTeps = dpnTepStateCache.getAllPresent(); + for (DpnsTeps dpnTep : dpnsTeps) { + List rmtdpns = dpnTep.getRemoteDpns(); + for (RemoteDpns remoteDpn : rmtdpns) { + if (remoteDpn.getDestinationDpnId().equals(dpnTepsToRecover.getDPNID()) + || dpnTep.getSourceDpnId().equals(dpnTepsToRecover.getDPNID())) { + eventRegistrationCount.incrementAndGet(); + interfaceListToRecover.add(remoteDpn.getTunnelName()); + } + } + } + LOG.trace("List of tunnels to be recovered : {}", interfaceListToRecover); + } else { + tunnelList.stream().filter(internalTunnel -> Objects.equals(internalTunnel + .getDestinationDPN(), dpnTepsToRecover.getDPNID()) || Objects.equals( + internalTunnel.getSourceDPN(), dpnTepsToRecover.getDPNID())).forEach(internalTunnel -> { + eventRegistrationCount.incrementAndGet(); + interfaceListToRecover.add(String.valueOf(internalTunnel.getTunnelInterfaceNames())); + }); + } + + if (!interfaceListToRecover.isEmpty()) { + interfaceListToRecover.forEach(interfaceName -> { + StateTunnelListKey tlKey = new StateTunnelListKey(interfaceName); + LOG.trace("TunnelStateKey: {} for interface: {}", tlKey, interfaceName); + InstanceIdentifier stListId = ItmUtils.buildStateTunnelListId(tlKey); + eventCallbacks.onRemove(LogicalDatastoreType.OPERATIONAL, stListId, (unused) -> { + LOG.trace("callback event for a delete {} interface instance....", stListId); + // recreating the transportZone + recreateTEP(tzName, tepsToRecover, eventCallbackCount, interfaceListToRecover.size()); + return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER; + }, Duration.ofMillis(5000), (id) -> { + LOG.trace("event callback timed out for {} tunnel interface ", interfaceName); + recreateTEP(tzName, tepsToRecover, eventCallbackCount, interfaceListToRecover.size()); + }); + }); + } else { + recreateTEP(tzName, tepsToRecover, eventCallbackCount, interfaceListToRecover.size()); + } } } } - private DPNTEPsInfo extractDPNTepsInfo(String entityId) { - - String[] params = entityId.split(":"); - if (params.length < 2) { - LOG.error("Not enough arguments..Exiting..."); - return null; - } else if (params.length > 2) { - LOG.info("Ignoring extra parameter and proceeding..."); + private void recreateTEP(String tzName, List tepts, AtomicInteger eventCallbackCount, int registeredEventSize) { + eventCallbackCount.incrementAndGet(); + if (eventCallbackCount.intValue() == registeredEventSize || registeredEventSize == 0) { + LOG.info("Re-creating TEP {}", tzName); + ItmTepAddWorker tepAddWorker = new ItmTepAddWorker(tepts, null, dataBroker, imdsalApiManager, + itmInternalTunnelAddWorker, itmExternalTunnelAddWorker); + jobCoordinator.enqueueJob(tzName, tepAddWorker); } + } - // ToDo:- Need to add more validations - this.tzName = params[0]; - String ipAddress = params[1]; + private DPNTEPsInfo extractDPNTepsInfo(String tzName, String ipAddress, TransportZone transportZone) { - transportZone = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker); if (transportZone == null) { LOG.error("Transportzone name {} is not valid.", tzName); return null; } - for (Subnets sub : transportZone.getSubnets()) { - if (sub.getVteps() == null || sub.getVteps().isEmpty()) { - LOG.error("Transport Zone {} subnet {} has no vteps", transportZone.getZoneName(), sub.getPrefix()); - } - for (Vteps vtep : sub.getVteps()) { - if (ipAddress.equals(String.valueOf(vtep.getIpAddress().getValue()))) { - - List zones = ItmUtils.createTransportZoneMembership(tzName); - LOG.trace("Transportzone {} found match for tep {} to be recovered", transportZone.getZoneName(), - ipAddress); - - //OfTunnels is false byDefault - TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(vtep.getDpnId(), - IpAddressBuilder.getDefaultInstance(ipAddress), vtep.getPortname(), false, sub.getVlanId(), - sub.getPrefix(), sub.getGatewayIp(), zones,transportZone.getTunnelType(), - itmConfig.getDefaultTunnelTos()); - - List teps = new ArrayList<>(); - teps.add(tunnelEndPoints); - return ItmUtils.createDPNTepInfo(vtep.getDpnId(), teps); - } + String portName = itmConfig.getPortname() == null ? ITMConstants.DUMMY_PORT : itmConfig.getPortname(); + int vlanId = itmConfig.getVlanId() != null ? itmConfig.getVlanId().toJava() : ITMConstants.DUMMY_VLANID; + + for (Vteps vtep : transportZone.getVteps()) { + if (ipAddress.equals(vtep.getIpAddress().stringValue())) { + + List zones = ItmUtils.createTransportZoneMembership(tzName); + LOG.trace("Transportzone {} found match for tep {} to be recovered", transportZone.getZoneName(), + ipAddress); + + //OfTunnels is false byDefault + TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(vtep.getDpnId(), + IpAddressBuilder.getDefaultInstance(ipAddress), portName, false, + vlanId, zones, transportZone.getTunnelType(), + itmConfig.getDefaultTunnelTos()); + + List teps = new ArrayList<>(); + teps.add(tunnelEndPoints); + return ItmUtils.createDPNTepInfo(vtep.getDpnId(), teps); } } return null; } -} \ No newline at end of file +}