Added code for PhysicalPort, LogicalSwitch
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transactions / md / PhysicalPortUpdateCommand.java
index 3585894724c7dca494b65399712b16915a0414c3..780a49dbd37d510d0bae728ca3f55e7f3863e721 100644 (file)
 
 package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+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.HwvtepSouthboundMapper;
 import org.opendaylight.ovsdb.lib.message.TableUpdates;
 import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+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.HwvtepLogicalSwitchRef;
+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.Switches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.PhysicalPortIdBuilder;
+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.VlanBindingsBuilder;
+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.NodeId;
+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.TerminationPointBuilder;
+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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+
 public class PhysicalPortUpdateCommand extends AbstractTransactionCommand {
 
     private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortUpdateCommand.class);
     private Map<UUID, PhysicalPort> updatedPPRows;
     private Map<UUID, PhysicalPort> oldPPRows;
+    private Map<UUID, PhysicalSwitch> switchUpdatedRows;
+    private Map<UUID, LogicalSwitch> lSwitchUpdatedRows;
 
     public PhysicalPortUpdateCommand(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());
+        lSwitchUpdatedRows = TyperUtils.extractRowsUpdated(LogicalSwitch.class, getUpdates(),getDbSchema());
     }
 
     @Override
     public void execute(ReadWriteTransaction transaction) {
-        // TODO Auto-generated method stub
+        final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
+        if ( updatedPPRows == null
+                || updatedPPRows.isEmpty()) {
+            return;
+        }
+        LOG.trace("PhysicalPortTable updated: {}", updatedPPRows);
+        Optional<Node> node = readNode(transaction, connectionIId);
+        if (node.isPresent()) {
+            updateTerminationPoints(transaction, node.get());
+            //TODO: Handle Deletion of VLAN Bindings
+        }
+    }
+
+    private void updateTerminationPoints(ReadWriteTransaction transaction, Node node) {
+        for (Entry<UUID, PhysicalPort> pPortUpdate : updatedPPRows.entrySet()) {
+            String portName = null;
+            portName = pPortUpdate.getValue().getNameColumn().getData();
+            Optional<InstanceIdentifier<Node>> switchIid = getTerminationPointSwitch(pPortUpdate.getKey());
+            if (!switchIid.isPresent()) {
+                switchIid = getTerminationPointSwitch( transaction, node, portName);
+            }
+            if (switchIid.isPresent()) {
+                NodeId switchId = HwvtepSouthboundMapper.createManagedNodeId(switchIid.get());
+                TerminationPointKey tpKey = new TerminationPointKey(new TpId(portName));
+                TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+                tpBuilder.setKey(tpKey);
+                tpBuilder.setTpId(tpKey.getTpId());
+                InstanceIdentifier<TerminationPoint> tpPath =
+                        getInstanceIdentifier(switchIid.get(), pPortUpdate.getValue());
+                HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder =
+                        new HwvtepPhysicalPortAugmentationBuilder();
+                buildTerminationPoint(tpAugmentationBuilder,pPortUpdate.getValue());
+                tpBuilder.addAugmentation(HwvtepPhysicalPortAugmentation.class, tpAugmentationBuilder.build());
+                if (oldPPRows.containsKey(pPortUpdate.getKey())) {
+                    transaction.merge(LogicalDatastoreType.OPERATIONAL,
+                            tpPath, tpBuilder.build());
+                } else {
+                    transaction.put(LogicalDatastoreType.OPERATIONAL,
+                            tpPath, tpBuilder.build());
+                }
+            }
+        }
+    }
+
+    private void buildTerminationPoint(HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
+                    PhysicalPort portUpdate) {
+        updatePhysicalPortId(portUpdate, tpAugmentationBuilder);
+        updatePort(portUpdate, tpAugmentationBuilder);
+    }
+
+    private void updatePort(PhysicalPort portUpdate,
+                    HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+        updateVlanBindings(portUpdate, tpAugmentationBuilder);
+    }
+
+    private void updatePhysicalPortId(PhysicalPort portUpdate,
+                    HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+        PhysicalPortIdBuilder portIdBuilder = new PhysicalPortIdBuilder();
+        portIdBuilder.setHwvtepNodeName(new HwvtepNodeName(portUpdate.getName()));
+        if(portUpdate.getDescription() != null) {
+            portIdBuilder.setHwvtepNodeDescription(portUpdate.getDescription());
+        }
+
+        tpAugmentationBuilder.setPhysicalPortId(portIdBuilder.build());
+    }
+
+    private void updateVlanBindings(PhysicalPort portUpdate,
+                    HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+        Map<Long, UUID> vlanBindings = portUpdate.getVlanBindingsColumn().getData();
+        if(vlanBindings != null && !vlanBindings.isEmpty()) {
+            Set<Long> vlanBindingsKeys = vlanBindings.keySet();
+            List<VlanBindings> vlanBindingsList = new ArrayList<>();
+            UUID vlanBindingValue = null;
+            for(Long vlanBindingKey: vlanBindingsKeys) {
+                vlanBindingValue = vlanBindings.get(vlanBindingKey);
+                if(vlanBindingValue != null && vlanBindingKey != null) {
+                    vlanBindingsList.add(createVlanBinding(portUpdate, vlanBindingKey, vlanBindingValue));
+                }
+            }
+            tpAugmentationBuilder.setVlanBindings(vlanBindingsList);
+        }
+    }
+
+    private VlanBindings createVlanBinding(PhysicalPort portUpdate, Long key, UUID value) {
+        VlanBindingsBuilder vbBuilder = new VlanBindingsBuilder();
+        VlanBindingsKey vbKey = new VlanBindingsKey(new VlanId(key.intValue()));
+        vbBuilder.setKey(vbKey);
+        vbBuilder.setVlanIdKey(vbKey.getVlanIdKey());
+        HwvtepLogicalSwitchRef lSwitchRef = this.getLogicalSwitchRef(value, portUpdate.getUuid());
+        vbBuilder.setLogicalSwitch(lSwitchRef);
+        return vbBuilder.build();
+    }
+
+    private HwvtepLogicalSwitchRef getLogicalSwitchRef( UUID switchUUID, UUID portUUID) {
+            if (lSwitchUpdatedRows.get(switchUUID) != null) {
+                Optional<InstanceIdentifier<Node>> optSwitchIid = Optional.of(HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
+                        this.lSwitchUpdatedRows.get(switchUUID)));
+                if(optSwitchIid.isPresent()) {
+                    return new HwvtepLogicalSwitchRef(optSwitchIid.get());
+                }
+            }
+        return null;
+    }
+
+    private Optional<InstanceIdentifier<Node>> getTerminationPointSwitch( UUID portUUID) {
+        for (UUID switchUUID : this.switchUpdatedRows.keySet()) {
+            if (this.switchUpdatedRows.get(switchUUID).getPortsColumn().getData().contains(portUUID)) {
+                return Optional.of(HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
+                        this.switchUpdatedRows.get(switchUUID)));
+            }
+        }
+        return Optional.absent();
+    }
+
+    private Optional<InstanceIdentifier<Node>> getTerminationPointSwitch(
+                    final ReadWriteTransaction transaction, Node node, String tpName) {
+                HwvtepGlobalAugmentation hwvtepNode = node.getAugmentation(HwvtepGlobalAugmentation.class);
+                List<Switches> switchNodes = hwvtepNode.getSwitches();
+                for ( Switches managedNodeEntry : switchNodes ) {
+                    @SuppressWarnings("unchecked")
+                    Node switchNode = readNode(transaction,
+                            (InstanceIdentifier<Node>)managedNodeEntry.getSwitchRef().getValue()).get();
+                    TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+                    TerminationPointKey tpKey = new TerminationPointKey(new TpId(tpName));
+                    tpBuilder.setKey(tpKey);
+                    if (switchNode.getTerminationPoint() != null
+                            && switchNode.getTerminationPoint().contains(tpBuilder.build())) {
+                        PhysicalSwitchAugmentation pSwitchAugment
+                            = switchNode.getAugmentation(PhysicalSwitchAugmentation.class);
+                        return Optional.of((InstanceIdentifier<Node>)managedNodeEntry.getSwitchRef().getValue());
+                    }
+                }
+                return Optional.absent();
+            }
+
+    private Optional<Node> readNode(final ReadWriteTransaction transaction, final InstanceIdentifier<Node> nodePath) {
+        Optional<Node> node = Optional.absent();
+        try {
+            node = transaction.read(
+                    LogicalDatastoreType.OPERATIONAL, nodePath)
+                    .checkedGet();
+        } catch (final ReadFailedException e) {
+            LOG.warn("Read Operational/DS for Node fail! {}",
+                    nodePath, e);
+        }
+        return node;
+    }
+
+    private InstanceIdentifier<TerminationPoint> getInstanceIdentifier(InstanceIdentifier<Node> switchIid,
+                    PhysicalPort pPort) {
+        return switchIid.child(TerminationPoint.class, new TerminationPointKey(new TpId(pPort.getName())));
     }
 
 }