/*
- * Copyright (c) 2016 - 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ * Copyright (c) 2016 - 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
*/
package org.opendaylight.netvirt.natservice.internal;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import javax.annotation.PostConstruct;
+import java.util.Optional;
+import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
-import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNames;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.infrautils.utils.concurrent.Executors;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.vpn._interface.VpnInstanceNames;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class NatInterfaceStateChangeListener
- extends AsyncDataTreeChangeListenerBase<Interface, NatInterfaceStateChangeListener> {
+ extends AbstractAsyncDataTreeChangeListener<Interface> {
private static final Logger LOG = LoggerFactory.getLogger(NatInterfaceStateChangeListener.class);
- private static final String NAT_DS = "NATDS";
private final DataBroker dataBroker;
- private final OdlInterfaceRpcService odlInterfaceRpcService;
- private final JobCoordinator coordinator;
+ private final NatSouthboundEventHandlers southboundEventHandlers;
@Inject
public NatInterfaceStateChangeListener(final DataBroker dataBroker,
- final OdlInterfaceRpcService odlInterfaceRpcService, final JobCoordinator coordinator) {
- super(Interface.class, NatInterfaceStateChangeListener.class);
+ final NatSouthboundEventHandlers southboundEventHandlers) {
+ super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(InterfacesState.class)
+ .child(Interface.class),
+ Executors.newListeningSingleThreadExecutor("NatInterfaceStateChangeListener", LOG));
this.dataBroker = dataBroker;
- this.odlInterfaceRpcService = odlInterfaceRpcService;
- this.coordinator = coordinator;
+ this.southboundEventHandlers = southboundEventHandlers;
}
- @Override
- @PostConstruct
public void init() {
LOG.info("{} init", getClass().getSimpleName());
- registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
- }
-
- @Override
- protected InstanceIdentifier<Interface> getWildCardPath() {
- return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
}
@Override
- protected NatInterfaceStateChangeListener getDataTreeChangeListener() {
- return NatInterfaceStateChangeListener.this;
+ @PreDestroy
+ public void close() {
+ super.close();
+ Executors.shutdownAndAwaitTermination(getExecutorService());
}
@Override
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
- protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
+ public void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
LOG.trace("add : Interface {} up event received", intrf);
if (!L2vlan.class.equals(intrf.getType())) {
LOG.debug("add : Interface {} is not Vlan Interface.Ignoring", intrf.getName());
return;
}
-
- NatInterfaceStateAddWorker natIfaceStateAddWorker = new NatInterfaceStateAddWorker(intrf);
- coordinator.enqueueJob(NAT_DS + "-" + intrf.getName(), natIfaceStateAddWorker);
+ String interfaceName = intrf.getName();
+ Uint64 intfDpnId;
+ try {
+ intfDpnId = NatUtil.getDpIdFromInterface(intrf);
+ } catch (Exception e) {
+ LOG.error("add : Exception occured while retriving dpnid for interface {}", intrf.getName(), e);
+ return;
+ }
+ if (Uint64.ZERO.equals(intfDpnId)) {
+ LOG.warn("add : Could not retrieve dp id for interface {} ", interfaceName);
+ return;
+ }
+ // We service only VM interfaces. We do not service Tunnel Interfaces here.
+ // Tunnel events are directly serviced by TunnelInterfacesStateListener present as part of
+ // VpnInterfaceManager
+ RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
+ if (routerInterface != null) {
+ this.southboundEventHandlers.handleAdd(interfaceName, intfDpnId, routerInterface);
+ } else {
+ LOG.info("add : Router-Interface Mapping not found for Interface : {}", interfaceName);
+ }
}
@Override
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
- protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
+ public void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
LOG.trace("remove : Interface {} removed event received", intrf);
if (!L2vlan.class.equals(intrf.getType())) {
LOG.debug("remove : Interface {} is not Vlan Interface.Ignoring", intrf.getName());
return;
}
-
- NatInterfaceStateRemoveWorker natIfaceStateRemoveWorker = new NatInterfaceStateRemoveWorker(intrf);
- coordinator.enqueueJob(NAT_DS + "-" + intrf.getName(), natIfaceStateRemoveWorker);
+ String interfaceName = intrf.getName();
+ Uint64 intfDpnId = Uint64.ZERO;
+ try {
+ intfDpnId = NatUtil.getDpIdFromInterface(intrf);
+ } catch (Exception e) {
+ LOG.error("remove : Exception occured while retriving dpnid for interface {}", intrf.getName(), e);
+ InstanceIdentifier<VpnInterface> id = NatUtil.getVpnInterfaceIdentifier(interfaceName);
+ Optional<VpnInterface> cfgVpnInterface =
+ SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
+ dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ if (!cfgVpnInterface.isPresent()) {
+ LOG.warn("remove : Interface {} is not a VPN Interface, ignoring.", interfaceName);
+ return;
+ }
+ for (VpnInstanceNames vpnInterfaceVpnInstance : cfgVpnInterface.get().nonnullVpnInstanceNames().values()) {
+ String vpnName = vpnInterfaceVpnInstance.getVpnName();
+ InstanceIdentifier<VpnInterfaceOpDataEntry> idOper = NatUtil
+ .getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
+ Optional<VpnInterfaceOpDataEntry> optVpnInterface =
+ SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
+ dataBroker, LogicalDatastoreType.OPERATIONAL, idOper);
+ if (optVpnInterface.isPresent()) {
+ intfDpnId = optVpnInterface.get().getDpnId();
+ break;
+ }
+ }
+ }
+ if (Uint64.ZERO.equals(intfDpnId)) {
+ LOG.warn("remove : Could not retrieve dpnid for interface {} ", interfaceName);
+ return;
+ }
+ RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
+ if (routerInterface != null) {
+ this.southboundEventHandlers.handleRemove(intrf.getName(), intfDpnId, routerInterface);
+ } else {
+ LOG.info("remove : Router-Interface Mapping not found for Interface : {}", interfaceName);
+ }
}
@Override
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
- protected void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
+ public void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
LOG.trace("update : Operation Interface update event - Old: {}, New: {}", original, update);
if (!L2vlan.class.equals(update.getType())) {
LOG.debug("update : Interface {} is not Vlan Interface.Ignoring", update.getName());
return;
}
-
- NatInterfaceStateUpdateWorker natIfaceStateupdateWorker = new NatInterfaceStateUpdateWorker(original,update);
- coordinator.enqueueJob(NAT_DS + "-" + update.getName(), natIfaceStateupdateWorker);
- }
-
- void handleRouterInterfacesUpEvent(String routerName, String interfaceName, WriteTransaction writeOperTxn) {
- LOG.debug("handleRouterInterfacesUpEvent : Handling UP event for router interface {} in Router {}",
- interfaceName, routerName);
- BigInteger dpId = NatUtil.getDpnForInterface(odlInterfaceRpcService, interfaceName);
- if (dpId.equals(BigInteger.ZERO)) {
- LOG.warn("handleRouterInterfacesUpEvent : Could not retrieve dp id for interface {} to handle router {} "
- + "association model", interfaceName, routerName);
- return;
- }
- NatUtil.addToNeutronRouterDpnsMap(dataBroker, routerName, interfaceName, dpId, writeOperTxn);
- NatUtil.addToDpnRoutersMap(dataBroker, routerName, interfaceName, dpId, writeOperTxn);
- }
-
- void handleRouterInterfacesDownEvent(String routerName, String interfaceName, BigInteger dpnId,
- WriteTransaction writeOperTxn) {
- LOG.debug("handleRouterInterfacesDownEvent : Handling DOWN event for router Interface {} in Router {}",
- interfaceName, routerName);
- NatUtil.removeFromNeutronRouterDpnsMap(dataBroker, routerName, interfaceName, dpnId, writeOperTxn);
- NatUtil.removeFromDpnRoutersMap(dataBroker, routerName, interfaceName, dpnId, odlInterfaceRpcService,
- writeOperTxn);
- }
-
- private class NatInterfaceStateAddWorker implements Callable<List<ListenableFuture<Void>>> {
- Interface iface;
-
- NatInterfaceStateAddWorker(Interface iface) {
- this.iface = iface;
- }
-
- @Override
- @SuppressWarnings("checkstyle:IllegalCatch")
- public List<ListenableFuture<Void>> call() {
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- final String interfaceName = iface.getName();
- try {
- LOG.trace("call : Received interface {} PORT UP OR ADD event ", interfaceName);
- // We service only VM interfaces and Router interfaces here. We do not service Tunnel Interfaces here.
- // Tunnel events are directly serviced by TunnelInterfacesStateListener present as part of
- // VpnInterfaceManager
- RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
- if (routerInterface != null) {
- String routerName = routerInterface.getRouterName();
- LOG.debug("call : Router Name {} ", routerInterface.getRouterName());
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- handleRouterInterfacesUpEvent(routerName, interfaceName, writeOperTxn);
- futures.add(writeOperTxn.submit());
- } else {
- LOG.info("call : Unable to process add for interface {}", interfaceName);
- }
- } catch (Exception e) {
- LOG.error("call : Exception caught in Interface {} Operational State Up event",
- interfaceName, e);
+ Uint64 intfDpnId = Uint64.ZERO;
+ String interfaceName = update.getName();
+ try {
+ intfDpnId = NatUtil.getDpIdFromInterface(update);
+ } catch (Exception e) {
+ LOG.error("update : Exception occured while retriving dpnid for interface {}", update.getName(), e);
+ InstanceIdentifier<VpnInterface> id = NatUtil.getVpnInterfaceIdentifier(interfaceName);
+ Optional<VpnInterface> cfgVpnInterface =
+ SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
+ dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ if (!cfgVpnInterface.isPresent()) {
+ LOG.warn("update : Interface {} is not a VPN Interface, ignoring.", interfaceName);
+ return;
}
- return futures;
- }
- }
-
- private class NatInterfaceStateRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
- Interface iface;
-
- NatInterfaceStateRemoveWorker(Interface iface) {
- this.iface = iface;
- }
-
- @Override
- @SuppressWarnings("checkstyle:IllegalCatch")
- public List<ListenableFuture<Void>> call() {
- final String interfaceName = iface.getName();
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- try {
- LOG.trace("call : Received interface {} PORT DOWN or REMOVE event", interfaceName);
- BigInteger dpId = null;
- try {
- dpId = NatUtil.getDpIdFromInterface(iface);
- } catch (Exception e) {
- LOG.error("call : Unable to retrieve DPNID from Interface operational data store for "
- + "Interface {}.", interfaceName, e);
- InstanceIdentifier<VpnInterface> id = NatUtil.getVpnInterfaceIdentifier(interfaceName);
- Optional<VpnInterface> cfgVpnInterface =
- SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
- dataBroker, LogicalDatastoreType.CONFIGURATION, id);
- if (!cfgVpnInterface.isPresent()) {
- LOG.warn("call : Interface {} is not a VPN Interface, ignoring.", interfaceName);
- return futures;
- }
- for (VpnInstanceNames vpnInterfaceVpnInstance : cfgVpnInterface.get().getVpnInstanceNames()) {
- String vpnName = vpnInterfaceVpnInstance.getVpnName();
- InstanceIdentifier<VpnInterfaceOpDataEntry> idOper = NatUtil
- .getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
- Optional<VpnInterfaceOpDataEntry> optVpnInterface =
- SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
- dataBroker, LogicalDatastoreType.CONFIGURATION, idOper);
- if (optVpnInterface.isPresent()) {
- dpId = optVpnInterface.get().getDpnId();
- break;
- }
- }
- }
- if (dpId == null || dpId.equals(BigInteger.ZERO)) {
- LOG.error("call : Unable to get DPN ID for the Interface {}", interfaceName);
- return futures;
- }
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
- if (routerInterface != null) {
- handleRouterInterfacesDownEvent(routerInterface.getRouterName(), interfaceName, dpId, writeOperTxn);
+ for (VpnInstanceNames vpnInterfaceVpnInstance : cfgVpnInterface.get().nonnullVpnInstanceNames().values()) {
+ String vpnName = vpnInterfaceVpnInstance.getVpnName();
+ InstanceIdentifier<VpnInterfaceOpDataEntry> idOper = NatUtil
+ .getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
+ Optional<VpnInterfaceOpDataEntry> optVpnInterface =
+ SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
+ dataBroker, LogicalDatastoreType.OPERATIONAL, idOper);
+ if (optVpnInterface.isPresent()) {
+ intfDpnId = optVpnInterface.get().getDpnId();
+ break;
}
- futures.add(writeOperTxn.submit());
- } catch (Exception e) {
- LOG.error("call : Exception observed in handling deletion of VPN Interface {}.", interfaceName, e);
}
- return futures;
}
- }
-
- private class NatInterfaceStateUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
- Interface original;
- Interface update;
-
- NatInterfaceStateUpdateWorker(Interface original, Interface update) {
- this.original = original;
- this.update = update;
+ if (Uint64.ZERO.equals(intfDpnId)) {
+ LOG.warn("remove : Could not retrieve dpnid for interface {} ", interfaceName);
+ return;
}
-
- @Override
- @SuppressWarnings("checkstyle:IllegalCatch")
- public List<ListenableFuture<Void>> call() {
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- try {
- final String interfaceName = update.getName();
- LOG.trace("call : Received interface {} state change event", interfaceName);
- BigInteger dpId = null;
- try {
- dpId = NatUtil.getDpIdFromInterface(update);
- } catch (Exception e) {
- LOG.error("call : Unable to retrieve DPN ID from Interface operational data "
- + "store for Interface {}", update.getName(), e);
- InstanceIdentifier<VpnInterface> id = NatUtil.getVpnInterfaceIdentifier(interfaceName);
- Optional<VpnInterface> cfgVpnInterface =
- SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
- dataBroker, LogicalDatastoreType.CONFIGURATION, id);
- if (!cfgVpnInterface.isPresent()) {
- LOG.warn("call : Interface {} is not a VPN Interface, ignoring.", interfaceName);
- return futures;
- }
- for (VpnInstanceNames vpnInterfaceVpnInstance : cfgVpnInterface.get().getVpnInstanceNames()) {
- String vpnName = vpnInterfaceVpnInstance.getVpnName();
- InstanceIdentifier<VpnInterfaceOpDataEntry> idOper = NatUtil
- .getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
- Optional<VpnInterfaceOpDataEntry> optVpnInterface =
- SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
- dataBroker, LogicalDatastoreType.OPERATIONAL, idOper);
- if (optVpnInterface.isPresent()) {
- dpId = optVpnInterface.get().getDpnId();
- break;
- }
- }
- }
- if (dpId == null || dpId.equals(BigInteger.ZERO)) {
- LOG.error("call : Unable to get DPN ID for the Interface {}", interfaceName);
- return futures;
- }
- LOG.debug("call : DPN ID {} for the interface {} ", dpId, interfaceName);
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
- if (routerInterface != null) {
- Interface.OperStatus originalOperStatus = original.getOperStatus();
- Interface.OperStatus updateOperStatus = update.getOperStatus();
- if (originalOperStatus != updateOperStatus) {
- String routerName = routerInterface.getRouterName();
- if (updateOperStatus == Interface.OperStatus.Unknown) {
- LOG.debug("call : DPN {} connnected to the interface {} has gone down."
- + "Hence clearing the dpn-vpninterfaces-list entry from the"
- + " neutron-router-dpns model in the ODL:L3VPN", dpId, interfaceName);
- // If the interface state is unknown, it means that the corresponding DPN has gone down.
- // So remove the dpn-vpninterfaces-list from the neutron-router-dpns model.
- NatUtil.removeFromNeutronRouterDpnsMap(dataBroker, routerName, dpId, writeOperTxn);
- } else if (updateOperStatus == Interface.OperStatus.Up) {
- LOG.debug("call : DPN {} connnected to the interface {} has come up. Hence adding"
- + " the dpn-vpninterfaces-list entry from the neutron-router-dpns model"
- + " in the ODL:L3VPN", dpId, interfaceName);
- handleRouterInterfacesUpEvent(routerName, interfaceName, writeOperTxn);
- }
- }
- }
- futures.add(writeOperTxn.submit());
- } catch (Exception e) {
- LOG.error("call : Exception observed in handling updation of VPN Interface {}.", update.getName(), e);
- }
- return futures;
+ RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
+ if (routerInterface != null) {
+ this.southboundEventHandlers.handleUpdate(original, update, intfDpnId, routerInterface);
+ } else {
+ LOG.info("update : Router-Interface Mapping not found for Interface : {}", interfaceName);
}
}
}