2 * Copyright (c) 2014 Intel Corp. and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.southbound.transactions.md;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import java.util.List;
18 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
21 import org.opendaylight.ovsdb.lib.message.TableUpdates;
22 import org.opendaylight.ovsdb.lib.notation.Column;
23 import org.opendaylight.ovsdb.lib.notation.UUID;
24 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
25 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
26 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
27 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
28 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
29 import org.opendaylight.ovsdb.schema.openvswitch.Port;
30 import org.opendaylight.ovsdb.southbound.OvsdbClientKey;
31 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
32 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
63 import com.google.common.base.Optional;
65 public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
66 private static final Logger LOG = LoggerFactory.getLogger(OvsdbPortUpdateCommand.class);
68 public OvsdbPortUpdateCommand(OvsdbClientKey key, TableUpdates updates,
69 DatabaseSchema dbSchema) {
70 super(key, updates, dbSchema);
74 public void execute(ReadWriteTransaction transaction) {
75 String bridgeName = null;
76 Collection<Port> portUpdatedRows = TyperUtils.extractRowsUpdated(
77 Port.class, getUpdates(), getDbSchema()).values();
78 Collection<Bridge> bridgeUpdatedRows = TyperUtils.extractRowsUpdated(
79 Bridge.class, getUpdates(), getDbSchema()).values();
80 for (Bridge bridge : bridgeUpdatedRows) {
81 Iterator<UUID> bridgePorts = bridge.getPortsColumn().getData()
83 while (bridgePorts.hasNext()) {
84 UUID portUUID = bridgePorts.next();
85 for (Port port : portUpdatedRows) {
86 if (portUUID.equals(port.getUuid())) {
87 bridgeName = bridge.getName();
88 NodeId bridgeId = SouthboundMapper.createManagedNodeId(
89 getKey(), new OvsdbBridgeName(bridgeName));
90 final InstanceIdentifier<Node> nodePath = SouthboundMapper
91 .createInstanceIdentifier(bridgeId);
92 Optional<Node> node = readNode(transaction, nodePath);
93 if (node.isPresent()) {
94 NodeBuilder nodeBuilder = buildNode(node, bridgeId, bridge, port);
95 transaction.merge(LogicalDatastoreType.OPERATIONAL,
96 nodePath, nodeBuilder.build());
104 private Optional<Node> readNode(final ReadWriteTransaction transaction, final InstanceIdentifier<Node> nodePath) {
105 Optional<Node> node = Optional.absent();
107 node = transaction.read(
108 LogicalDatastoreType.OPERATIONAL, nodePath)
110 } catch (final ReadFailedException e) {
111 LOG.warn("Read Operational/DS for Node fail! {}",
117 private NodeBuilder buildNode(final Optional<Node> node, final NodeId bridgeId, final Bridge bridge,
119 NodeBuilder nodeBuilder = new NodeBuilder();
120 nodeBuilder.setNodeId(bridgeId);
121 List<TerminationPoint> tpList = buildTpList(bridge, port);
122 nodeBuilder.setTerminationPoint(tpList);
123 nodeBuilder.addAugmentation(
124 OvsdbBridgeAugmentation.class,
125 node.get().getAugmentation(
126 OvsdbBridgeAugmentation.class));
130 private List<TerminationPoint> buildTpList(final Bridge bridge, final Port port) {
131 List<TerminationPoint> tpList = new ArrayList<TerminationPoint>();
132 TerminationPointBuilder entry = new TerminationPointBuilder();
133 entry.setTpId(new TpId(port.getName()));
134 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder =
135 new OvsdbTerminationPointAugmentationBuilder();
136 ovsdbTerminationPointBuilder
137 .setName(port.getName());
138 ovsdbTerminationPointBuilder.setPortUuid(new Uuid(
139 port.getUuid().toString()));
140 updatePort(port, ovsdbTerminationPointBuilder);
141 updateInterfaces(port, bridge, ovsdbTerminationPointBuilder);
142 entry.addAugmentation(
143 OvsdbTerminationPointAugmentation.class,
144 ovsdbTerminationPointBuilder.build());
145 tpList.add(entry.build());
149 private void updateInterfaces(final Port port, final Bridge bridge,
150 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
152 Column<GenericTableSchema, Set<UUID>> iface = port.getInterfacesColumn();
153 Set<UUID> ifUuid = iface.getData();
154 Collection<Interface> ifUpdateRows = TyperUtils.extractRowsUpdated(
155 Interface.class, getUpdates(), getDbSchema()).values();
156 updateInterfaces(ifUuid, ifUpdateRows, bridge, ovsdbTerminationPointBuilder);
159 private void updateInterfaces(final Set<UUID> ifUuid, final Collection<Interface> ifUpdateRows,
160 final Bridge bridge, final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
162 for (UUID ifIter : ifUuid) {
163 for (Interface interfIter : ifUpdateRows) {
164 Column<GenericTableSchema, String> typeColumn = interfIter.getTypeColumn();
165 String type = typeColumn.getData();
166 if ((interfIter.getUuid()).equals(ifIter)) {
167 updateInterface(interfIter, bridge, type, ovsdbTerminationPointBuilder);
174 private void updatePort(final Port port,
175 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
177 updateVlan(port, ovsdbTerminationPointBuilder);
178 updateVlanTrunks(port, ovsdbTerminationPointBuilder);
179 updateVlanMode(port, ovsdbTerminationPointBuilder);
180 updatePortExternalIds(port, ovsdbTerminationPointBuilder);
181 updatePortOtherConfig(port, ovsdbTerminationPointBuilder);
184 private void updateInterface(final Interface interf,
185 final Bridge bridge, final String type,
186 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
188 ovsdbTerminationPointBuilder.setInterfaceUuid(
189 new Uuid(interf.getUuid().toString()));
190 ovsdbTerminationPointBuilder.setInterfaceType(
191 SouthboundMapper.createInterfaceType(type));
192 updateOfPort(interf, bridge, ovsdbTerminationPointBuilder);
193 updateOfPortRequest(interf, bridge, ovsdbTerminationPointBuilder);
194 updateInterfaceExternalIds(interf, ovsdbTerminationPointBuilder);
195 updateOptions(interf, ovsdbTerminationPointBuilder);
196 updateInterfaceOtherConfig(interf, ovsdbTerminationPointBuilder);
199 private void updateVlan(final Port port,
200 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
202 Collection<Long> vlanId = port.getTagColumn().getData();
203 if (vlanId.size() > 0) {
204 Iterator<Long> itr = vlanId.iterator();
205 // There are no loops here, just get the first element.
206 int id = itr.next().intValue();
207 ovsdbTerminationPointBuilder.setVlanTag(new VlanId(id));
211 private void updateVlanTrunks(final Port port,
212 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
214 Set<Long> portTrunks = port.getTrunksColumn().getData();
215 List<Trunks> modelTrunks = new ArrayList<Trunks>();
216 if (!portTrunks.isEmpty()) {
217 for (Long trunk: portTrunks) {
219 modelTrunks.add(new TrunksBuilder()
220 .setTrunk(new VlanId(trunk.intValue())).build());
223 ovsdbTerminationPointBuilder.setTrunks(modelTrunks);
227 private void updateVlanMode(final Port port,
228 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
230 Collection<String> vlanMode = port.getVlanModeColumn().getData();
231 if (!vlanMode.isEmpty()) {
232 Iterator<String> itr = vlanMode.iterator();
233 String vlanType = itr.next();
234 if (vlanType.equals(SouthboundConstants.VLANMODES.ACCESS.getMode())) {
235 ovsdbTerminationPointBuilder
236 .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
237 } else if (vlanType.equals(SouthboundConstants.VLANMODES.NATIVE_TAGGED.getMode())) {
238 ovsdbTerminationPointBuilder
239 .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.NativeTagged);
240 } else if (vlanType.equals(SouthboundConstants.VLANMODES.NATIVE_UNTAGGED.getMode())) {
241 ovsdbTerminationPointBuilder
242 .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.NativeUntagged);
243 } else if (vlanType.equals(SouthboundConstants.VLANMODES.TRUNK.getMode())) {
244 ovsdbTerminationPointBuilder
245 .setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk);
247 LOG.debug("Invalid vlan mode {}.", vlanType);
252 private void updateOfPort(final Interface interf,
254 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
256 Set<Long> ofPorts = interf.getOpenFlowPortColumn().getData();
257 if (ofPorts != null && !ofPorts.isEmpty()) {
258 Iterator<Long> ofPortsIter = ofPorts.iterator();
259 long ofPort = ofPortsIter.next();
261 ovsdbTerminationPointBuilder
264 LOG.debug("Received negative value for ofPort from ovsdb for {} {} {}",
265 bridge.getName(), interf.getName(),ofPort);
270 private void updateOfPortRequest(final Interface interf,
272 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
274 Set<Long> ofPortRequests = interf
275 .getOpenFlowPortRequestColumn().getData();
276 if (ofPortRequests != null && !ofPortRequests.isEmpty()) {
277 Iterator<Long> ofPortRequestsIter = ofPortRequests.iterator();
278 int ofPort = ofPortRequestsIter.next().intValue();
280 ovsdbTerminationPointBuilder
281 .setOfportRequest(ofPort);
283 LOG.debug("Received negative value for ofPort from ovsdb for {} {} {}",
284 bridge.getName(), interf.getName(),ofPort);
289 private void updateInterfaceExternalIds(final Interface interf,
290 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
292 Map<String, String> interfaceExternalIds =
293 interf.getExternalIdsColumn().getData();
294 if (interfaceExternalIds != null && !interfaceExternalIds.isEmpty()) {
295 Set<String> externalIdKeys = interfaceExternalIds.keySet();
296 List<InterfaceExternalIds> externalIdsList =
297 new ArrayList<InterfaceExternalIds>();
298 String externalIdValue;
299 for (String externalIdKey : externalIdKeys) {
300 externalIdValue = interfaceExternalIds.get(externalIdKey);
301 if (externalIdKey != null && externalIdValue != null) {
302 externalIdsList.add(new InterfaceExternalIdsBuilder()
303 .setExternalIdKey(externalIdKey)
304 .setExternalIdValue(externalIdValue).build());
307 ovsdbTerminationPointBuilder.setInterfaceExternalIds(externalIdsList);
311 private void updatePortExternalIds(final Port port,
312 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
314 Map<String, String> portExternalIds = port.getExternalIdsColumn().getData();
315 if (portExternalIds != null && !portExternalIds.isEmpty()) {
316 Set<String> externalIdKeys = portExternalIds.keySet();
317 List<PortExternalIds> externalIdsList = new ArrayList<PortExternalIds>();
318 String externalIdValue;
319 for (String externalIdKey : externalIdKeys) {
320 externalIdValue = portExternalIds.get(externalIdKey);
321 if (externalIdKey != null && externalIdValue != null) {
322 externalIdsList.add(new PortExternalIdsBuilder()
323 .setExternalIdKey(externalIdKey)
324 .setExternalIdValue(externalIdValue).build());
327 ovsdbTerminationPointBuilder.setPortExternalIds(externalIdsList);
331 private void updateOptions(final Interface interf,
332 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
334 Map<String, String> optionsMap = interf.getOptionsColumn().getData();
335 if (optionsMap != null && !optionsMap.isEmpty()) {
336 List<Options> options = new ArrayList<Options>();
337 String optionsValueString;
338 OptionsKey optionsKey;
339 for (String optionsKeyString : optionsMap.keySet()) {
340 optionsValueString = optionsMap.get(optionsKeyString);
341 if (optionsKeyString != null && optionsValueString != null) {
342 optionsKey = new OptionsKey(optionsKeyString);
343 options.add(new OptionsBuilder()
345 .setValue(optionsValueString).build());
348 ovsdbTerminationPointBuilder.setOptions(options);
352 private void updatePortOtherConfig(final Port port,
353 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
355 Map<String, String> portOtherConfigMap = port.getOtherConfigColumn().getData();
356 if (portOtherConfigMap != null && !portOtherConfigMap.isEmpty()) {
357 List<PortOtherConfigs> portOtherConfigs = new ArrayList<PortOtherConfigs>();
358 String portOtherConfigValueString;
359 for (String portOtherConfigKeyString : portOtherConfigMap.keySet()) {
360 portOtherConfigValueString = portOtherConfigMap.get(portOtherConfigKeyString);
361 if (portOtherConfigKeyString != null && portOtherConfigValueString != null) {
362 portOtherConfigs.add(new PortOtherConfigsBuilder()
363 .setOtherConfigKey(portOtherConfigKeyString)
364 .setOtherConfigValue(portOtherConfigValueString).build());
367 ovsdbTerminationPointBuilder.setPortOtherConfigs(portOtherConfigs);
371 private void updateInterfaceOtherConfig(final Interface interf,
372 final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
374 Map<String, String> interfaceOtherConfigMap = interf.getOtherConfigColumn().getData();
375 if (interfaceOtherConfigMap != null && !interfaceOtherConfigMap.isEmpty()) {
376 List<InterfaceOtherConfigs> interfaceOtherConfigs = new ArrayList<InterfaceOtherConfigs>();
377 String interfaceOtherConfigValueString;
378 for (String interfaceOtherConfigKeyString : interfaceOtherConfigMap.keySet()) {
379 interfaceOtherConfigValueString = interfaceOtherConfigMap.get(interfaceOtherConfigKeyString);
380 if (interfaceOtherConfigKeyString != null && interfaceOtherConfigValueString != null) {
381 interfaceOtherConfigs.add(new InterfaceOtherConfigsBuilder()
382 .setOtherConfigKey(interfaceOtherConfigKeyString)
383 .setOtherConfigValue(interfaceOtherConfigValueString).build());
386 ovsdbTerminationPointBuilder.setInterfaceOtherConfigs(interfaceOtherConfigs);