bug 8712 vlan bindings update fix 06/61606/8
authorK.V Suneelu Verma <k.v.suneelu.verma@ericsson.com>
Mon, 14 Aug 2017 12:01:21 +0000 (17:31 +0530)
committersuneel verma <k.v.suneelu.verma@ericsson.com>
Wed, 25 Oct 2017 09:26:33 +0000 (09:26 +0000)
when global node and physical switch node are updated in same transaction
from application, vlan bindings are missing.

Make vlan bindings participate in dependency workflow.

Do not create/delete port from controller.
Only update the port from controller.
port creation happens from device always.

Added port reconciliation when port is added later.

Change-Id: Ic86a3545428e186f3aeb26c8a36a783f774ecf53
Signed-off-by: K.V Suneelu Verma <k.v.suneelu.verma@ericsson.com>
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalRouterUpdateCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortUpdateCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepPhysicalPortRemoveCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepPhysicalPortUpdateCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepPhysicalSwitchRemoveCommand.java

index 5d56cbf8a0ca53f15246a20113a6778fef523712..2f37a2a220a92452e4a90fe2494ca0e78c0dd7d8 100644 (file)
@@ -66,7 +66,7 @@ public class LogicalRouterUpdateCommand extends AbstractTransactCommand<LogicalR
             LogicalRouter logicalRouter = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalRouter.class);
             setDescription(logicalRouter, lrouter);
 
-            setSwitchBindings(logicalRouter, lrouter.getSwitchBindings());
+            setSwitchBindings(transaction, logicalRouter, lrouter.getSwitchBindings());
             setStaticRoutes(logicalRouter, lrouter.getStaticRoutes());
             setAclBindings(logicalRouter, lrouter.getAclBindings());
 
@@ -108,7 +108,7 @@ public class LogicalRouterUpdateCommand extends AbstractTransactCommand<LogicalR
         }
     }
 
-    private void setSwitchBindings(final LogicalRouter logicalRouter, final List<SwitchBindings> switchBindings) {
+    private void setSwitchBindings(final TransactionBuilder transaction, final LogicalRouter logicalRouter, final List<SwitchBindings> switchBindings) {
         if (switchBindings != null) {
             Map<String, UUID> bindingMap = new HashMap<String, UUID>();
             for (SwitchBindings switchBinding : switchBindings) {
@@ -123,7 +123,7 @@ public class LogicalRouterUpdateCommand extends AbstractTransactCommand<LogicalR
                             new UUID(logicalSwitchUuid.getValue()));
                 }else{
                     bindingMap.put(switchBinding.getDestinationAddress().getIpv4Prefix().getValue(),
-                            TransactUtils.getLogicalSwitchUUID(lswitchIid));
+                            TransactUtils.getLogicalSwitchUUID(transaction, getOperationalState(), lswitchIid));
                 }
             }
             logicalRouter.setSwitchBinding(bindingMap);
index f8b896e0a234960f5c58d6e6bd97adfed326de28..25fdfecb40b190c8872fbc939deaa57eb73a4ca2 100644 (file)
@@ -18,23 +18,31 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import com.google.common.collect.Lists;
 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.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
 import org.opendaylight.ovsdb.lib.notation.Mutator;
 import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 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.PhysicalSwitchAugmentation;
 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.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
 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.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -42,6 +50,7 @@ import com.google.common.base.Optional;
 
 public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
     private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortUpdateCommand.class);
+    private static final VlanBindingsUnMetDependencyGetter DEPENDENCY_GETTER = new VlanBindingsUnMetDependencyGetter();
 
     public PhysicalPortUpdateCommand(HwvtepOperationalState state,
             Collection<DataTreeModification<Node>> changes) {
@@ -57,7 +66,7 @@ public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
         if (!createds.isEmpty()) {
             for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> created:
                 createds.entrySet()) {
-                updatePhysicalPort(transaction,  created.getKey(), created.getValue(), createdPhysicalSwitches);
+                updatePhysicalPort(transaction,  created.getKey(), created.getValue());
             }
         }
         Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updateds =
@@ -65,49 +74,29 @@ public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
         if (!updateds.isEmpty()) {
             for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updated:
                 updateds.entrySet()) {
-                updatePhysicalPort(transaction,  updated.getKey(), updated.getValue(), createdPhysicalSwitches);
+                updatePhysicalPort(transaction,  updated.getKey(), updated.getValue());
             }
         }
     }
 
-    private void updatePhysicalPort(TransactionBuilder transaction,
-            InstanceIdentifier<Node> psNodeiid,
-            List<HwvtepPhysicalPortAugmentation> listPort,
-            Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> createdPhysicalSwitches ) {
+    public void updatePhysicalPort(final TransactionBuilder transaction,
+                                   final InstanceIdentifier<Node> psNodeiid,
+                                   final List<HwvtepPhysicalPortAugmentation> listPort) {
         //Get physical switch which the port belong to: in operation DS or new created
-        PhysicalSwitchAugmentation physicalSwitchBelong = getPhysicalSwitchBelong(psNodeiid, createdPhysicalSwitches);
         for (HwvtepPhysicalPortAugmentation port : listPort) {
             LOG.debug("Creating a physical port named: {}", port.getHwvtepNodeName().getValue());
-            Optional<HwvtepPhysicalPortAugmentation> operationalPhysicalPortOptional =
-                    getOperationalState().getPhysicalPortAugmentation(psNodeiid, port.getHwvtepNodeName());
-            PhysicalPort physicalPort = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalPort.class);
-            //get managing global node of physicalSwitchBelong
-            InstanceIdentifier<?> globalNodeIid = physicalSwitchBelong.getManagedBy().getValue();
-            setVlanBindings(globalNodeIid, physicalPort, port);
-            setDescription(physicalPort, port);
-            if (!operationalPhysicalPortOptional.isPresent()) {
-                //create a physical port
-                setName(physicalPort, port, operationalPhysicalPortOptional);
-                String portUuid = "PhysicalPort_" + HwvtepSouthboundMapper.getRandomUUID();
-                LOG.trace("execute: creating physical port: {}", physicalPort);
-                transaction.add(op.insert(physicalPort).withId(portUuid));
-                transaction.add(op.comment("Physical Port: Creating " + port.getHwvtepNodeName().getValue()));
-                //update physical switch table
-                PhysicalSwitch physicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalSwitch.class);
-                physicalSwitch.setName(physicalSwitchBelong.getHwvtepNodeName().getValue());
-                physicalSwitch.setPorts(Collections.singleton(new UUID(portUuid)));
-                LOG.trace("execute: mutating physical switch: {}", physicalSwitch);
-                transaction.add(op.mutate(physicalSwitch)
-                        .addMutation(physicalSwitch.getPortsColumn().getSchema(), Mutator.INSERT,
-                                physicalSwitch.getPortsColumn().getData())
-                        .where(physicalSwitch.getNameColumn().getSchema().opEqual(physicalSwitch.getNameColumn().getData()))
-                        .build());
-                transaction.add(op.comment("Physical Switch: Mutating " +
-                                port.getHwvtepNodeName().getValue() + " " + portUuid));
+            HwvtepDeviceInfo.DeviceData deviceOperdata = getDeviceInfo().getDeviceOperData(TerminationPoint.class,
+                    getTpIid(psNodeiid, port.getHwvtepNodeName().getValue()));
+            if (deviceOperdata == null) {
+                //create a physical port always happens from device
+                LOG.error("Physical port {} not present in oper datastore", port.getHwvtepNodeName().getValue());
             } else {
-                //updated physical port only
-                HwvtepPhysicalPortAugmentation updatedPhysicalPort = operationalPhysicalPortOptional.get();
-                String existingPhysicalPortName = updatedPhysicalPort.getHwvtepNodeName().getValue();
+                PhysicalPort physicalPort = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
+                        PhysicalPort.class);
+                physicalPort.setName(port.getHwvtepNodeName().getValue());
+                setVlanBindings(psNodeiid, physicalPort, port, transaction);
+                setDescription(physicalPort, port);
+                String existingPhysicalPortName = port.getHwvtepNodeName().getValue();
                 PhysicalPort extraPhyscialPort =
                         TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalPort.class);
                 extraPhyscialPort.setName("");
@@ -149,28 +138,111 @@ public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
         }
     }
 
-    private void setVlanBindings(InstanceIdentifier<?> globalNodeIid, PhysicalPort physicalPort,
-            HwvtepPhysicalPortAugmentation inputPhysicalPort) {
+    private void setVlanBindings(final InstanceIdentifier<Node> psNodeiid,
+                                 final PhysicalPort physicalPort,
+                                 final HwvtepPhysicalPortAugmentation inputPhysicalPort,
+                                 final TransactionBuilder transaction) {
         if (inputPhysicalPort.getVlanBindings() != null) {
             //get UUID by LogicalSwitchRef
             Map<Long, UUID> bindingMap = new HashMap<>();
             for (VlanBindings vlanBinding: inputPhysicalPort.getVlanBindings()) {
+                InstanceIdentifier<VlanBindings> vlanIid = getVlanBindingIid(psNodeiid, physicalPort, vlanBinding);
                 @SuppressWarnings("unchecked")
                 InstanceIdentifier<LogicalSwitches> lswitchIid =
                         (InstanceIdentifier<LogicalSwitches>) vlanBinding.getLogicalSwitchRef().getValue();
-                Optional<LogicalSwitches> operationalSwitchOptional =
-                        getOperationalState().getLogicalSwitches(lswitchIid);
-                if (operationalSwitchOptional.isPresent()) {
-                    Uuid logicalSwitchUuid = operationalSwitchOptional.get().getLogicalSwitchUuid();
-                    bindingMap.put(vlanBinding.getVlanIdKey().getValue().longValue(), new UUID(logicalSwitchUuid.getValue()));
-                }else{
-                    bindingMap.put(vlanBinding.getVlanIdKey().getValue().longValue(), TransactUtils.getLogicalSwitchUUID(lswitchIid));
+
+                Map inTransitDependencies = DEPENDENCY_GETTER.getInTransitDependencies(
+                        getOperationalState(), vlanBinding);
+                Map configDependencies = DEPENDENCY_GETTER.getUnMetConfigDependencies(
+                        getOperationalState(), vlanBinding);
+
+                if (!HwvtepSouthboundUtil.isEmptyMap(configDependencies)) {
+                    createConfigWaitJob(psNodeiid, inputPhysicalPort,
+                            vlanBinding, configDependencies, vlanIid);
+                    continue;
+                }
+                if (!HwvtepSouthboundUtil.isEmptyMap(inTransitDependencies)) {
+                    createOperWaitingJob(psNodeiid, inputPhysicalPort,
+                            vlanBinding, inTransitDependencies, vlanIid);
+                    continue;
                 }
+
+                bindingMap.put(vlanBinding.getVlanIdKey().getValue().longValue(),
+                        TransactUtils.getLogicalSwitchUUID(transaction, getOperationalState(), lswitchIid));
             }
             physicalPort.setVlanBindings(bindingMap);
         }
     }
 
+    private void createOperWaitingJob(final InstanceIdentifier<Node> psNodeiid,
+                                      final HwvtepPhysicalPortAugmentation inputPhysicalPort,
+                                      final VlanBindings vlanBinding,
+                                      final Map inTransitDependencies,
+                                      final InstanceIdentifier<VlanBindings> vlanIid) {
+
+        DependentJob<VlanBindings> opWaitingJob = new DependentJob.OpWaitingJob(
+                vlanIid, vlanBinding, inTransitDependencies) {
+            @Override
+            public void onDependencyResolved(final HwvtepOperationalState operationalState,
+                                             final TransactionBuilder transactionBuilder) {
+                PhysicalPortUpdateCommand.this.threadLocalOperationalState.set(operationalState);
+                PhysicalPortUpdateCommand.this.threadLocalDeviceTransaction.set(transactionBuilder);
+                updatePhysicalPort(transactionBuilder, psNodeiid, Lists.newArrayList(inputPhysicalPort));
+            }
+        };
+        getDeviceInfo().addJobToQueue(opWaitingJob);
+    }
+
+    private void createConfigWaitJob(final InstanceIdentifier<Node> psNodeiid,
+                                     final HwvtepPhysicalPortAugmentation inputPhysicalPort,
+                                     final VlanBindings vlanBinding,
+                                     final Map configDependencies,
+                                     final InstanceIdentifier<VlanBindings> vlanIid) {
+
+        DependentJob<VlanBindings> configWaitingJob = new DependentJob.ConfigWaitingJob(
+                vlanIid, vlanBinding, configDependencies) {
+            @Override
+            public void onDependencyResolved(final HwvtepOperationalState operationalState,
+                                             final TransactionBuilder transactionBuilder) {
+                PhysicalPortUpdateCommand.this.threadLocalOperationalState.set(operationalState);
+                PhysicalPortUpdateCommand.this.threadLocalDeviceTransaction.set(transactionBuilder);
+                updatePhysicalPort(transactionBuilder, psNodeiid, Lists.newArrayList(inputPhysicalPort));
+            }
+        };
+        getDeviceInfo().addJobToQueue(configWaitingJob);
+    }
+
+    private InstanceIdentifier<TerminationPoint> getTpIid(final InstanceIdentifier<Node> psNodeiid,
+                                                          final String portName) {
+        return psNodeiid.child(
+                TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+    }
+
+    private InstanceIdentifier<VlanBindings> getVlanBindingIid(
+            final InstanceIdentifier<Node> psNodeiid,
+            final PhysicalPort physicalPort,
+            final VlanBindings vlanBinding) {
+
+        return psNodeiid.child(
+                TerminationPoint.class, new TerminationPointKey(new TpId(physicalPort.getName())))
+                .augmentation(HwvtepPhysicalPortAugmentation.class)
+                .child(VlanBindings.class, new VlanBindingsKey(vlanBinding.getVlanIdKey()));
+    }
+
+    static class VlanBindingsUnMetDependencyGetter extends UnMetDependencyGetter<VlanBindings> {
+
+        public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(VlanBindings data) {
+            if (data == null) {
+                return Collections.emptyList();
+            }
+            return Collections.singletonList(data.getLogicalSwitchRef().getValue());
+        }
+
+        public List<InstanceIdentifier<?>> getTerminationPointDependencies(VlanBindings data) {
+            return Collections.emptyList();
+        }
+    }
+
     private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractCreated(
             Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
         Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result = new HashMap<>();
index 593fdfae055e9ae35751d1800f8b50b971f58cf3..cf29c3e536c159c3f7f60e875100ed28e8796c45 100644 (file)
@@ -65,6 +65,7 @@ public class HwvtepPhysicalPortRemoveCommand extends AbstractTransactionCommand
                                 updatedPSwitchData).child(TerminationPoint.class,
                                 new TerminationPointKey(new TpId(portName)));
                 transaction.delete(LogicalDatastoreType.OPERATIONAL, nodePath);
+                getDeviceInfo().clearDeviceOperData(TerminationPoint.class, nodePath);
             }
         }
     }
index 4e4448b52b3d0960131c160bdee5f3ce0fc26b03..ce65d5c6212a28ab0302a09a437249664973eb89 100644 (file)
@@ -9,15 +9,25 @@
 package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.HwvtepOperationalState;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.PhysicalPortUpdateCommand;
 import org.opendaylight.ovsdb.lib.message.TableUpdates;
 import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
@@ -32,6 +42,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hw
 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.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.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.PortFaultStatus;
@@ -59,12 +70,25 @@ public class HwvtepPhysicalPortUpdateCommand extends AbstractTransactionCommand
     private Map<UUID, PhysicalPort> updatedPPRows;
     private Map<UUID, PhysicalPort> oldPPRows;
     private Map<UUID, PhysicalSwitch> switchUpdatedRows;
+    private Set<UUID> skipReconciliationPorts;
 
     public HwvtepPhysicalPortUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
         super(key, updates, dbSchema);
         updatedPPRows = TyperUtils.extractRowsUpdated(PhysicalPort.class, getUpdates(), getDbSchema());
         oldPPRows = TyperUtils.extractRowsOld(PhysicalPort.class, getUpdates(), getDbSchema());
         switchUpdatedRows = TyperUtils.extractRowsUpdated(PhysicalSwitch.class, getUpdates(), getDbSchema());
+        skipReconciliationPorts = new HashSet<>();
+        for (Entry<UUID, PhysicalPort> pPortUpdateEntry : updatedPPRows.entrySet()) {
+            Optional<InstanceIdentifier<Node>> switchIid = getTerminationPointSwitch(pPortUpdateEntry.getKey());
+            if (switchIid.isPresent()) {
+                if (getDeviceInfo().getDeviceOperData(Node.class, switchIid.get()) == null) {
+                    //This is the first update from switch do not have to do reconciliation of this port
+                    //it is taken care by switch reconciliation
+                    skipReconciliationPorts.add(pPortUpdateEntry.getKey());
+                }
+            }
+        }
+
     }
 
     @Override
@@ -105,6 +129,9 @@ public class HwvtepPhysicalPortUpdateCommand extends AbstractTransactionCommand
                 } else {
                     transaction.put(LogicalDatastoreType.OPERATIONAL, tpPath, tpBuilder.build());
                 }
+                reconcileToPort(transaction, pPortUpdate, tpPath);
+                getDeviceInfo().updateDeviceOperData(TerminationPoint.class, tpPath,
+                        pPortUpdate.getUuid(), pPortUpdate);
                 // Update with Deleted VlanBindings
                 if (oldPPRows.get(pPortUpdateEntry.getKey()) != null
                         && oldPPRows.get(pPortUpdateEntry.getKey()).getVlanBindingsColumn() != null) {
@@ -127,6 +154,48 @@ public class HwvtepPhysicalPortUpdateCommand extends AbstractTransactionCommand
         }
     }
 
+    private void reconcileToPort(final ReadWriteTransaction transaction,
+                                 final PhysicalPort pPortUpdate,
+                                 final InstanceIdentifier<TerminationPoint> tpPath) {
+        if (skipReconciliationPorts.contains(pPortUpdate.getUuid())) {
+            //case of port added along with switch add
+            //switch reconciliation will take care of this port along with other ports
+            return;
+        }
+        if (getDeviceInfo().getDeviceOperData(TerminationPoint.class, tpPath) != null) {
+            //case of port update not new port add
+            return;
+        }
+        //case of individual port add , reconcile to this port
+        getDeviceInfo().updateDeviceOperData(TerminationPoint.class, tpPath, pPortUpdate.getUuid(), pPortUpdate);
+        Futures.addCallback(transaction.read(LogicalDatastoreType.CONFIGURATION, tpPath),
+                new FutureCallback<Optional<TerminationPoint>>() {
+                    @Override
+                    public void onSuccess(Optional<TerminationPoint> optionalConfigTp) {
+                        if (!optionalConfigTp.isPresent() || optionalConfigTp.get().getAugmentation(
+                                HwvtepPhysicalPortAugmentation.class) == null) {
+                            //TODO port came with some vlan bindings clean them up use PortRemovedCommand
+                            return;
+                        }
+                        getDeviceInfo().updateDeviceOperData(TerminationPoint.class, tpPath,
+                                pPortUpdate.getUuid(), pPortUpdate);
+                        TerminationPoint configTp = optionalConfigTp.get();
+                        getDeviceInfo().scheduleTransaction((transactionBuilder) -> {
+                            InstanceIdentifier psIid = tpPath.firstIdentifierOf(Node.class);
+                            HwvtepOperationalState operState = new HwvtepOperationalState(getOvsdbConnectionInstance());
+                            PhysicalPortUpdateCommand portUpdateCommand = new PhysicalPortUpdateCommand(
+                                    operState, Collections.EMPTY_LIST);
+                            portUpdateCommand.updatePhysicalPort(transactionBuilder, psIid,
+                                    Lists.newArrayList(configTp.getAugmentation(HwvtepPhysicalPortAugmentation.class)));
+                        });
+                    }
+
+                    @Override
+                    public void onFailure(Throwable throwable) {
+                    }
+                });
+    }
+
     private <T extends DataObject> void deleteEntries(ReadWriteTransaction transaction,
             List<InstanceIdentifier<T>> entryIids) {
         for (InstanceIdentifier<T> entryIid : entryIids) {
index d1b682d9b3f938fdaec4e92b1bd6195c138bf684..30210469b79d5bc2562dcda3a7d8491b906b2f9d 100644 (file)
@@ -43,7 +43,7 @@ public class HwvtepPhysicalSwitchRemoveCommand extends AbstractTransactionComman
             // TODO handle removal of reference to managed switch from model
             transaction.delete(LogicalDatastoreType.OPERATIONAL, nodeIid);
             transaction.delete(LogicalDatastoreType.OPERATIONAL, switchIid);
-            getOvsdbConnectionInstance().getDeviceInfo().removePhysicalSwitch(pSwitch.getUuid());
+            getDeviceInfo().clearDeviceOperData(Node.class, switchIid);
         }
     }