X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=elanmanager%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Felan%2Fl2gw%2Flisteners%2FLocalUcastMacListener.java;h=817dfb4f6e3c37946b3de8df5c63da8581fdaf02;hb=2f0569ed75ef8a1fb60f992d19c8bbdf92ff45bf;hp=831d81dd0f6453efd75ad09b7e59052dbc9a2209;hpb=993aa2a49eb88f074aee0958f3740860e3d6d675;p=netvirt.git diff --git a/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/LocalUcastMacListener.java b/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/LocalUcastMacListener.java index 831d81dd0f..817dfb4f6e 100644 --- a/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/LocalUcastMacListener.java +++ b/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/LocalUcastMacListener.java @@ -7,80 +7,86 @@ */ package org.opendaylight.netvirt.elan.l2gw.listeners; +import static org.opendaylight.genius.infra.Datastore.CONFIGURATION; +import static org.opendaylight.genius.infra.Datastore.OPERATIONAL; + import com.google.common.collect.Sets; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.function.Predicate; -import javax.annotation.Nullable; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Singleton; -import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; -import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.genius.infra.ManagedNewTransactionRunner; import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl; import org.opendaylight.genius.utils.batching.ResourceBatchingManager; -import org.opendaylight.genius.utils.hwvtep.HwvtepHACache; +import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache; import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils; import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; -import org.opendaylight.infrautils.utils.concurrent.ListenableFutures; +import org.opendaylight.infrautils.utils.concurrent.LoggingFutures; +import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.DataTreeModification; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.netvirt.elan.cache.ElanInstanceCache; import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil; import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpClusteredListener; +import org.opendaylight.netvirt.elan.l2gw.recovery.impl.L2GatewayServiceRecoveryHandler; import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils; import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils; import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice; +import org.opendaylight.serviceutils.srm.RecoverableListener; +import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; -import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Singleton public class LocalUcastMacListener extends ChildListener - implements ClusteredDataTreeChangeListener { + implements ClusteredDataTreeChangeListener, RecoverableListener { + private static final Logger LOG = LoggerFactory.getLogger(LocalUcastMacListener.class); public static final String NODE_CHECK = "physical"; private static final Predicate> IS_PS_NODE_IID = (iid) -> iid.firstKeyOf(Node.class).getNodeId().getValue().contains(NODE_CHECK); - private static final Predicate> IS_NOT_HA_CHILD = - (iid) -> !HwvtepHACache.getInstance().isHAEnabledDevice(iid) - && !iid.firstKeyOf(Node.class).getNodeId().getValue().contains(HwvtepHAUtil.PHYSICALSWITCH); - - private static final Predicate> IS_HA_CHILD = - (iid) -> HwvtepHACache.getInstance().isHAEnabledDevice(iid); - private final ManagedNewTransactionRunner txRunner; private final ElanL2GatewayUtils elanL2GatewayUtils; private final HAOpClusteredListener haOpClusteredListener; private final JobCoordinator jobCoordinator; private final ElanInstanceCache elanInstanceCache; + private final HwvtepNodeHACache hwvtepNodeHACache; @Inject public LocalUcastMacListener(final DataBroker dataBroker, final HAOpClusteredListener haOpClusteredListener, final ElanL2GatewayUtils elanL2GatewayUtils, final JobCoordinator jobCoordinator, - final ElanInstanceCache elanInstanceCache) { + final ElanInstanceCache elanInstanceCache, + final HwvtepNodeHACache hwvtepNodeHACache, + final L2GatewayServiceRecoveryHandler l2GatewayServiceRecoveryHandler, + final ServiceRecoveryRegistry serviceRecoveryRegistry) { super(dataBroker, false); this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker); this.elanL2GatewayUtils = elanL2GatewayUtils; this.haOpClusteredListener = haOpClusteredListener; this.jobCoordinator = jobCoordinator; this.elanInstanceCache = elanInstanceCache; + this.hwvtepNodeHACache = hwvtepNodeHACache; + serviceRecoveryRegistry.addRecoverableListener(l2GatewayServiceRecoveryHandler.buildServiceRegistryKey(), this); } @Override @@ -88,11 +94,28 @@ public class LocalUcastMacListener extends ChildListener parent) { - return IS_NOT_HA_CHILD.test(parent); + return isNotHAChild(parent); } protected String getElanName(final LocalUcastMacs mac) { @@ -113,9 +136,9 @@ public class LocalUcastMacListener extends ChildListener identifier, final LocalUcastMacs macRemoved) { String hwvtepNodeId = identifier.firstKeyOf(Node.class).getNodeId().getValue(); - String macAddress = macRemoved.getMacEntryKey().getValue().toLowerCase(Locale.getDefault()); + MacAddress macAddress = IetfYangUtil.INSTANCE.canonizeMacAddress(macRemoved.getMacEntryKey()); - LOG.trace("LocalUcastMacs {} removed from {}", macAddress, hwvtepNodeId); + LOG.trace("LocalUcastMacs {} removed from {}", macAddress.getValue(), hwvtepNodeId); ResourceBatchingManager.getInstance().delete(ResourceBatchingManager.ShardResource.CONFIG_TOPOLOGY, identifier); @@ -133,11 +156,11 @@ public class LocalUcastMacListener extends ChildListener aug = mod.getModifiedAugmentation( HwvtepGlobalAugmentation.class); if (aug != null && getModificationType(aug) != null) { - Collection> children = aug.getModifiedChildren(); - children.stream() + aug.getModifiedChildren().stream() .filter(childMod -> getModificationType(childMod) != null) .filter(childMod -> childMod.getDataType() == LocalUcastMacs.class) .forEach(childMod -> { @@ -192,7 +213,7 @@ public class LocalUcastMacListener extends ChildListener iid = parentIid .augmentation(HwvtepGlobalAugmentation.class) - .child(LocalUcastMacs.class, mac.getKey()); + .child(LocalUcastMacs.class, mac.key()); result.put(iid, (DataObjectModification) childMod); }); } @@ -205,28 +226,30 @@ public class LocalUcastMacListener extends ChildListener { - haOpClusteredListener.onGlobalNodeAdd(nodeIid, modification.getRootNode().getDataAfter(), tx); - if (!IS_HA_CHILD.test(nodeIid)) { + // TODO skitt we're only using read transactions here + LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, + tx -> haOpClusteredListener.onGlobalNodeAdd(nodeIid, modification.getRootNode().getDataAfter(), tx)), LOG, + "Error processing added parent"); + if (!isHAChild(nodeIid)) { + LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> { LOG.trace("On parent add {}", nodeIid); Node operNode = modification.getRootNode().getDataAfter(); - Set configMacs = - getMacs(tx.read(LogicalDatastoreType.CONFIGURATION, nodeIid).checkedGet().orNull()); + Set configMacs = getMacs(tx.read(nodeIid).get().orElse(null)); Set operMacs = getMacs(operNode); Set staleMacs = Sets.difference(configMacs, operMacs); staleMacs.forEach(staleMac -> removed(getMacIid(nodeIid, staleMac), staleMac)); - } - }), LOG, "Error processing added parent"); + }), LOG, "Error processing added parent"); + } } InstanceIdentifier getMacIid(InstanceIdentifier nodeIid, LocalUcastMacs mac) { return nodeIid.augmentation(HwvtepGlobalAugmentation.class) - .child(LocalUcastMacs.class, mac.getKey()); + .child(LocalUcastMacs.class, mac.key()); } - private Set getMacs(@Nullable Node node) { + private static Set getMacs(@Nullable Node node) { if (node != null) { - HwvtepGlobalAugmentation augmentation = node.getAugmentation(HwvtepGlobalAugmentation.class); + HwvtepGlobalAugmentation augmentation = node.augmentation(HwvtepGlobalAugmentation.class); if (augmentation != null && augmentation.getLocalUcastMacs() != null) { return new HashSet<>(augmentation.getLocalUcastMacs()); } @@ -247,4 +270,13 @@ public class LocalUcastMacListener extends ChildListener nodeId) { + return !hwvtepNodeHACache.isHAEnabledDevice(nodeId) + && !nodeId.firstKeyOf(Node.class).getNodeId().getValue().contains(HwvtepHAUtil.PHYSICALSWITCH); + } + + private boolean isHAChild(InstanceIdentifier nodeId) { + return hwvtepNodeHACache.isHAEnabledDevice(nodeId); + } }