<feature name='odl-ovsdb-hwvtepsouthbound' version='${project.version}' description='OpenDaylight :: hwvtepsouthbound'>
<feature version='${controller.mdsal.version}'>odl-mdsal-broker</feature>
<feature version='${project.version}'>odl-ovsdb-hwvtepsouthbound-api</feature>
+ <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.ovsdb/hwvtepsouthbound-impl/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.ovsdb/library/{{VERSION}}</bundle>
<bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/{{VERSION}}</bundle>
<artifactId>schema.hardwarevtep</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>utils.mdsal-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- Testing Dependencies -->
<dependency>
<groupId>junit</groupId>
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.ReconciliationManager;
import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.ReconciliationTask;
+import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration.HwvtepReconciliationTask;
import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.connection.ConnectionReconciliationTask;
import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.HwvtepGlobalRemoveCommand;
import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionCommand;
import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.Global;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
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.HwvtepPhysicalSwitchAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
}
}
- private HwvtepConnectionInstance getConnectionInstance(HwvtepPhysicalSwitchAttributes pNode) {
+ public HwvtepConnectionInstance getConnectionInstance(HwvtepPhysicalSwitchAttributes pNode) {
Optional<HwvtepGlobalAugmentation> optional = HwvtepSouthboundUtil.getManagingNode(db, pNode);
if(optional.isPresent()) {
return getConnectionInstance(optional.get().getConnectionInfo());
}
}
+ public void stopConfigurationReconciliation(final InstanceIdentifier<Node> nodeIid) {
+ final ReconciliationTask task = new HwvtepReconciliationTask(
+ reconciliationManager, HwvtepConnectionManager.this, nodeIid, null, null, db);
+
+ reconciliationManager.dequeue(task);
+ }
+
+ public void reconcileConfigurations(final HwvtepConnectionInstance client, Node psNode) {
+ final InstanceIdentifier<Node> nodeIid = client.getInstanceIdentifier();
+ final ReconciliationTask task = new HwvtepReconciliationTask(
+ reconciliationManager, HwvtepConnectionManager.this, nodeIid, psNode, client, db);
+
+ reconciliationManager.enqueue(task);
+ }
+
private void removeConnectionInstance(ConnectionInfo key) {
ConnectionInfo connectionInfo = HwvtepSouthboundMapper.suppressLocalIpPort(key);
clients.remove(connectionInfo);
return;
}
//Connection detail need to be cached, irrespective of ownership result.
- putConnectionInstance(hwvtepConnectionInstance.getMDConnectionInfo(),hwvtepConnectionInstance);
+ putConnectionInstance(hwvtepConnectionInstance.getMDConnectionInfo(), hwvtepConnectionInstance);
if (ownershipChange.isOwner() == hwvtepConnectionInstance.getHasDeviceOwnership()) {
LOG.debug("handleOwnershipChanged: no change in ownership for {}. Ownership status is : {}",
new VlanBindingsKey(vBindings.getKey()));
}
+
+ public static InstanceIdentifier<Node> createInstanceIdentifier() {
+ InstanceIdentifier<Node> path = InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+ .child(Node.class);
+ return path;
+ }
}
import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration.HwvtepReconciliationManager;
import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvoker;
import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvokerImpl;
import org.opendaylight.ovsdb.lib.OvsdbConnection;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
private EntityOwnershipCandidateRegistration registration;
private HwvtepsbPluginInstanceEntityOwnershipListener providerOwnershipChangeListener;
private HwvtepDataChangeListener hwvtepDTListener;
+ private HwvtepReconciliationManager hwvtepReconciliationManager;
public HwvtepSouthboundProvider(final DataBroker dataBroker,
final EntityOwnershipService entityOwnershipServiceDependency,
this.entityOwnershipService = entityOwnershipServiceDependency;
registration = null;
this.ovsdbConnection = ovsdbConnection;
-
HwvtepSouthboundUtil.setInstanceIdentifierCodec(new InstanceIdentifierCodec(schemaService,
bindingNormalizedNodeSerializer));
LOG.info("HwvtepSouthboundProvider ovsdbConnectionService: {}", ovsdbConnection);
txInvoker = new TransactionInvokerImpl(db);
cm = new HwvtepConnectionManager(db, txInvoker, entityOwnershipService);
hwvtepDTListener = new HwvtepDataChangeListener(db, cm);
-
+ hwvtepReconciliationManager = new HwvtepReconciliationManager(db, cm);
//Register listener for entityOnwership changes
providerOwnershipChangeListener =
new HwvtepsbPluginInstanceEntityOwnershipListener(this,this.entityOwnershipService);
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
+import java.util.concurrent.ExecutionException;
+
public class HwvtepSouthboundUtil {
private static final Logger LOG = LoggerFactory.getLogger(HwvtepSouthboundUtil.class);
--- /dev/null
+/*
+ * Copyright (c) 2016 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration;
+
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class DataObjectModificationImpl<T extends DataObject> implements DataObjectModification<T> {
+
+ private Collection<DataObjectModification<? extends DataObject>> childNodesCache = new ArrayList<>();
+ InstanceIdentifier<T> nodeId;
+ T newNode;
+ T oldNode;
+
+ public DataObjectModificationImpl(InstanceIdentifier<T> nodeId, T newData, T oldData) {
+ this.nodeId = nodeId;
+ this.newNode = newData;
+ this.oldNode = oldData;
+ }
+
+
+ @Override
+ public T getDataBefore() {
+ return oldNode;
+ }
+
+ @Override
+ public T getDataAfter() {
+ return newNode;
+ }
+
+ @Override
+ public Class<T> getDataType() {
+ return (Class<T>) newNode.getClass();
+ }
+
+ @Override
+ public InstanceIdentifier.PathArgument getIdentifier() {
+ return nodeId.getPathArguments().iterator().next();
+ }
+
+ @Override
+ public ModificationType getModificationType() {
+ return ModificationType.WRITE;
+
+ }
+
+ @Override
+ public Collection<DataObjectModification<? extends DataObject>> getModifiedChildren() {
+ return childNodesCache;
+ }
+
+ @Override
+ public DataObjectModification<? extends DataObject> getModifiedChild(final InstanceIdentifier.PathArgument arg) {
+ return null;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <C extends Identifiable<K> & ChildOf<? super T>, K extends Identifier<C>> DataObjectModification<C>
+ getModifiedChildListItem(final Class<C> listItem, final K listKey) {
+ return (DataObjectModification<C>) getModifiedChild(
+ new InstanceIdentifier.IdentifiableItem<>(listItem, listKey));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <C extends ChildOf<? super T>> DataObjectModification<C> getModifiedChildContainer(final Class<C> arg) {
+ return (DataObjectModification<C>) getModifiedChild(new InstanceIdentifier.Item<>(arg));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <C extends Augmentation<T> & DataObject> DataObjectModification<C> getModifiedAugmentation(
+ final Class<C> augmentation) {
+ return (DataObjectModification<C>) getModifiedChild(new InstanceIdentifier.Item<>(augmentation));
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{identifier = " + nodeId +"}";
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration;
+
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class DataTreeModificationImpl<T extends DataObject> implements DataTreeModification {
+
+ InstanceIdentifier<T> nodeId;
+ T newNode;
+ T oldNode;
+
+ public DataTreeModificationImpl(InstanceIdentifier<T> nodeId, T newNode, T oldNode) {
+ this.nodeId = nodeId;
+ this.newNode = newNode;
+ this.oldNode = oldNode;
+ }
+
+ @Override
+ public DataTreeIdentifier<T> getRootPath() {
+ return new DataTreeIdentifier<T>(LogicalDatastoreType.CONFIGURATION, nodeId);
+ }
+
+ @Override
+ public DataObjectModification<T> getRootNode() {
+ return new DataObjectModificationImpl<T>(nodeId, newNode, oldNode);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+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.HwvtepGlobalAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacs;
+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.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class GlobalConfigOperationalChangeGetter {
+
+ public static DataTreeModification<Node> getModification(InstanceIdentifier<Node> nodeId, Node configNode,
+ Node opNode) {
+
+ NodeBuilder newNodeBuilder = getNodeBuilderFromNode(configNode);
+ NodeBuilder oldNodeBuilder = getNodeBuilderFromNode(opNode);
+
+ HwvtepGlobalAugmentationBuilder newAugmentation = getAugmentationFromNode(configNode);
+ HwvtepGlobalAugmentationBuilder oldAugmentation = getAugmentationFromNode(opNode);
+
+ //fire removal of local ucast macs so that logical switches will be deleted
+ fillLocalMcacsToBeRemoved(oldAugmentation, configNode, opNode);
+
+ newNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, newAugmentation.build());
+ oldNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, oldAugmentation.build());
+
+ return new DataTreeModificationImpl<Node>(nodeId, newNodeBuilder.build(), oldNodeBuilder.build());
+ }
+
+ static void fillLocalMcacsToBeRemoved(HwvtepGlobalAugmentationBuilder oldAugmentation, Node configNode,
+ Node opNode) {
+ Set<String> logicalSwitchNamesToBeRemoved = getLogicalSwitchesToBeRemoved(configNode, opNode);
+ List<LocalUcastMacs> localUcastMacsToBeRemoved = getLocalUcastMacsToBeRemoved(opNode,
+ logicalSwitchNamesToBeRemoved);
+ List<LocalMcastMacs> localMcastMacsToBeRemoved = getLocalMcastMacsToBeRemoved(opNode,
+ logicalSwitchNamesToBeRemoved);
+
+ oldAugmentation.setLocalUcastMacs(localUcastMacsToBeRemoved);
+ oldAugmentation.setLocalMcastMacs(localMcastMacsToBeRemoved);
+ }
+
+ static List<LocalUcastMacs> getLocalUcastMacsToBeRemoved(Node opNode, final Set<String> removedSwitchNames) {
+ if (opNode == null || opNode.getAugmentation(HwvtepGlobalAugmentation.class) == null) {
+ return null;
+ }
+ List<LocalUcastMacs> localUcastMacs = opNode.getAugmentation(HwvtepGlobalAugmentation.class).
+ getLocalUcastMacs();
+ if (localUcastMacs == null) {
+ return null;
+ }
+ Iterable<LocalUcastMacs> removedLocalUcastMacs = Iterables.filter(localUcastMacs,
+ new Predicate<LocalUcastMacs>() {
+ @Override
+ public boolean apply(LocalUcastMacs mac) {
+ String ls = mac.getLogicalSwitchRef().getValue().firstKeyOf(LogicalSwitches.class).
+ getHwvtepNodeName().getValue();
+ if (removedSwitchNames.contains(ls)) {
+ return true;
+ }
+ return false;
+ }
+ });
+ return Lists.newArrayList(removedLocalUcastMacs);
+ }
+
+ static List<LocalMcastMacs> getLocalMcastMacsToBeRemoved(Node opNode, final Set<String> removedSwitchNames) {
+ if (opNode == null || opNode.getAugmentation(HwvtepGlobalAugmentation.class) == null) {
+ return null;
+ }
+ List<LocalMcastMacs> localMcastMacs = opNode.getAugmentation(HwvtepGlobalAugmentation.class).
+ getLocalMcastMacs();
+ if (localMcastMacs == null) {
+ return null;
+ }
+ Iterable<LocalMcastMacs> removedLocalMcastMacs = Iterables.filter(localMcastMacs,
+ new Predicate<LocalMcastMacs>() {
+ @Override
+ public boolean apply(LocalMcastMacs mac) {
+ String ls = mac.getLogicalSwitchRef().getValue().firstKeyOf(LogicalSwitches.class).
+ getHwvtepNodeName().getValue();
+ if (removedSwitchNames.contains(ls)) {
+ return true;
+ }
+ return false;
+ }
+ });
+ return Lists.newArrayList(removedLocalMcastMacs);
+ }
+
+ static Set<String> getLogicalSwitchesToBeRemoved(Node configNode, Node opNode) {
+ Set<String> opSwitchNames = new HashSet<>();
+ Set<String> cfgSwitchNames = new HashSet<>();
+ List<LogicalSwitches> cfgLogicalSwitches = Lists.newArrayList();
+
+ List<LogicalSwitches> opLogicalSwitches = opNode.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
+ if (configNode != null) {
+ cfgLogicalSwitches = configNode.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
+ }
+ if (opLogicalSwitches != null) {
+ for (LogicalSwitches ls : opLogicalSwitches) {
+ opSwitchNames.add(ls.getHwvtepNodeName().getValue());
+ }
+ }
+ if (cfgLogicalSwitches != null) {
+ for (LogicalSwitches ls : cfgLogicalSwitches) {
+ cfgSwitchNames.add(ls.getHwvtepNodeName().getValue());
+ }
+ }
+ final Set<String> removedSwitchNames = Sets.difference(opSwitchNames, cfgSwitchNames);
+ return removedSwitchNames;
+ }
+
+ static HwvtepGlobalAugmentationBuilder getAugmentationFromNode(Node node ) {
+ if (node == null) {
+ return new HwvtepGlobalAugmentationBuilder();
+ }
+ HwvtepGlobalAugmentation src = node.getAugmentation(HwvtepGlobalAugmentation.class);
+ HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder();
+ if (src != null) {
+ builder.setLogicalSwitches(src.getLogicalSwitches());
+ builder.setRemoteMcastMacs(src.getRemoteMcastMacs());
+ builder.setRemoteUcastMacs(src.getRemoteUcastMacs());
+ }
+ return builder;
+ }
+
+ static NodeBuilder getNodeBuilderFromNode(Node node) {
+ NodeBuilder newNodeBuilder;
+ if (node != null) {
+ newNodeBuilder = new NodeBuilder(node);
+ newNodeBuilder.removeAugmentation(HwvtepGlobalAugmentation.class);
+ } else {
+ newNodeBuilder = new NodeBuilder();
+ }
+ newNodeBuilder.setTerminationPoint(new ArrayList<>());
+ return newNodeBuilder;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration;
+
+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.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionManager;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+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.HwvtepPhysicalSwitchAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+
+public class HwvtepReconciliationManager implements ClusteredDataTreeChangeListener<Node>, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HwvtepReconciliationManager.class);
+ private ListenerRegistration<HwvtepReconciliationManager> registration;
+ private HwvtepConnectionManager hcm;
+ private DataBroker db;
+
+ public HwvtepReconciliationManager(DataBroker db, HwvtepConnectionManager hcm) {
+ this.db = db;
+ this.hcm = hcm;
+ registerListener(db);
+ }
+
+ private void registerListener(final DataBroker db) {
+ InstanceIdentifier<Node> iid = HwvtepSouthboundMapper.createInstanceIdentifier();
+ DataTreeIdentifier<Node> treeId =
+ new DataTreeIdentifier<Node>(LogicalDatastoreType.OPERATIONAL, iid);
+ LOG.trace("Registering listener for path {}", treeId);
+ registration = db.registerDataTreeChangeListener(treeId, HwvtepReconciliationManager.this);
+ }
+
+ @Override
+ public void close() throws Exception {
+ if(registration != null) {
+ registration.close();
+ }
+ }
+
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
+ processConnectedNodes(changes);
+ processDisconnectedNodes(changes);
+ }
+
+ private void processDisconnectedNodes(Collection<DataTreeModification<Node>> changes) {
+ for (DataTreeModification<Node> change : changes) {
+ final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<Node> mod = change.getRootNode();
+ Node deleted = getRemoved(mod);
+ if (deleted != null) {
+ if (deleted.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
+ LOG.trace("Cancel config reconciliation for node {}", deleted.getKey());
+ hcm.stopConfigurationReconciliation(key);
+ }
+ }
+ }
+ }
+
+ private void processConnectedNodes(Collection<DataTreeModification<Node>> changes) {
+ for (DataTreeModification<Node> change : changes) {
+ InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ DataObjectModification<Node> mod = change.getRootNode();
+ Node node = getCreated(mod);
+ if (node != null) {
+ PhysicalSwitchAugmentation physicalSwitch = node.getAugmentation(PhysicalSwitchAugmentation.class);
+ if (physicalSwitch != null) {
+ HwvtepConnectionInstance connection =
+ hcm.getConnectionInstance((HwvtepPhysicalSwitchAttributes)physicalSwitch);
+ if (connection != null) {
+ LOG.trace("Reconcile config for node {}, IP : {}", node.getKey(),
+ connection.getConnectionInfo().getRemoteAddress());
+ hcm.reconcileConfigurations(connection, node);
+ }
+ }
+ }
+ }
+ }
+
+ private Node getCreated(DataObjectModification<Node> mod) {
+ if((mod.getModificationType() == ModificationType.WRITE)
+ && (mod.getDataBefore() == null)){
+ return mod.getDataAfter();
+ }
+ return null;
+ }
+
+ private Node getRemoved(DataObjectModification<Node> mod) {
+ if(mod.getModificationType() == ModificationType.DELETE){
+ return mod.getDataBefore();
+ }
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionManager;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
+import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.ReconciliationManager;
+import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.ReconciliationTask;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.HwvtepOperationalState;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactCommandAggregator;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+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.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.ExecutionException;
+
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+
+public class HwvtepReconciliationTask extends ReconciliationTask {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HwvtepReconciliationTask.class);
+ private HwvtepConnectionInstance connectionInstance;
+ private DataBroker db;
+ private Node psNode;
+ private MdsalUtils mdsalUtils;
+
+ public HwvtepReconciliationTask(ReconciliationManager reconciliationManager,
+ HwvtepConnectionManager connectionManager,
+ InstanceIdentifier<?> nodeId,
+ Node psNode,
+ HwvtepConnectionInstance connectionInstance,
+ DataBroker db) {
+ super(reconciliationManager, connectionManager, nodeId, null);
+ this.db = db;
+ this.psNode = psNode;
+ this.connectionInstance = connectionInstance;
+ this.mdsalUtils = new MdsalUtils(db);
+ }
+
+ private void transactChangesToDevice(Collection<DataTreeModification<Node>> changes) {
+ HwvtepOperationalState hwvtepOperationalState = new HwvtepOperationalState(db, changes);
+ connectionInstance.transact(new TransactCommandAggregator(hwvtepOperationalState,changes));
+ }
+
+ @Override
+ public boolean reconcileConfiguration(HwvtepConnectionManager connectionManagerOfDevice) {
+ InstanceIdentifier<Node> psNodeIid = HwvtepSouthboundMapper.createInstanceIdentifier(psNode.getNodeId());
+ InstanceIdentifier<Node> nodeId = (InstanceIdentifier<Node>)nodeIid;
+ ReadOnlyTransaction tx = reconciliationManager.getDb().newReadOnlyTransaction();
+
+ Node globalConfigNode = mdsalUtils.read(CONFIGURATION, nodeId);
+ Node globalOpNode = mdsalUtils.read(OPERATIONAL, nodeId);
+ Node psConfigNode = mdsalUtils.read(CONFIGURATION, psNodeIid);
+
+ DataTreeModification<Node> change = null;
+ Collection<DataTreeModification<Node>> changes = new ArrayList<>();
+ change = GlobalConfigOperationalChangeGetter.getModification(nodeId, globalConfigNode, globalOpNode);
+ changes.add(change);
+
+ change = SwitchConfigOperationalChangeGetter.getModification(psNodeIid, psConfigNode, psNode);
+ changes.add(change);
+
+ transactChangesToDevice(changes);
+ return true;
+ }
+
+ @Override
+ public void doRetry(boolean wasPreviousAttemptSuccessful) {
+ }
+
+ @Override
+ public void checkReadinessAndProcess() {
+ }
+
+ @Override
+ public long retryDelayInMills() {
+ return 0;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration;
+
+import com.google.common.collect.Lists;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SwitchConfigOperationalChangeGetter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SwitchConfigOperationalChangeGetter.class);
+
+ public static DataTreeModification<Node> getModification(InstanceIdentifier<Node> psNodeId,
+ Node configNode, Node operationalNode) {
+
+ NodeBuilder newNodeBuilder = getNodeBuilderFromNode(configNode);
+ NodeBuilder oldNodeBuilder = getNodeBuilderFromNode(operationalNode);
+
+ List<TerminationPoint> tpList = getPorts(configNode);
+ if (tpList.size() > 0) {
+ newNodeBuilder.setTerminationPoint(tpList);
+ }
+
+ tpList = getPorts(operationalNode);
+ if (tpList.size() > 0) {
+ oldNodeBuilder.setTerminationPoint(tpList);
+ }
+
+ return new DataTreeModificationImpl<Node>(psNodeId, newNodeBuilder.build(), oldNodeBuilder.build());
+
+ }
+
+
+ static NodeBuilder getNodeBuilderFromNode(Node node) {
+ NodeBuilder newNodeBuilder;
+ if (node != null) {
+ newNodeBuilder = new NodeBuilder(node);
+ newNodeBuilder.removeAugmentation(PhysicalSwitchAugmentation.class);
+ } else {
+ newNodeBuilder = new NodeBuilder();
+ }
+ List<TerminationPoint> emptyList = Lists.newArrayList();
+ newNodeBuilder.setTerminationPoint(emptyList);
+
+ return newNodeBuilder;
+ }
+
+
+ static List<TerminationPoint> getPorts(Node node) {
+ ArrayList<TerminationPoint> tpList = Lists.newArrayList();
+ if (node == null || node.getTerminationPoint() == null) {
+ return tpList;
+ }
+ for (TerminationPoint tp: node.getTerminationPoint()) {
+ TerminationPointBuilder terminationPointBuilder = new TerminationPointBuilder(tp);
+ terminationPointBuilder.removeAugmentation(HwvtepPhysicalPortAugmentation.class);
+
+ HwvtepPhysicalPortAugmentation augmentation = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
+ HwvtepPhysicalPortAugmentationBuilder builder = new HwvtepPhysicalPortAugmentationBuilder();
+ if (augmentation != null) {
+ builder = new HwvtepPhysicalPortAugmentationBuilder(augmentation);
+ }
+ if (augmentation != null && augmentation.getVlanBindings() != null && !augmentation.getVlanBindings().isEmpty() ) {
+ builder.setVlanBindings(augmentation.getVlanBindings());
+ terminationPointBuilder.addAugmentation(HwvtepPhysicalPortAugmentation.class, builder.build());
+ tpList.add(terminationPointBuilder.build());
+ }
+ }
+ return tpList;
+ }
+}
\ No newline at end of file
import java.util.Map;
import java.util.Map.Entry;
+import com.google.common.collect.Maps;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
+import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
public class HwvtepOperationalState {
private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperationalState.class);
private Map<InstanceIdentifier<Node>, Node> operationalNodes = new HashMap<>();
- ReadWriteTransaction transaction;
+ private ReadWriteTransaction transaction;
+ HashMap<InstanceIdentifier<TerminationPoint>, UUID> inflightLocators = Maps.newHashMap();
public HwvtepOperationalState(DataBroker db, Collection<DataTreeModification<Node>> changes) {
Map<InstanceIdentifier<Node>, Node> nodeCreateOrUpdate =
public ReadWriteTransaction getReadWriteTransaction() {
return transaction;
}
+
+ public void setPhysicalLocatorInFlight(InstanceIdentifier<TerminationPoint> iid,
+ UUID uuid) {
+ inflightLocators.put(iid, uuid);
+ }
+
+ public UUID getPhysicalLocatorInFlight(InstanceIdentifier<TerminationPoint> iid) {
+ return inflightLocators.get(iid);
+ }
}
lswitchListBefore.removeAll(lswitchListUpdated);
}
//then exclude updated ones
- for (LogicalSwitches lswitchBefore: lswitchListBefore) {
- int i = 0;
- for(; i < lswitchListUpdated.size(); i++) {
- if (lswitchBefore.getHwvtepNodeName().equals(lswitchListUpdated.get(i).getHwvtepNodeName())) {
- break;
+ if (lswitchListUpdated != null) {
+ for (LogicalSwitches lswitchBefore : lswitchListBefore) {
+ int i = 0;
+ for (; i < lswitchListUpdated.size(); i++) {
+ if (lswitchBefore.getHwvtepNodeName().equals(lswitchListUpdated.get(i).getHwvtepNodeName())) {
+ break;
+ }
+ }
+ if (i == lswitchListUpdated.size()) {
+ lswitchListRemoved.add(lswitchBefore);
}
}
- if (i == lswitchListUpdated.size()) {
- lswitchListRemoved.add(lswitchBefore);
- }
+ } else {
+ lswitchListRemoved.addAll(lswitchListBefore);
}
if (!lswitchListRemoved.isEmpty()) {
result.put(key, lswitchListRemoved);
macListBefore.removeAll(macListUpdated);
}
//then exclude updated localMcastMacs
- for (LocalMcastMacs macBefore: macListBefore) {
- int i = 0;
- for(; i < macListUpdated.size(); i++) {
- if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
- break;
+ if (macListUpdated != null) {
+ for (LocalMcastMacs macBefore : macListBefore) {
+ int i = 0;
+ for (; i < macListUpdated.size(); i++) {
+ if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
+ break;
+ }
+ }
+ if (i == macListUpdated.size()) {
+ macListRemoved.add(macBefore);
}
}
- if (i == macListUpdated.size()) {
- macListRemoved.add(macBefore);
- }
+ } else {
+ macListRemoved.addAll(macListBefore);
}
if (!macListRemoved.isEmpty()) {
result.put(key, macListRemoved);
macListBefore.removeAll(macListUpdated);
}
//then exclude updated remoteMcastMacs
- for (RemoteMcastMacs macBefore: macListBefore) {
- int i = 0;
- for(; i < macListUpdated.size(); i++) {
- if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
- break;
+ if (macListUpdated != null) {
+ for (RemoteMcastMacs macBefore : macListBefore) {
+ int i = 0;
+ for (; i < macListUpdated.size(); i++) {
+ if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
+ break;
+ }
+ }
+ if (i == macListUpdated.size()) {
+ macListRemoved.add(macBefore);
}
}
- if (i == macListUpdated.size()) {
- macListRemoved.add(macBefore);
- }
+ } else {
+ macListRemoved.addAll(macListBefore);
}
if (!macListRemoved.isEmpty()) {
result.put(key, macListRemoved);
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocatorSet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
HwvtepPhysicalLocatorAugmentation locatorAugmentation = operationalLocatorOptional.get();
locatorUuid = new UUID(locatorAugmentation.getPhysicalLocatorUuid().getValue());
} else {
- //if no, get it from config DS and create id
- Optional<TerminationPoint> configLocatorOptional =
- readNodeFromConfig(hwvtepOperationalState.getReadWriteTransaction(), iid);
- if (configLocatorOptional.isPresent()) {
- HwvtepPhysicalLocatorAugmentation locatorAugmentation =
- configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
- locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
- } else {
- LOG.warn("Create or update localMcastMac: No physical locator found in operational datastore!"
- + "Its indentifier is {}", locator.getLocatorRef().getValue());
+ locatorUuid = hwvtepOperationalState.getPhysicalLocatorInFlight(iid);
+ if (locatorUuid == null) {
+ //if no, get it from config DS and create id
+ Optional<TerminationPoint> configLocatorOptional =
+ readNodeFromConfig(hwvtepOperationalState.getReadWriteTransaction(), iid);
+ if (configLocatorOptional.isPresent()) {
+ HwvtepPhysicalLocatorAugmentation locatorAugmentation =
+ configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
+ locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
+ hwvtepOperationalState.setPhysicalLocatorInFlight(iid, locatorUuid);
+ } else {
+ LOG.warn("Create or update localMcastMac: No physical locator found in operational datastore!"
+ + "Its indentifier is {}", locator.getLocatorRef().getValue());
+ }
}
}
if (locatorUuid != null) {
}
}
+ static String sanitizeUUID(HwvtepNodeName hwvtepNodeName) {
+ //ovs is not accepting '-' in the named uuids
+ return hwvtepNodeName.getValue().replaceAll("-", "_");
+ }
+
public static String getLogicalSwitchId(LogicalSwitches lswitch){
- return HwvtepSouthboundConstants.LOGICALSWITCH_UUID_PREFIX+lswitch.getHwvtepNodeName().getValue();
+ return HwvtepSouthboundConstants.LOGICALSWITCH_UUID_PREFIX + sanitizeUUID(lswitch.getHwvtepNodeName());
}
public static UUID getLogicalSwitchUUID(InstanceIdentifier<LogicalSwitches> lswitchIid){
- return new UUID(HwvtepSouthboundConstants.LOGICALSWITCH_UUID_PREFIX+lswitchIid.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue());
+ return new UUID(HwvtepSouthboundConstants.LOGICALSWITCH_UUID_PREFIX +
+ sanitizeUUID(lswitchIid.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName()));
}
}
macListBefore.removeAll(macListUpdated);
}
//then exclude updated remoteUcastMacs
- for (LocalUcastMacs macBefore: macListBefore) {
- int i = 0;
- for(; i < macListUpdated.size(); i++) {
- if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
- break;
+ if (macListUpdated != null) {
+ for (LocalUcastMacs macBefore : macListBefore) {
+ int i = 0;
+ for (; i < macListUpdated.size(); i++) {
+ if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
+ break;
+ }
+ }
+ if (i == macListUpdated.size()) {
+ macListRemoved.add(macBefore);
}
}
- if (i == macListUpdated.size()) {
- macListRemoved.add(macBefore);
- }
+ } else {
+ macListRemoved.addAll(macListBefore);
}
if (!macListRemoved.isEmpty()) {
result.put(key, macListRemoved);
macListBefore.removeAll(macListUpdated);
}
//then exclude updated remoteUcastMacs
- for (RemoteUcastMacs macBefore: macListBefore) {
- int i = 0;
- for(; i < macListUpdated.size(); i++) {
- if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
- break;
+ if (macListUpdated != null) {
+ for (RemoteUcastMacs macBefore : macListBefore) {
+ int i = 0;
+ for (; i < macListUpdated.size(); i++) {
+ if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
+ break;
+ }
+ }
+ if (i == macListUpdated.size()) {
+ macListRemoved.add(macBefore);
}
}
- if (i == macListUpdated.size()) {
- macListRemoved.add(macBefore);
- }
+ } else {
+ macListRemoved.addAll(macListBefore);
}
if (!macListRemoved.isEmpty()) {
result.put(key, macListRemoved);
} else {
//TODO: need to optimize by eliminating reading Configuration datastore
//if no, get it from config DS and create id
- Optional<TerminationPoint> configLocatorOptional =
- TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid);
- if (configLocatorOptional.isPresent()) {
- HwvtepPhysicalLocatorAugmentation locatorAugmentation =
- configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
- locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
- } else {
- LOG.warn("Create or update remoteUcastMac: No physical locator found in operational datastore!"
- + "Its indentifier is {}", inputMac.getLocatorRef().getValue());
+ locatorUuid = getOperationalState().getPhysicalLocatorInFlight(iid);
+ if (locatorUuid == null) {
+ Optional<TerminationPoint> configLocatorOptional =
+ TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid);
+ if (configLocatorOptional.isPresent()) {
+ HwvtepPhysicalLocatorAugmentation locatorAugmentation =
+ configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
+ locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
+ getOperationalState().setPhysicalLocatorInFlight(iid, locatorUuid);
+ } else {
+ LOG.warn("Create or update remoteUcastMac: No physical locator found in operational datastore!"
+ + "Its indentifier is {}", inputMac.getLocatorRef().getValue());
+ }
}
}
if (locatorUuid != null) {
commands.add(new HwvtepManagerUpdateCommand(key, updates, dbSchema));
commands.add(new HwvtepManagerRemoveCommand(key, updates, dbSchema));
commands.add(new HwvtepLogicalSwitchUpdateCommand(key, updates, dbSchema));
- commands.add(new HwvtepLogicalSwitchRemoveCommand(key, updates, dbSchema));
commands.add(new HwvtepPhysicalPortUpdateCommand(key, updates, dbSchema));
commands.add(new HwvtepPhysicalPortRemoveCommand(key, updates, dbSchema));
commands.add(new HwvtepPhysicalLocatorUpdateCommand(key, updates, dbSchema));
commands.add(new HwvtepMcastMacsLocalUpdateCommand(key, updates, dbSchema));
commands.add(new HwvtepMcastMacsRemoteUpdateCommand(key, updates, dbSchema));
commands.add(new HwvtepMacEntriesRemoveCommand(key, updates, dbSchema));
+ commands.add(new HwvtepLogicalSwitchRemoveCommand(key, updates, dbSchema));
}
@Override