X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=southbound%2Fsouthbound-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Fsouthbound%2Ftransactions%2Fmd%2FOvsdbPortUpdateCommand.java;h=2e7e3f6a5d97abdbc702efced461ef826cac5a31;hb=48096e085b70127b9358d9ec33e772a6d94f569d;hp=120ef5e6a5a60840174a4e1dc7e39517dae4410d;hpb=a792a362c87c59a113da397885954baf7f66baba;p=ovsdb.git diff --git a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbPortUpdateCommand.java b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbPortUpdateCommand.java index 120ef5e6a..2e7e3f6a5 100644 --- a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbPortUpdateCommand.java +++ b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbPortUpdateCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Intel Corp. and others. All rights reserved. + * Copyright (c) 2014, 2017 Intel Corp. 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, @@ -8,17 +8,21 @@ package org.opendaylight.ovsdb.southbound.transactions.md; +import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog; + +import com.google.common.annotations.VisibleForTesting; + import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; 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.mdsal.binding.api.ReadWriteTransaction; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.ovsdb.lib.error.ColumnSchemaNotFoundException; import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException; import org.opendaylight.ovsdb.lib.message.TableUpdates; @@ -30,18 +34,31 @@ import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils; import org.opendaylight.ovsdb.schema.openvswitch.Bridge; import org.opendaylight.ovsdb.schema.openvswitch.Interface; import org.opendaylight.ovsdb.schema.openvswitch.Port; +import org.opendaylight.ovsdb.schema.openvswitch.Qos; +import org.opendaylight.ovsdb.southbound.InstanceIdentifierCodec; import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance; import org.opendaylight.ovsdb.southbound.SouthboundConstants; import org.opendaylight.ovsdb.southbound.SouthboundMapper; import org.opendaylight.ovsdb.southbound.SouthboundUtil; +import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; 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.rev150105.OvsdbBridgeAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQosRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfd; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatusBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatusKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp; @@ -56,6 +73,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntryKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; @@ -72,30 +92,34 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; - public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { private static final Logger LOG = LoggerFactory.getLogger(OvsdbPortUpdateCommand.class); - private Map portUpdatedRows; - private Map portOldRows; - private Map interfaceUpdatedRows; - private Map interfaceOldRows; - private Map bridgeUpdatedRows; - public OvsdbPortUpdateCommand(OvsdbConnectionInstance key, TableUpdates updates, - DatabaseSchema dbSchema) { + + private final InstanceIdentifierCodec instanceIdentifierCodec; + private final Map portUpdatedRows; + private final Map portOldRows; + private final Map interfaceUpdatedRows; + private final Map interfaceOldRows; + private final Map bridgeUpdatedRows; + private final Map qosUpdatedRows; + + public OvsdbPortUpdateCommand(InstanceIdentifierCodec instanceIdentifierCodec, OvsdbConnectionInstance key, + TableUpdates updates, DatabaseSchema dbSchema) { super(key, updates, dbSchema); + this.instanceIdentifierCodec = instanceIdentifierCodec; portUpdatedRows = TyperUtils.extractRowsUpdated(Port.class, updates, dbSchema); portOldRows = TyperUtils.extractRowsOld(Port.class, updates, dbSchema); interfaceUpdatedRows = TyperUtils.extractRowsUpdated(Interface.class, updates, dbSchema); interfaceOldRows = TyperUtils.extractRowsOld(Interface.class, updates, dbSchema); bridgeUpdatedRows = TyperUtils.extractRowsUpdated(Bridge.class, updates, dbSchema); + qosUpdatedRows = TyperUtils.extractRowsUpdated(Qos.class, updates, dbSchema); } @Override public void execute(ReadWriteTransaction transaction) { final InstanceIdentifier connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier(); - if ( (portUpdatedRows == null && interfaceOldRows == null ) - || ( interfaceOldRows.isEmpty() && portUpdatedRows.isEmpty())) { + if (portUpdatedRows == null && interfaceOldRows == null + || interfaceOldRows.isEmpty() && portUpdatedRows.isEmpty()) { return; } Optional node = readNode(transaction, connectionIId); @@ -103,75 +127,99 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { updateTerminationPoints(transaction, node.get()); } } - private void updateTerminationPoints(ReadWriteTransaction transaction, Node node) { + + @VisibleForTesting + void updateTerminationPoints(ReadWriteTransaction transaction, Node node) { for (Entry portUpdate : portUpdatedRows.entrySet()) { String portName = null; portName = portUpdate.getValue().getNameColumn().getData(); Optional> bridgeIid = getTerminationPointBridge(portUpdate.getKey()); if (!bridgeIid.isPresent()) { - bridgeIid = getTerminationPointBridge( transaction, node, portName); + bridgeIid = getTerminationPointBridge(transaction, node, portName); } if (bridgeIid.isPresent()) { NodeId bridgeId = SouthboundMapper.createManagedNodeId(bridgeIid.get()); TerminationPointKey tpKey = new TerminationPointKey(new TpId(portName)); + getOvsdbConnectionInstance().updatePortInterface(portName, bridgeIid.get()); TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); - tpBuilder.setKey(tpKey); + tpBuilder.withKey(tpKey); tpBuilder.setTpId(tpKey.getTpId()); InstanceIdentifier tpPath = getInstanceIdentifier(bridgeIid.get(), portUpdate.getValue()); OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); - buildTerminationPoint(tpAugmentationBuilder,portUpdate.getValue()); - UUID interfaceUUID = (UUID)portUpdate.getValue().getInterfacesColumn().getData().toArray()[0]; - if (interfaceUpdatedRows.containsKey(interfaceUUID)) { - buildTerminationPoint(tpAugmentationBuilder, - interfaceUpdatedRows.get(interfaceUUID)); - interfaceUpdatedRows.remove(interfaceUUID); - interfaceOldRows.remove(interfaceUUID); + buildTerminationPoint(transaction, tpPath, tpAugmentationBuilder, node, portUpdate); + UUID interfaceUuid = (UUID)portUpdate.getValue().getInterfacesColumn().getData().toArray()[0]; + if (interfaceUpdatedRows.containsKey(interfaceUuid)) { + buildTerminationPoint(tpAugmentationBuilder, interfaceUpdatedRows.get(interfaceUuid)); + interfaceUpdatedRows.remove(interfaceUuid); + interfaceOldRows.remove(interfaceUuid); } tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build()); if (portOldRows.containsKey(portUpdate.getKey()) && !portQosCleared(portUpdate)) { - transaction.merge(LogicalDatastoreType.OPERATIONAL, - tpPath, tpBuilder.build()); + updateToDataStore(transaction, tpBuilder, tpPath, true); + LOG.info("DEVICE - {} TerminationPoint : {} to Bridge : {}", TransactionType.ADD, + tpKey.getTpId().getValue(), bridgeId.getValue()); } else { - transaction.put(LogicalDatastoreType.OPERATIONAL, - tpPath, tpBuilder.build()); + updateToDataStore(transaction, tpBuilder, tpPath, false); + LOG.debug("DEVICE - {} TerminationPoint : {} to Bridge : {}", TransactionType.UPDATE, + tpKey.getTpId().getValue(), bridgeId.getValue()); } } } for (Entry interfaceUpdate : interfaceUpdatedRows.entrySet()) { String interfaceName = null; + Optional> bridgeIid = Optional.empty(); interfaceName = interfaceUpdatedRows.get(interfaceUpdate.getKey()).getNameColumn().getData(); - Optional> bridgeIid = getTerminationPointBridge( transaction, node, interfaceName); + if (getOvsdbConnectionInstance().getPortInterface(interfaceName) != null) { + bridgeIid = Optional.of(getOvsdbConnectionInstance().getPortInterface(interfaceName)); + } + if (!bridgeIid.isPresent()) { + bridgeIid = getTerminationPointBridge(transaction, node, interfaceName); + } if (bridgeIid.isPresent()) { - NodeId bridgeId = SouthboundMapper.createManagedNodeId(bridgeIid.get()); TerminationPointKey tpKey = new TerminationPointKey(new TpId(interfaceName)); - InstanceIdentifier tpPath = InstanceIdentifier - .create(NetworkTopology.class) - .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID)) - .child(Node.class,new NodeKey(bridgeId)) - .child(TerminationPoint.class,tpKey); TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); - tpBuilder.setKey(tpKey); + tpBuilder.withKey(tpKey); tpBuilder.setTpId(tpKey.getTpId()); OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); buildTerminationPoint(tpAugmentationBuilder, interfaceUpdate.getValue()); tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build()); - transaction.merge(LogicalDatastoreType.OPERATIONAL, - tpPath, tpBuilder.build()); + NodeId bridgeId = SouthboundMapper.createManagedNodeId(bridgeIid.get()); + InstanceIdentifier tpPath = InstanceIdentifier + .create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID)) + .child(Node.class,new NodeKey(bridgeId)) + .child(TerminationPoint.class,tpKey); + updateToDataStore(transaction, tpBuilder, tpPath, true); } } } - private void buildTerminationPoint(OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder, - Port portUpdate) { + + protected void updateToDataStore(ReadWriteTransaction transaction, TerminationPointBuilder tpBuilder, + InstanceIdentifier tpPath, boolean merge) { + if (merge) { + transaction.merge(LogicalDatastoreType.OPERATIONAL, + tpPath, tpBuilder.build()); + } else { + transaction.put(LogicalDatastoreType.OPERATIONAL, + tpPath, tpBuilder.build()); + } + } + + @VisibleForTesting + void buildTerminationPoint(ReadWriteTransaction transaction, + InstanceIdentifier tpPath, + OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder, + Node node, Entry portUpdate) { tpAugmentationBuilder - .setName(portUpdate.getName()); + .setName(portUpdate.getValue().getName()); tpAugmentationBuilder.setPortUuid(new Uuid( - portUpdate.getUuid().toString())); - updatePort(portUpdate, tpAugmentationBuilder); + portUpdate.getValue().getUuid().toString())); + updatePort(transaction, node, tpPath, portUpdate, tpAugmentationBuilder); } private void buildTerminationPoint(OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder, @@ -184,49 +232,66 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { updateInterfaces(interfaceUpdate, tpAugmentationBuilder); } + @SuppressWarnings("IllegalCatch") private Optional readNode(final ReadWriteTransaction transaction, final InstanceIdentifier nodePath) { - Optional node = Optional.absent(); + Optional node = Optional.empty(); try { - node = transaction.read( - LogicalDatastoreType.OPERATIONAL, nodePath) - .checkedGet(); - } catch (final ReadFailedException e) { - LOG.warn("Read Operational/DS for Node fail! {}", - nodePath, e); + node = SouthboundUtil.readNode(transaction, nodePath); + } catch (Exception exp) { + LOG.error("Error in getting the Node for {}", nodePath, exp); } return node; } - private Optional> getTerminationPointBridge( UUID portUUID) { - for (UUID bridgeUUID : this.bridgeUpdatedRows.keySet()) { - if (this.bridgeUpdatedRows.get(bridgeUUID).getPortsColumn().getData().contains(portUUID)) { - return Optional.of(SouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), - this.bridgeUpdatedRows.get(bridgeUUID))); + private Optional> getTerminationPointBridge(UUID portUuid) { + + if (bridgeUpdatedRows != null) { + for (Entry entry : this.bridgeUpdatedRows.entrySet()) { + UUID bridgeUuid = entry.getKey(); + if (this.bridgeUpdatedRows.get(bridgeUuid).getPortsColumn().getData() + .contains(portUuid)) { + InstanceIdentifier iid = SouthboundMapper.createInstanceIdentifier( + instanceIdentifierCodec, getOvsdbConnectionInstance(), + this.bridgeUpdatedRows.get(bridgeUuid)); + getOvsdbConnectionInstance().updatePort(portUuid, iid); + return Optional.of(iid); + } } } - return Optional.absent(); + if (getOvsdbConnectionInstance().getPort(portUuid) != null) { + return Optional.of(getOvsdbConnectionInstance().getPort(portUuid)); + } + return Optional.empty(); } + + @SuppressWarnings("unchecked") private Optional> getTerminationPointBridge( final ReadWriteTransaction transaction, Node node, String tpName) { - OvsdbNodeAugmentation ovsdbNode = node.getAugmentation(OvsdbNodeAugmentation.class); + OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class); List managedNodes = ovsdbNode.getManagedNodeEntry(); - for ( ManagedNodeEntry managedNodeEntry : managedNodes ) { - @SuppressWarnings("unchecked") - Node managedNode = readNode(transaction - ,(InstanceIdentifier)managedNodeEntry.getBridgeRef().getValue()).get(); - TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); - TerminationPointKey tpKey = new TerminationPointKey(new TpId(tpName)); - tpBuilder.setKey(tpKey); - if (managedNode.getTerminationPoint().contains(tpBuilder.build())) { - OvsdbBridgeAugmentation ovsdbNodeAugment - = managedNode.getAugmentation(OvsdbBridgeAugmentation.class); - return Optional.of((InstanceIdentifier)managedNodeEntry.getBridgeRef().getValue()); + TpId tpId = new TpId(tpName); + + for (ManagedNodeEntry managedNodeEntry : managedNodes) { + Optional optManagedNode = SouthboundUtil.readNode(transaction, + (InstanceIdentifier)managedNodeEntry.getBridgeRef().getValue()); + if (optManagedNode.isPresent()) { + Node managedNode = optManagedNode.get(); + List tpEntrys = managedNode.getTerminationPoint(); + if (tpEntrys != null) { + for (TerminationPoint tpEntry : tpEntrys) { + if (tpId.equals(tpEntry.getTpId())) { + return Optional.of((InstanceIdentifier) managedNodeEntry.getBridgeRef().getValue()); + } + } + } } } - return Optional.absent(); + + return Optional.empty(); } - private void updateInterfaces(Interface interfaceUpdate, + @VisibleForTesting + void updateInterfaces(Interface interfaceUpdate, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Column typeColumn = interfaceUpdate.getTypeColumn(); @@ -234,18 +299,21 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { updateInterface(interfaceUpdate, type,ovsdbTerminationPointBuilder); } - private void updatePort(final Port port, + @VisibleForTesting + void updatePort(final ReadWriteTransaction transaction, final Node node, + final InstanceIdentifier tpPath, final Entry port, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { - updateVlan(port, ovsdbTerminationPointBuilder); - updateVlanTrunks(port, ovsdbTerminationPointBuilder); - updateVlanMode(port, ovsdbTerminationPointBuilder); - updateQos(port, ovsdbTerminationPointBuilder); - updatePortExternalIds(port, ovsdbTerminationPointBuilder); - updatePortOtherConfig(port, ovsdbTerminationPointBuilder); + updateVlan(port.getValue(), ovsdbTerminationPointBuilder); + updateVlanTrunks(port.getValue(), ovsdbTerminationPointBuilder); + updateVlanMode(port.getValue(), ovsdbTerminationPointBuilder); + updateQos(transaction, node, tpPath, port, ovsdbTerminationPointBuilder); + updatePortExternalIds(port.getValue(), ovsdbTerminationPointBuilder); + updatePortOtherConfig(port.getValue(), ovsdbTerminationPointBuilder); } - private void updateInterface(final Interface interf, + @VisibleForTesting + void updateInterface(final Interface interf, final String type, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { @@ -253,15 +321,22 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { new Uuid(interf.getUuid().toString())); ovsdbTerminationPointBuilder.setInterfaceType( SouthboundMapper.createInterfaceType(type)); + updateIfIndex(interf, ovsdbTerminationPointBuilder); + updateMac(interf, ovsdbTerminationPointBuilder); + updateMacInUse(interf, ovsdbTerminationPointBuilder); updateOfPort(interf, ovsdbTerminationPointBuilder); updateOfPortRequest(interf, ovsdbTerminationPointBuilder); updateInterfaceExternalIds(interf, ovsdbTerminationPointBuilder); updateOptions(interf, ovsdbTerminationPointBuilder); updateInterfaceOtherConfig(interf, ovsdbTerminationPointBuilder); updateInterfaceLldp(interf, ovsdbTerminationPointBuilder); + updateInterfaceBfd(interf, ovsdbTerminationPointBuilder); + updateInterfaceBfdStatus(interf, ovsdbTerminationPointBuilder); + updateInterfacePolicing(interf, ovsdbTerminationPointBuilder); } - private void updateVlan(final Port port, + @VisibleForTesting + void updateVlan(final Port port, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Collection vlanId = port.getTagColumn().getData(); @@ -273,7 +348,8 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { } } - private void updateVlanTrunks(final Port port, + @VisibleForTesting + void updateVlanTrunks(final Port port, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Set portTrunks = port.getTrunksColumn().getData(); @@ -285,27 +361,28 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { .setTrunk(new VlanId(trunk.intValue())).build()); } } - ovsdbTerminationPointBuilder.setTrunks(modelTrunks); } + ovsdbTerminationPointBuilder.setTrunks(modelTrunks); } - private void updateVlanMode(final Port port, + @VisibleForTesting + void updateVlanMode(final Port port, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Collection vlanMode = port.getVlanModeColumn().getData(); if (!vlanMode.isEmpty()) { Iterator itr = vlanMode.iterator(); String vlanType = itr.next(); - if (vlanType.equals(SouthboundConstants.VLANMODES.ACCESS.getMode())) { + if (vlanType.equals(SouthboundConstants.VlanModes.ACCESS.getMode())) { ovsdbTerminationPointBuilder .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access); - } else if (vlanType.equals(SouthboundConstants.VLANMODES.NATIVE_TAGGED.getMode())) { + } else if (vlanType.equals(SouthboundConstants.VlanModes.NATIVE_TAGGED.getMode())) { ovsdbTerminationPointBuilder .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.NativeTagged); - } else if (vlanType.equals(SouthboundConstants.VLANMODES.NATIVE_UNTAGGED.getMode())) { + } else if (vlanType.equals(SouthboundConstants.VlanModes.NATIVE_UNTAGGED.getMode())) { ovsdbTerminationPointBuilder .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.NativeUntagged); - } else if (vlanType.equals(SouthboundConstants.VLANMODES.TRUNK.getMode())) { + } else if (vlanType.equals(SouthboundConstants.VlanModes.TRUNK.getMode())) { ovsdbTerminationPointBuilder .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk); } else { @@ -314,20 +391,143 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { } } - private void updateQos(final Port port, - final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { - if (port.getQosColumn() == null) { + private void updateQos(final ReadWriteTransaction transaction, final Node node, + InstanceIdentifier tpPath, final Entry port, + final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { + if (port.getValue() == null) { return; } - Collection qosUuidCol = port.getQosColumn().getData(); + Collection qosUuidCol = port.getValue().getQosColumn().getData(); if (!qosUuidCol.isEmpty()) { - Iterator itr = qosUuidCol.iterator(); - UUID qosUuid = itr.next(); - ovsdbTerminationPointBuilder.setQos(new Uuid(qosUuid.toString())); + UUID qosUuid = qosUuidCol.iterator().next(); + + NodeId nodeId = node.getNodeId(); + OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class); + + // Delete an older QoS entry + if (portOldRows.containsKey(port.getKey()) && portOldRows.get(port.getKey()).getQosColumn() != null) { + Collection oldQos = portOldRows.get(port.getKey()).getQosColumn().getData(); + if (!oldQos.isEmpty()) { + UUID oldQosUuid = oldQos.iterator().next(); + if (!oldQosUuid.equals(qosUuid)) { + InstanceIdentifier oldQosIid = getQosIid(nodeId, ovsdbNode, oldQosUuid); + if (oldQosIid != null) { + InstanceIdentifier oldPortQosIid = tpPath + .augmentation(OvsdbTerminationPointAugmentation.class) + .child(QosEntry.class, + new QosEntryKey(Long.valueOf(SouthboundConstants.PORT_QOS_LIST_KEY))); + transaction.delete(LogicalDatastoreType.OPERATIONAL, oldPortQosIid); + } + } + } + } + + InstanceIdentifier qosIid = getQosIid(nodeId, ovsdbNode, qosUuid); + if (qosIid != null) { + List qosList = new ArrayList<>(); + OvsdbQosRef qosRef = new OvsdbQosRef(qosIid); + qosList.add(new QosEntryBuilder() + .withKey(new QosEntryKey(Long.valueOf(SouthboundConstants.PORT_QOS_LIST_KEY))) + .setQosRef(qosRef).build()); + ovsdbTerminationPointBuilder.setQosEntry(qosList); + } + } + } + + @SuppressWarnings("unchecked") + private InstanceIdentifier getQosIid(NodeId nodeId, OvsdbNodeAugmentation ovsdbNode, UUID qosUuid) { + // Search for the QoS entry first in the operational datastore + for (QosEntries qosEntry : ovsdbNode.getQosEntries()) { + if (qosEntry.getQosUuid().equals(new Uuid(qosUuid.toString()))) { + return SouthboundMapper.createInstanceIdentifier(nodeId) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, new QosEntriesKey(qosEntry.getQosId())); + } } + + // Search for the QoS entry in the current OVS updates + for (Entry qosUpdate : qosUpdatedRows.entrySet()) { + Qos qos = qosUpdate.getValue(); + if (qos.getUuid().equals(qosUuid)) { + if (qos.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) { + return (InstanceIdentifier) instanceIdentifierCodec.bindingDeserializerOrNull( + qos.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY)); + } else { + return SouthboundMapper.createInstanceIdentifier(nodeId) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, new QosEntriesKey( + new Uri(SouthboundConstants.QOS_URI_PREFIX + "://" + qosUuid.toString()))); + } + } + } + LOG.debug("QoS UUID {} assigned to port not found in operational node {} or QoS updates", qosUuid, ovsdbNode); + return SouthboundMapper.createInstanceIdentifier(nodeId) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, new QosEntriesKey( + new Uri(SouthboundConstants.QOS_URI_PREFIX + "://" + qosUuid.toString()))); } - private void updateOfPort(final Interface interf, + private void updateIfIndex(final Interface interf, + final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { + Set ifIndexSet = null; + try { + if (interf.getIfIndexColumn() != null) { + ifIndexSet = interf.getIfIndexColumn().getData(); + } + if (ifIndexSet != null && !ifIndexSet.isEmpty()) { + for (Long ifIndex : ifIndexSet) { + ovsdbTerminationPointBuilder.setIfindex(ifIndex); + } + } + } catch (SchemaVersionMismatchException e) { + schemaMismatchLog("ifindex", "Interface", e); + } + } + + private void updateMac(final Interface interf, + final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { + Set macSet = null; + try { + if (interf.getMacColumn() != null) { + macSet = interf.getMacColumn().getData(); + } + if (macSet != null && !macSet.isEmpty()) { + /* + * It is a set due to way JSON decoder converts [] objects. OVS + * only supports ONE mac, so we're fine. + */ + for (String mac: macSet) { + ovsdbTerminationPointBuilder.setMac(new MacAddress(mac)); + } + } + } catch (SchemaVersionMismatchException e) { + schemaMismatchLog("mac", "Interface", e); + } + } + + private void updateMacInUse(final Interface interf, + final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { + Set macInUseSet = null; + try { + if (interf.getMacInUseColumn() != null) { + macInUseSet = interf.getMacInUseColumn().getData(); + } + if (macInUseSet != null && !macInUseSet.isEmpty()) { + /* + * It is a set due to way JSON decoder converts [] objects. OVS + * only supports ONE mac, so we're fine. + */ + for (String macInUse: macInUseSet) { + ovsdbTerminationPointBuilder.setMacInUse(new MacAddress(macInUse)); + } + } + } catch (SchemaVersionMismatchException e) { + schemaMismatchLog("mac_in_use", "Interface", e); + } + } + + @VisibleForTesting + void updateOfPort(final Interface interf, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Set ofPorts = interf.getOpenFlowPortColumn().getData(); @@ -338,13 +538,14 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { ovsdbTerminationPointBuilder .setOfport(ofPort); } else { - LOG.debug("Received negative value for ofPort from ovsdb for {} {} {}", + LOG.debug("Received negative value for ofPort from ovsdb for {} {}", interf.getName(),ofPort); } } } - private void updateOfPortRequest(final Interface interf, + @VisibleForTesting + void updateOfPortRequest(final Interface interf, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Set ofPortRequests = null; @@ -360,24 +561,23 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { ovsdbTerminationPointBuilder .setOfportRequest(ofPort); } else { - LOG.debug("Received negative value for ofPort from ovsdb for {} {} {}", + LOG.debug("Received negative value for ofPort from ovsdb for {} {}", interf.getName(),ofPort); } } } - private void updateInterfaceExternalIds(final Interface interf, + @VisibleForTesting + void updateInterfaceExternalIds(final Interface interf, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Map interfaceExternalIds = interf.getExternalIdsColumn().getData(); if (interfaceExternalIds != null && !interfaceExternalIds.isEmpty()) { - Set externalIdKeys = interfaceExternalIds.keySet(); - List externalIdsList = - new ArrayList<>(); - String externalIdValue; - for (String externalIdKey : externalIdKeys) { - externalIdValue = interfaceExternalIds.get(externalIdKey); + List externalIdsList = new ArrayList<>(); + for (Entry entry : interfaceExternalIds.entrySet()) { + String externalIdKey = entry.getKey(); + String externalIdValue = entry.getValue(); if (externalIdKey != null && externalIdValue != null) { externalIdsList.add(new InterfaceExternalIdsBuilder() .setExternalIdKey(externalIdKey) @@ -388,16 +588,16 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { } } - private void updatePortExternalIds(final Port port, + @VisibleForTesting + void updatePortExternalIds(final Port port, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Map portExternalIds = port.getExternalIdsColumn().getData(); if (portExternalIds != null && !portExternalIds.isEmpty()) { - Set externalIdKeys = portExternalIds.keySet(); List externalIdsList = new ArrayList<>(); - String externalIdValue; - for (String externalIdKey : externalIdKeys) { - externalIdValue = portExternalIds.get(externalIdKey); + for (Entry entry : portExternalIds.entrySet()) { + String externalIdKey = entry.getKey(); + String externalIdValue = entry.getValue(); if (externalIdKey != null && externalIdValue != null) { externalIdsList.add(new PortExternalIdsBuilder() .setExternalIdKey(externalIdKey) @@ -408,20 +608,20 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { } } - private void updateOptions(final Interface interf, + @VisibleForTesting + void updateOptions(final Interface interf, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Map optionsMap = interf.getOptionsColumn().getData(); if (optionsMap != null && !optionsMap.isEmpty()) { List options = new ArrayList<>(); - String optionsValueString; - OptionsKey optionsKey; - for (String optionsKeyString : optionsMap.keySet()) { - optionsValueString = optionsMap.get(optionsKeyString); + for (Entry entry : optionsMap.entrySet()) { + String optionsKeyString = entry.getKey(); + String optionsValueString = entry.getValue(); if (optionsKeyString != null && optionsValueString != null) { - optionsKey = new OptionsKey(optionsKeyString); + OptionsKey optionsKey = new OptionsKey(optionsKeyString); options.add(new OptionsBuilder() - .setKey(optionsKey) + .withKey(optionsKey) .setValue(optionsValueString).build()); } } @@ -429,15 +629,16 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { } } - private void updatePortOtherConfig(final Port port, + @VisibleForTesting + void updatePortOtherConfig(final Port port, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Map portOtherConfigMap = port.getOtherConfigColumn().getData(); if (portOtherConfigMap != null && !portOtherConfigMap.isEmpty()) { List portOtherConfigs = new ArrayList<>(); - String portOtherConfigValueString; - for (String portOtherConfigKeyString : portOtherConfigMap.keySet()) { - portOtherConfigValueString = portOtherConfigMap.get(portOtherConfigKeyString); + for (Entry entry : portOtherConfigMap.entrySet()) { + String portOtherConfigKeyString = entry.getKey(); + String portOtherConfigValueString = entry.getValue(); if (portOtherConfigKeyString != null && portOtherConfigValueString != null) { portOtherConfigs.add(new PortOtherConfigsBuilder() .setOtherConfigKey(portOtherConfigKeyString) @@ -455,11 +656,12 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { Map interfaceLldpMap = interf.getLldpColumn().getData(); if (interfaceLldpMap != null && !interfaceLldpMap.isEmpty()) { List interfaceLldpList = new ArrayList<>(); - for (String interfaceLldpKeyString : interfaceLldpMap.keySet()) { - String interfaceLldpValueString = interfaceLldpMap.get(interfaceLldpKeyString); - if (interfaceLldpKeyString != null && interfaceLldpValueString!=null) { + for (Entry entry : interfaceLldpMap.entrySet()) { + String interfaceLldpKeyString = entry.getKey(); + String interfaceLldpValueString = entry.getValue(); + if (interfaceLldpKeyString != null && interfaceLldpValueString != null) { interfaceLldpList.add(new InterfaceLldpBuilder() - .setKey(new InterfaceLldpKey(interfaceLldpKeyString)) + .withKey(new InterfaceLldpKey(interfaceLldpKeyString)) .setLldpKey(interfaceLldpKeyString) .setLldpValue(interfaceLldpValueString) .build()); @@ -468,20 +670,20 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { ovsdbTerminationPointBuilder.setInterfaceLldp(interfaceLldpList); } } catch (SchemaVersionMismatchException e) { - // We don't care about the exception stack trace here - LOG.debug("lldp column for Interface Table unsupported for this version of ovsdb schema. {}", e.getMessage()); + schemaMismatchLog("lldp", "Interface", e); } } - private void updateInterfaceOtherConfig(final Interface interf, + @VisibleForTesting + void updateInterfaceOtherConfig(final Interface interf, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { Map interfaceOtherConfigMap = interf.getOtherConfigColumn().getData(); if (interfaceOtherConfigMap != null && !interfaceOtherConfigMap.isEmpty()) { List interfaceOtherConfigs = new ArrayList<>(); - String interfaceOtherConfigValueString; - for (String interfaceOtherConfigKeyString : interfaceOtherConfigMap.keySet()) { - interfaceOtherConfigValueString = interfaceOtherConfigMap.get(interfaceOtherConfigKeyString); + for (Entry entry : interfaceOtherConfigMap.entrySet()) { + String interfaceOtherConfigKeyString = entry.getKey(); + String interfaceOtherConfigValueString = entry.getValue(); if (interfaceOtherConfigKeyString != null && interfaceOtherConfigValueString != null) { interfaceOtherConfigs.add(new InterfaceOtherConfigsBuilder() .setOtherConfigKey(interfaceOtherConfigKeyString) @@ -492,6 +694,89 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { } } + private void updateInterfaceBfdStatus(final Interface interf, + final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { + + try { + Map interfaceBfdStatusMap = interf.getBfdStatusColumn().getData(); + if (interfaceBfdStatusMap != null && !interfaceBfdStatusMap.isEmpty()) { + List interfaceBfdStatusList = new ArrayList<>(); + for (Entry entry : interfaceBfdStatusMap.entrySet()) { + String interfaceBfdStatusKeyString = entry.getKey(); + String interfaceBfdStatusValueString = entry.getValue(); + if (interfaceBfdStatusKeyString != null && interfaceBfdStatusValueString != null) { + interfaceBfdStatusList.add(new InterfaceBfdStatusBuilder() + .withKey(new InterfaceBfdStatusKey(interfaceBfdStatusKeyString)) + .setBfdStatusKey(interfaceBfdStatusKeyString) + .setBfdStatusValue(interfaceBfdStatusValueString) + .build()); + } + } + ovsdbTerminationPointBuilder.setInterfaceBfdStatus(interfaceBfdStatusList); + } + } catch (SchemaVersionMismatchException e) { + schemaMismatchLog("bfd", "Interface", e); + } + } + + private void updateInterfaceBfd(final Interface interf, + final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { + + try { + Map interfaceBfdMap = interf.getBfdColumn().getData(); + if (interfaceBfdMap != null && !interfaceBfdMap.isEmpty()) { + List interfaceBfdList = new ArrayList<>(); + for (Entry entry : interfaceBfdMap.entrySet()) { + String interfaceBfdKeyString = entry.getKey(); + String interfaceBfdValueString = entry.getValue(); + if (interfaceBfdKeyString != null && interfaceBfdValueString != null) { + interfaceBfdList.add(new InterfaceBfdBuilder() + .withKey(new InterfaceBfdKey(interfaceBfdKeyString)) + .setBfdKey(interfaceBfdKeyString) + .setBfdValue(interfaceBfdValueString) + .build()); + } + } + ovsdbTerminationPointBuilder.setInterfaceBfd(interfaceBfdList); + } + } catch (SchemaVersionMismatchException e) { + schemaMismatchLog("bfd", "Interface", e); + + } + } + + private void updateInterfacePolicing(final Interface interf, + final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) { + + Long ingressPolicingRate = null; + if (interf.getIngressPolicingRateColumn() != null) { + ingressPolicingRate = interf.getIngressPolicingRateColumn().getData(); + } + if (ingressPolicingRate != null) { + if (ingressPolicingRate >= 0) { + ovsdbTerminationPointBuilder + .setIngressPolicingRate(ingressPolicingRate); + } else { + LOG.debug("Received negative value for ingressPolicingRate from ovsdb for {} {}", + interf.getName(),ingressPolicingRate); + } + } + + Long ingressPolicingBurst = null; + if (interf.getIngressPolicingBurstColumn() != null) { + ingressPolicingBurst = interf.getIngressPolicingBurstColumn().getData(); + } + if (ingressPolicingBurst != null) { + if (ingressPolicingBurst >= 0) { + ovsdbTerminationPointBuilder + .setIngressPolicingBurst(ingressPolicingBurst); + } else { + LOG.debug("Received negative value for ingressPolicingBurst from ovsdb for {} {}", + interf.getName(),ingressPolicingBurst); + } + } + } + private boolean portQosCleared(Entry portUpdate) { if (portUpdate.getValue().getQosColumn() == null) { return false; @@ -509,12 +794,14 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand { } } - private InstanceIdentifier getInstanceIdentifier(InstanceIdentifier bridgeIid,Port port) { + @SuppressWarnings("unchecked") + @VisibleForTesting + InstanceIdentifier getInstanceIdentifier(InstanceIdentifier bridgeIid,Port port) { if (port.getExternalIdsColumn() != null && port.getExternalIdsColumn().getData() != null && port.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) { String iidString = port.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY); - return (InstanceIdentifier) SouthboundUtil.deserializeInstanceIdentifier(iidString); + return (InstanceIdentifier) instanceIdentifierCodec.bindingDeserializerOrNull(iidString); } else { return bridgeIid.child(TerminationPoint.class, new TerminationPointKey(new TpId(port.getName()))); }