Upgrade ietf-{inet,yang}-types to 2013-07-15
[ovsdb.git] / southbound / southbound-impl / src / main / java / org / opendaylight / ovsdb / southbound / transactions / md / OvsdbPortUpdateCommand.java
1 /*
2  * Copyright (c) 2014 Intel Corp. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.ovsdb.southbound.transactions.md;
10
11 import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
12
13 import com.google.common.base.Optional;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Map.Entry;
20 import java.util.Set;
21 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
24 import org.opendaylight.ovsdb.lib.error.ColumnSchemaNotFoundException;
25 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
26 import org.opendaylight.ovsdb.lib.message.TableUpdates;
27 import org.opendaylight.ovsdb.lib.notation.Column;
28 import org.opendaylight.ovsdb.lib.notation.UUID;
29 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
30 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
31 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
32 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
33 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
34 import org.opendaylight.ovsdb.schema.openvswitch.Port;
35 import org.opendaylight.ovsdb.schema.openvswitch.Qos;
36 import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
37 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
38 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
39 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQosRef;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfd;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatus;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatusBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatusKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntry;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntryBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.QosEntryKey;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
76 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
77 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
78 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
79 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
80 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
81 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
82 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
83 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
84 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
85 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
86 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
87 import org.slf4j.Logger;
88 import org.slf4j.LoggerFactory;
89
90 public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
91     private static final Logger LOG = LoggerFactory.getLogger(OvsdbPortUpdateCommand.class);
92     private Map<UUID, Port> portUpdatedRows;
93     private Map<UUID, Port> portOldRows;
94     private Map<UUID, Interface> interfaceUpdatedRows;
95     private Map<UUID, Interface> interfaceOldRows;
96     private Map<UUID, Bridge> bridgeUpdatedRows;
97     private Map<UUID, Qos> qosUpdatedRows;
98
99     public OvsdbPortUpdateCommand(OvsdbConnectionInstance key, TableUpdates updates,
100             DatabaseSchema dbSchema) {
101         super(key, updates, dbSchema);
102         portUpdatedRows = TyperUtils.extractRowsUpdated(Port.class, updates, dbSchema);
103         portOldRows = TyperUtils.extractRowsOld(Port.class, updates, dbSchema);
104         interfaceUpdatedRows = TyperUtils.extractRowsUpdated(Interface.class, updates, dbSchema);
105         interfaceOldRows = TyperUtils.extractRowsOld(Interface.class, updates, dbSchema);
106         bridgeUpdatedRows = TyperUtils.extractRowsUpdated(Bridge.class, updates, dbSchema);
107         qosUpdatedRows = TyperUtils.extractRowsUpdated(Qos.class, updates, dbSchema);
108     }
109
110     @Override
111     public void execute(ReadWriteTransaction transaction) {
112         final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
113         if ( (portUpdatedRows == null && interfaceOldRows == null )
114                 || ( interfaceOldRows.isEmpty() && portUpdatedRows.isEmpty())) {
115             return;
116         }
117         Optional<Node> node = readNode(transaction, connectionIId);
118         if (node.isPresent()) {
119             updateTerminationPoints(transaction, node.get());
120         }
121     }
122
123     private void updateTerminationPoints(ReadWriteTransaction transaction, Node node) {
124         for (Entry<UUID, Port> portUpdate : portUpdatedRows.entrySet()) {
125             String portName = null;
126             portName = portUpdate.getValue().getNameColumn().getData();
127             Optional<InstanceIdentifier<Node>> bridgeIid = getTerminationPointBridge(portUpdate.getKey());
128             if (!bridgeIid.isPresent()) {
129                 bridgeIid = getTerminationPointBridge( transaction, node, portName);
130             }
131             if (bridgeIid.isPresent()) {
132                 NodeId bridgeId = SouthboundMapper.createManagedNodeId(bridgeIid.get());
133                 TerminationPointKey tpKey = new TerminationPointKey(new TpId(portName));
134                 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
135                 tpBuilder.setKey(tpKey);
136                 tpBuilder.setTpId(tpKey.getTpId());
137                 InstanceIdentifier<TerminationPoint> tpPath =
138                         getInstanceIdentifier(bridgeIid.get(), portUpdate.getValue());
139                 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
140                         new OvsdbTerminationPointAugmentationBuilder();
141                 buildTerminationPoint(transaction, tpPath, tpAugmentationBuilder, node, portUpdate);
142                 UUID interfaceUuid = (UUID)portUpdate.getValue().getInterfacesColumn().getData().toArray()[0];
143                 if (interfaceUpdatedRows.containsKey(interfaceUuid)) {
144                     buildTerminationPoint(tpAugmentationBuilder, interfaceUpdatedRows.get(interfaceUuid));
145                     interfaceUpdatedRows.remove(interfaceUuid);
146                     interfaceOldRows.remove(interfaceUuid);
147                 }
148                 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
149                 if (portOldRows.containsKey(portUpdate.getKey()) && !portQosCleared(portUpdate)) {
150                     transaction.merge(LogicalDatastoreType.OPERATIONAL,
151                             tpPath, tpBuilder.build());
152                 } else {
153                     transaction.put(LogicalDatastoreType.OPERATIONAL,
154                             tpPath, tpBuilder.build());
155                 }
156             }
157         }
158         for (Entry<UUID, Interface> interfaceUpdate : interfaceUpdatedRows.entrySet()) {
159             String interfaceName = null;
160             interfaceName = interfaceUpdatedRows.get(interfaceUpdate.getKey()).getNameColumn().getData();
161             Optional<InstanceIdentifier<Node>> bridgeIid = getTerminationPointBridge( transaction, node, interfaceName);
162             if (bridgeIid.isPresent()) {
163                 TerminationPointKey tpKey = new TerminationPointKey(new TpId(interfaceName));
164                 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
165                 tpBuilder.setKey(tpKey);
166                 tpBuilder.setTpId(tpKey.getTpId());
167                 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
168                         new OvsdbTerminationPointAugmentationBuilder();
169                 buildTerminationPoint(tpAugmentationBuilder, interfaceUpdate.getValue());
170                 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
171                 NodeId bridgeId = SouthboundMapper.createManagedNodeId(bridgeIid.get());
172                 InstanceIdentifier<TerminationPoint> tpPath = InstanceIdentifier
173                         .create(NetworkTopology.class)
174                         .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
175                         .child(Node.class,new NodeKey(bridgeId))
176                         .child(TerminationPoint.class,tpKey);
177                 transaction.merge(LogicalDatastoreType.OPERATIONAL,
178                         tpPath, tpBuilder.build());
179             }
180         }
181
182     }
183
184     private void buildTerminationPoint(ReadWriteTransaction transaction,
185             InstanceIdentifier<TerminationPoint> tpPath,
186             OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder,
187             Node node, Entry<UUID, Port> portUpdate) {
188
189         tpAugmentationBuilder
190                 .setName(portUpdate.getValue().getName());
191         tpAugmentationBuilder.setPortUuid(new Uuid(
192                 portUpdate.getValue().getUuid().toString()));
193         updatePort(transaction, node, tpPath, portUpdate, tpAugmentationBuilder);
194     }
195
196     private void buildTerminationPoint(OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder,
197             Interface interfaceUpdate) {
198
199         tpAugmentationBuilder
200                 .setName(interfaceUpdate.getName());
201         tpAugmentationBuilder.setInterfaceUuid(new Uuid(
202                 interfaceUpdate.getUuid().toString()));
203         updateInterfaces(interfaceUpdate, tpAugmentationBuilder);
204     }
205
206     private Optional<Node> readNode(final ReadWriteTransaction transaction, final InstanceIdentifier<Node> nodePath) {
207         Optional<Node> node = Optional.absent();
208         try {
209             node = transaction.read(
210                     LogicalDatastoreType.OPERATIONAL, nodePath)
211                     .checkedGet();
212         } catch (final ReadFailedException e) {
213             LOG.warn("Read Operational/DS for Node fail! {}",
214                     nodePath, e);
215         }
216         return node;
217     }
218
219     private Optional<InstanceIdentifier<Node>> getTerminationPointBridge(UUID portUuid) {
220         for (UUID bridgeUuid : this.bridgeUpdatedRows.keySet()) {
221             if (this.bridgeUpdatedRows.get(bridgeUuid).getPortsColumn().getData().contains(portUuid)) {
222                 return Optional.of(SouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
223                         this.bridgeUpdatedRows.get(bridgeUuid)));
224             }
225         }
226         return Optional.absent();
227     }
228
229     @SuppressWarnings("unchecked")
230     private Optional<InstanceIdentifier<Node>> getTerminationPointBridge(
231             final ReadWriteTransaction transaction, Node node, String tpName) {
232         OvsdbNodeAugmentation ovsdbNode = node.getAugmentation(OvsdbNodeAugmentation.class);
233         List<ManagedNodeEntry> managedNodes = ovsdbNode.getManagedNodeEntry();
234         TpId tpId = new TpId(tpName);
235         for ( ManagedNodeEntry managedNodeEntry : managedNodes ) {
236             Node managedNode = readNode(transaction,
237                     (InstanceIdentifier<Node>)managedNodeEntry.getBridgeRef().getValue()).get();
238             for (TerminationPoint tpEntry : managedNode.getTerminationPoint()) {
239                 if (tpId.equals(tpEntry.getTpId())) {
240                     return Optional.of((InstanceIdentifier<Node>)managedNodeEntry.getBridgeRef().getValue());
241                 }
242             }
243         }
244         return Optional.absent();
245     }
246
247     private void updateInterfaces(Interface interfaceUpdate,
248             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
249
250         Column<GenericTableSchema, String> typeColumn = interfaceUpdate.getTypeColumn();
251         String type = typeColumn.getData();
252         updateInterface(interfaceUpdate, type,ovsdbTerminationPointBuilder);
253     }
254
255     private void updatePort(final ReadWriteTransaction transaction, final Node node,
256             final InstanceIdentifier<TerminationPoint> tpPath, final Entry<UUID, Port> port,
257             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
258
259         updateVlan(port.getValue(), ovsdbTerminationPointBuilder);
260         updateVlanTrunks(port.getValue(), ovsdbTerminationPointBuilder);
261         updateVlanMode(port.getValue(), ovsdbTerminationPointBuilder);
262         updateQos(transaction, node, tpPath, port, ovsdbTerminationPointBuilder);
263         updatePortExternalIds(port.getValue(), ovsdbTerminationPointBuilder);
264         updatePortOtherConfig(port.getValue(), ovsdbTerminationPointBuilder);
265     }
266
267     private void updateInterface(final Interface interf,
268             final String type,
269             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
270
271         ovsdbTerminationPointBuilder.setInterfaceUuid(
272                 new Uuid(interf.getUuid().toString()));
273         ovsdbTerminationPointBuilder.setInterfaceType(
274                 SouthboundMapper.createInterfaceType(type));
275         updateIfIndex(interf, ovsdbTerminationPointBuilder);
276         updateOfPort(interf, ovsdbTerminationPointBuilder);
277         updateOfPortRequest(interf, ovsdbTerminationPointBuilder);
278         updateInterfaceExternalIds(interf, ovsdbTerminationPointBuilder);
279         updateOptions(interf, ovsdbTerminationPointBuilder);
280         updateInterfaceOtherConfig(interf, ovsdbTerminationPointBuilder);
281         updateInterfaceLldp(interf, ovsdbTerminationPointBuilder);
282         updateInterfaceBfd(interf, ovsdbTerminationPointBuilder);
283         updateInterfaceBfdStatus(interf, ovsdbTerminationPointBuilder);
284         updateInterfacePolicing(interf, ovsdbTerminationPointBuilder);
285     }
286
287     private void updateVlan(final Port port,
288             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
289
290         Collection<Long> vlanId = port.getTagColumn().getData();
291         if (vlanId.size() > 0) {
292             Iterator<Long> itr = vlanId.iterator();
293             // There are no loops here, just get the first element.
294             int id = itr.next().intValue();
295             ovsdbTerminationPointBuilder.setVlanTag(new VlanId(id));
296         }
297     }
298
299     private void updateVlanTrunks(final Port port,
300             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
301
302         Set<Long> portTrunks = port.getTrunksColumn().getData();
303         List<Trunks> modelTrunks = new ArrayList<>();
304         if (!portTrunks.isEmpty()) {
305             for (Long trunk: portTrunks) {
306                 if (trunk != null) {
307                     modelTrunks.add(new TrunksBuilder()
308                         .setTrunk(new VlanId(trunk.intValue())).build());
309                 }
310             }
311             ovsdbTerminationPointBuilder.setTrunks(modelTrunks);
312         }
313     }
314
315     private void updateVlanMode(final Port port,
316             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
317
318         Collection<String> vlanMode = port.getVlanModeColumn().getData();
319         if (!vlanMode.isEmpty()) {
320             Iterator<String> itr = vlanMode.iterator();
321             String vlanType = itr.next();
322             if (vlanType.equals(SouthboundConstants.VlanModes.ACCESS.getMode())) {
323                 ovsdbTerminationPointBuilder
324                     .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
325             } else if (vlanType.equals(SouthboundConstants.VlanModes.NATIVE_TAGGED.getMode())) {
326                 ovsdbTerminationPointBuilder
327                     .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.NativeTagged);
328             } else if (vlanType.equals(SouthboundConstants.VlanModes.NATIVE_UNTAGGED.getMode())) {
329                 ovsdbTerminationPointBuilder
330                     .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.NativeUntagged);
331             } else if (vlanType.equals(SouthboundConstants.VlanModes.TRUNK.getMode())) {
332                 ovsdbTerminationPointBuilder
333                     .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk);
334             } else {
335                 LOG.debug("Invalid vlan mode {}.", vlanType);
336             }
337         }
338     }
339
340     @SuppressWarnings("unchecked")
341     private void updateQos(final ReadWriteTransaction transaction, final Node node,
342                            InstanceIdentifier<TerminationPoint> tpPath, final Entry<UUID, Port> port,
343                            final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
344         if (port.getValue() == null) {
345             return;
346         }
347         Collection<UUID> qosUuidCol = port.getValue().getQosColumn().getData();
348         if (!qosUuidCol.isEmpty()) {
349             UUID qosUuid = qosUuidCol.iterator().next();
350             ovsdbTerminationPointBuilder.setQos(new Uuid(qosUuid.toString()));
351
352             NodeId nodeId = node.getNodeId();
353             OvsdbNodeAugmentation ovsdbNode = node.getAugmentation(OvsdbNodeAugmentation.class);
354
355             // Delete an older QoS entry
356             if (portOldRows.containsKey(port.getKey()) && portOldRows.get(port.getKey()).getQosColumn() != null) {
357                 Collection<UUID> oldQos = portOldRows.get(port.getKey()).getQosColumn().getData();
358                 if (!oldQos.isEmpty()) {
359                     UUID oldQosUuid = oldQos.iterator().next();
360                     if (!oldQosUuid.equals(qosUuid)) {
361                         InstanceIdentifier<QosEntries> oldQosIid = getQosIid(nodeId, ovsdbNode, oldQosUuid);
362                         if (oldQosIid != null) {
363                             InstanceIdentifier<QosEntry> oldPortQosIid = tpPath
364                                 .augmentation(OvsdbTerminationPointAugmentation.class)
365                                 .child(QosEntry.class,
366                                       new QosEntryKey(new Long(SouthboundConstants.PORT_QOS_LIST_KEY)));
367 //                                    new QosEntryKey(new OvsdbQosRef(oldQosIid)));
368                             transaction.delete(LogicalDatastoreType.OPERATIONAL, oldPortQosIid);
369                         }
370                     }
371                 }
372             }
373
374             InstanceIdentifier<QosEntries> qosIid = getQosIid(nodeId, ovsdbNode, qosUuid);
375             if (qosIid != null) {
376                 List<QosEntry> qosList = new ArrayList<>();
377                 OvsdbQosRef qosRef = new OvsdbQosRef(qosIid);
378                 qosList.add(new QosEntryBuilder()
379                     .setKey(new QosEntryKey(new Long(SouthboundConstants.PORT_QOS_LIST_KEY)))
380                     .setQosRef(qosRef).build());
381                 ovsdbTerminationPointBuilder.setQosEntry(qosList);
382             }
383         }
384     }
385
386     @SuppressWarnings("unchecked")
387     private InstanceIdentifier<QosEntries> getQosIid(NodeId nodeId, OvsdbNodeAugmentation ovsdbNode, UUID qosUuid) {
388         // Search for the QoS entry first in the operational datastore
389         for (QosEntries qosEntry : ovsdbNode.getQosEntries()) {
390             if (qosEntry.getQosUuid().equals(new Uuid(qosUuid.toString()))) {
391                 return SouthboundMapper.createInstanceIdentifier(nodeId)
392                         .augmentation(OvsdbNodeAugmentation.class)
393                         .child(QosEntries.class, new QosEntriesKey(qosEntry.getQosId()));
394             }
395         }
396
397         // Search for the QoS entry in the current OVS updates
398         for (Entry<UUID, Qos> qosUpdate : qosUpdatedRows.entrySet()) {
399             Qos qos = qosUpdate.getValue();
400             if (qos.getUuid().equals(qosUuid)) {
401                 if (qos.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) {
402                     return (InstanceIdentifier<QosEntries>) SouthboundUtil.deserializeInstanceIdentifier(
403                             qos.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY));
404                 } else {
405                     return SouthboundMapper.createInstanceIdentifier(nodeId)
406                             .augmentation(OvsdbNodeAugmentation.class)
407                             .child(QosEntries.class, new QosEntriesKey(
408                                     new Uri(SouthboundConstants.QOS_URI_PREFIX + "://" + qosUuid.toString())));
409                 }
410             }
411         }
412         LOG.debug("QoS UUID {} assigned to port not found in operational node {} or QoS updates", qosUuid, ovsdbNode);
413         return SouthboundMapper.createInstanceIdentifier(nodeId)
414                 .augmentation(OvsdbNodeAugmentation.class)
415                 .child(QosEntries.class, new QosEntriesKey(
416                         new Uri(SouthboundConstants.QOS_URI_PREFIX + "://" + qosUuid.toString())));
417     }
418
419     private void updateIfIndex(final Interface interf,
420             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
421         Set<Long> ifIndexSet = null;
422         try {
423             if (interf.getIfIndexColumn() != null) {
424                 ifIndexSet = interf.getIfIndexColumn().getData();
425             }
426             if (ifIndexSet != null && !ifIndexSet.isEmpty()) {
427                 for (Long ifIndex : ifIndexSet) {
428                     ovsdbTerminationPointBuilder.setIfindex(ifIndex);
429                 }
430             }
431         } catch (SchemaVersionMismatchException e) {
432             schemaMismatchLog("ifindex", "Interface", e);
433         }
434     }
435
436     private void updateOfPort(final Interface interf,
437             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
438
439         Set<Long> ofPorts = interf.getOpenFlowPortColumn().getData();
440         if (ofPorts != null && !ofPorts.isEmpty()) {
441             Iterator<Long> ofPortsIter = ofPorts.iterator();
442             long ofPort = ofPortsIter.next();
443             if (ofPort >= 0) {
444                 ovsdbTerminationPointBuilder
445                     .setOfport(ofPort);
446             } else {
447                 LOG.debug("Received negative value for ofPort from ovsdb for {} {} {}",
448                         interf.getName(),ofPort);
449             }
450         }
451     }
452
453     private void updateOfPortRequest(final Interface interf,
454             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
455
456         Set<Long> ofPortRequests = null;
457         try {
458             ofPortRequests = interf.getOpenFlowPortRequestColumn().getData();
459         } catch (ColumnSchemaNotFoundException e) {
460             LOG.warn("Cannot find openflow column", e);
461         }
462         if (ofPortRequests != null && !ofPortRequests.isEmpty()) {
463             Iterator<Long> ofPortRequestsIter = ofPortRequests.iterator();
464             int ofPort = ofPortRequestsIter.next().intValue();
465             if (ofPort >= 0) {
466                 ovsdbTerminationPointBuilder
467                     .setOfportRequest(ofPort);
468             } else {
469                 LOG.debug("Received negative value for ofPort from ovsdb for {} {} {}",
470                         interf.getName(),ofPort);
471             }
472         }
473     }
474
475     private void updateInterfaceExternalIds(final Interface interf,
476             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
477
478         Map<String, String> interfaceExternalIds =
479                 interf.getExternalIdsColumn().getData();
480         if (interfaceExternalIds != null && !interfaceExternalIds.isEmpty()) {
481             Set<String> externalIdKeys = interfaceExternalIds.keySet();
482             List<InterfaceExternalIds> externalIdsList =
483                     new ArrayList<>();
484             String externalIdValue;
485             for (String externalIdKey : externalIdKeys) {
486                 externalIdValue = interfaceExternalIds.get(externalIdKey);
487                 if (externalIdKey != null && externalIdValue != null) {
488                     externalIdsList.add(new InterfaceExternalIdsBuilder()
489                             .setExternalIdKey(externalIdKey)
490                             .setExternalIdValue(externalIdValue).build());
491                 }
492             }
493             ovsdbTerminationPointBuilder.setInterfaceExternalIds(externalIdsList);
494         }
495     }
496
497     private void updatePortExternalIds(final Port port,
498             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
499
500         Map<String, String> portExternalIds = port.getExternalIdsColumn().getData();
501         if (portExternalIds != null && !portExternalIds.isEmpty()) {
502             Set<String> externalIdKeys = portExternalIds.keySet();
503             List<PortExternalIds> externalIdsList = new ArrayList<>();
504             String externalIdValue;
505             for (String externalIdKey : externalIdKeys) {
506                 externalIdValue = portExternalIds.get(externalIdKey);
507                 if (externalIdKey != null && externalIdValue != null) {
508                     externalIdsList.add(new PortExternalIdsBuilder()
509                             .setExternalIdKey(externalIdKey)
510                             .setExternalIdValue(externalIdValue).build());
511                 }
512             }
513             ovsdbTerminationPointBuilder.setPortExternalIds(externalIdsList);
514         }
515     }
516
517     private void updateOptions(final Interface interf,
518             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
519
520         Map<String, String> optionsMap = interf.getOptionsColumn().getData();
521         if (optionsMap != null && !optionsMap.isEmpty()) {
522             List<Options> options = new ArrayList<>();
523             String optionsValueString;
524             OptionsKey optionsKey;
525             for (String optionsKeyString : optionsMap.keySet()) {
526                 optionsValueString = optionsMap.get(optionsKeyString);
527                 if (optionsKeyString != null && optionsValueString != null) {
528                     optionsKey = new OptionsKey(optionsKeyString);
529                     options.add(new OptionsBuilder()
530                         .setKey(optionsKey)
531                         .setValue(optionsValueString).build());
532                 }
533             }
534             ovsdbTerminationPointBuilder.setOptions(options);
535         }
536     }
537
538     private void updatePortOtherConfig(final Port port,
539             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
540
541         Map<String, String> portOtherConfigMap = port.getOtherConfigColumn().getData();
542         if (portOtherConfigMap != null && !portOtherConfigMap.isEmpty()) {
543             List<PortOtherConfigs> portOtherConfigs = new ArrayList<>();
544             String portOtherConfigValueString;
545             for (String portOtherConfigKeyString : portOtherConfigMap.keySet()) {
546                 portOtherConfigValueString = portOtherConfigMap.get(portOtherConfigKeyString);
547                 if (portOtherConfigKeyString != null && portOtherConfigValueString != null) {
548                     portOtherConfigs.add(new PortOtherConfigsBuilder()
549                         .setOtherConfigKey(portOtherConfigKeyString)
550                         .setOtherConfigValue(portOtherConfigValueString).build());
551                 }
552             }
553             ovsdbTerminationPointBuilder.setPortOtherConfigs(portOtherConfigs);
554         }
555     }
556
557     private void updateInterfaceLldp(final Interface interf,
558             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
559
560         try {
561             Map<String, String> interfaceLldpMap = interf.getLldpColumn().getData();
562             if (interfaceLldpMap != null && !interfaceLldpMap.isEmpty()) {
563                 List<InterfaceLldp> interfaceLldpList = new ArrayList<>();
564                 for (String interfaceLldpKeyString : interfaceLldpMap.keySet()) {
565                     String interfaceLldpValueString = interfaceLldpMap.get(interfaceLldpKeyString);
566                     if (interfaceLldpKeyString != null && interfaceLldpValueString != null) {
567                         interfaceLldpList.add(new InterfaceLldpBuilder()
568                                 .setKey(new InterfaceLldpKey(interfaceLldpKeyString))
569                                 .setLldpKey(interfaceLldpKeyString)
570                                 .setLldpValue(interfaceLldpValueString)
571                                 .build());
572                     }
573                 }
574                 ovsdbTerminationPointBuilder.setInterfaceLldp(interfaceLldpList);
575             }
576         } catch (SchemaVersionMismatchException e) {
577             schemaMismatchLog("lldp", "Interface", e);
578         }
579     }
580
581     private void updateInterfaceOtherConfig(final Interface interf,
582             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
583
584         Map<String, String> interfaceOtherConfigMap = interf.getOtherConfigColumn().getData();
585         if (interfaceOtherConfigMap != null && !interfaceOtherConfigMap.isEmpty()) {
586             List<InterfaceOtherConfigs> interfaceOtherConfigs = new ArrayList<>();
587             String interfaceOtherConfigValueString;
588             for (String interfaceOtherConfigKeyString : interfaceOtherConfigMap.keySet()) {
589                 interfaceOtherConfigValueString = interfaceOtherConfigMap.get(interfaceOtherConfigKeyString);
590                 if (interfaceOtherConfigKeyString != null && interfaceOtherConfigValueString != null) {
591                     interfaceOtherConfigs.add(new InterfaceOtherConfigsBuilder()
592                         .setOtherConfigKey(interfaceOtherConfigKeyString)
593                         .setOtherConfigValue(interfaceOtherConfigValueString).build());
594                 }
595             }
596             ovsdbTerminationPointBuilder.setInterfaceOtherConfigs(interfaceOtherConfigs);
597         }
598     }
599
600     private void updateInterfaceBfdStatus(final Interface interf,
601             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
602
603         try {
604             Map<String, String> interfaceBfdStatusMap = interf.getBfdStatusColumn().getData();
605             if (interfaceBfdStatusMap != null && !interfaceBfdStatusMap.isEmpty()) {
606                 List<InterfaceBfdStatus> interfaceBfdStatusList = new ArrayList<>();
607                 for (String interfaceBfdStatusKeyString : interfaceBfdStatusMap.keySet()) {
608                     String interfaceBfdStatusValueString = interfaceBfdStatusMap.get(interfaceBfdStatusKeyString);
609                     if (interfaceBfdStatusKeyString != null && interfaceBfdStatusValueString != null) {
610                         interfaceBfdStatusList.add(new InterfaceBfdStatusBuilder()
611                                 .setKey(new InterfaceBfdStatusKey(interfaceBfdStatusKeyString))
612                                 .setBfdStatusKey(interfaceBfdStatusKeyString)
613                                 .setBfdStatusValue(interfaceBfdStatusValueString)
614                                 .build());
615                     }
616                 }
617                 ovsdbTerminationPointBuilder.setInterfaceBfdStatus(interfaceBfdStatusList);
618             }
619         } catch (SchemaVersionMismatchException e) {
620             schemaMismatchLog("bfd", "Interface", e);
621         }
622     }
623
624     private void updateInterfaceBfd(final Interface interf,
625             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
626
627         try {
628             Map<String, String> interfaceBfdMap = interf.getBfdColumn().getData();
629             if (interfaceBfdMap != null && !interfaceBfdMap.isEmpty()) {
630                 List<InterfaceBfd> interfaceBfdList = new ArrayList<>();
631                 for (String interfaceBfdKeyString : interfaceBfdMap.keySet()) {
632                     String interfaceBfdValueString = interfaceBfdMap.get(interfaceBfdKeyString);
633                     if (interfaceBfdKeyString != null && interfaceBfdValueString != null) {
634                         interfaceBfdList.add(new InterfaceBfdBuilder()
635                                 .setKey(new InterfaceBfdKey(interfaceBfdKeyString))
636                                 .setBfdKey(interfaceBfdKeyString)
637                                 .setBfdValue(interfaceBfdValueString)
638                                 .build());
639                     }
640                 }
641                 ovsdbTerminationPointBuilder.setInterfaceBfd(interfaceBfdList);
642             }
643         } catch (SchemaVersionMismatchException e) {
644             schemaMismatchLog("bfd", "Interface", e);
645
646         }
647     }
648
649     private void updateInterfacePolicing(final Interface interf,
650             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
651
652         Long ingressPolicingRate = null;
653         if (interf.getIngressPolicingRateColumn() != null) {
654             ingressPolicingRate = interf.getIngressPolicingRateColumn().getData();
655         }
656         if (ingressPolicingRate != null) {
657             if (ingressPolicingRate >= 0) {
658                 ovsdbTerminationPointBuilder
659                     .setIngressPolicingRate(ingressPolicingRate);
660             } else {
661                 LOG.debug("Received negative value for ingressPolicingRate from ovsdb for {} {}",
662                         interf.getName(),ingressPolicingRate);
663             }
664         }
665
666         Long ingressPolicingBurst = null;
667         if (interf.getIngressPolicingBurstColumn() != null) {
668             ingressPolicingBurst = interf.getIngressPolicingBurstColumn().getData();
669         }
670         if (ingressPolicingBurst != null) {
671             if (ingressPolicingBurst >= 0) {
672                 ovsdbTerminationPointBuilder
673                     .setIngressPolicingBurst(ingressPolicingBurst);
674             } else {
675                 LOG.debug("Received negative value for ingressPolicingBurst from ovsdb for {} {}",
676                         interf.getName(),ingressPolicingBurst);
677             }
678         }
679     }
680
681     private boolean portQosCleared(Entry<UUID, Port> portUpdate) {
682         if (portUpdate.getValue().getQosColumn() == null) {
683             return false;
684         }
685         Collection<UUID> newQos = portUpdate.getValue().getQosColumn().getData();
686         if (portOldRows.get(portUpdate.getKey()).getQosColumn() == null) {
687             return false;
688         }
689         Collection<UUID> oldQos = portOldRows.get(portUpdate.getKey()).getQosColumn().getData();
690
691         if (newQos.isEmpty() && !oldQos.isEmpty()) {
692             return true;
693         } else {
694             return false;
695         }
696     }
697
698     @SuppressWarnings("unchecked")
699     private InstanceIdentifier<TerminationPoint> getInstanceIdentifier(InstanceIdentifier<Node> bridgeIid,Port port) {
700         if (port.getExternalIdsColumn() != null
701                 && port.getExternalIdsColumn().getData() != null
702                 && port.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) {
703             String iidString = port.getExternalIdsColumn().getData().get(SouthboundConstants.IID_EXTERNAL_ID_KEY);
704             return (InstanceIdentifier<TerminationPoint>) SouthboundUtil.deserializeInstanceIdentifier(iidString);
705         } else {
706             return bridgeIid.child(TerminationPoint.class, new TerminationPointKey(new TpId(port.getName())));
707         }
708     }
709 }