Merge "Add support for external-ids in the OVSDB node"
[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 java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17
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.SouthboundMapper;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 import com.google.common.base.Optional;
58
59 public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
60     private static final Logger LOG = LoggerFactory.getLogger(OvsdbPortUpdateCommand.class);
61
62     public OvsdbPortUpdateCommand(OvsdbClientKey key, TableUpdates updates,
63             DatabaseSchema dbSchema) {
64         super(key, updates, dbSchema);
65     }
66
67     @Override
68     public void execute(ReadWriteTransaction transaction) {
69         String bridgeName = null;
70         Collection<Port> portUpdatedRows = TyperUtils.extractRowsUpdated(
71                 Port.class, getUpdates(), getDbSchema()).values();
72         Collection<Bridge> bridgeUpdatedRows = TyperUtils.extractRowsUpdated(
73                 Bridge.class, getUpdates(), getDbSchema()).values();
74         for (Bridge bridge : bridgeUpdatedRows) {
75             Iterator<UUID> bridgePorts = bridge.getPortsColumn().getData()
76                     .iterator();
77             while (bridgePorts.hasNext()) {
78                 UUID portUUID = bridgePorts.next();
79                 for (Port port : portUpdatedRows) {
80                     if (portUUID.equals(port.getUuid())) {
81                         Collection<Long> vlanId = port.getTagColumn().getData();
82                         Set<Long> portTrunks = port.getTrunksColumn().getData();
83                         bridgeName = bridge.getName();
84                         NodeId bridgeId = SouthboundMapper.createManagedNodeId(
85                                 getKey(), new OvsdbBridgeName(bridgeName));
86                         final InstanceIdentifier<Node> nodePath = SouthboundMapper
87                                 .createInstanceIdentifier(bridgeId);
88                         Optional<Node> node = Optional.absent();
89                         try {
90                             node = transaction.read(
91                                     LogicalDatastoreType.OPERATIONAL, nodePath)
92                                     .checkedGet();
93                         } catch (final ReadFailedException e) {
94                             LOG.warn("Read Operational/DS for Node fail! {}",
95                                     nodePath, e);
96                         }
97                         if (node.isPresent()) {
98                             NodeBuilder nodeBuilder = new NodeBuilder();
99                             nodeBuilder.setNodeId(bridgeId);
100
101                             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder
102                                 = new OvsdbTerminationPointAugmentationBuilder();
103                             List<TerminationPoint> tpList = new ArrayList<TerminationPoint>();
104                             TerminationPointBuilder entry = new TerminationPointBuilder();
105                             entry.setTpId(new TpId(port.getName()));
106                             ovsdbTerminationPointBuilder
107                                     .setName(port.getName());
108                             ovsdbTerminationPointBuilder.setPortUuid(new Uuid(
109                                     port.getUuid().toString()));
110                             if (vlanId.size() > 0) {
111                                 Iterator<Long> itr = vlanId.iterator();
112                                 // There are no loops here, just get the first element.
113                                 int id = itr.next().intValue();
114                                 ovsdbTerminationPointBuilder.setVlanTag(new VlanId(id));
115                             }
116                             List<Trunks> modelTrunks = new ArrayList<Trunks>();
117                             for (Long trunk: portTrunks) {
118                                 if (trunk != null) {
119                                     modelTrunks.add(new TrunksBuilder().setTrunk(new VlanId(trunk.intValue())).build());
120                                 }
121                             }
122                             ovsdbTerminationPointBuilder.setTrunks(modelTrunks);
123
124                             Map<String, String> portExternalIds = port.getExternalIdsColumn().getData();
125                             if (portExternalIds != null && !portExternalIds.isEmpty()) {
126                                 Set<String> externalIdKeys = portExternalIds.keySet();
127                                 List<PortExternalIds> externalIdsList = new ArrayList<PortExternalIds>();
128                                 String externalIdValue;
129                                 for (String externalIdKey : externalIdKeys) {
130                                     externalIdValue = portExternalIds.get(externalIdKey);
131                                     if (externalIdKey != null && externalIdValue != null) {
132                                         externalIdsList.add(new PortExternalIdsBuilder()
133                                                 .setExternalIdKey(externalIdKey)
134                                                 .setExternalIdValue(externalIdValue).build());
135                                     }
136                                 }
137                                 ovsdbTerminationPointBuilder.setPortExternalIds(externalIdsList);
138                             }
139
140                             Column<GenericTableSchema, Set<UUID>> iface = port.getInterfacesColumn();
141                             Set<UUID> ifUuid = iface.getData();
142                             Collection<Interface> ifUpdateRows = TyperUtils.extractRowsUpdated(
143                                     Interface.class, getUpdates(),  getDbSchema()).values();
144                             for (UUID ifIter : ifUuid) {
145                                 for (Interface interfIter : ifUpdateRows) {
146                                     Column<GenericTableSchema, String> typeColumn = interfIter.getTypeColumn();
147                                     String type = typeColumn.getData();
148                                     if ((interfIter.getUuid()).equals(ifIter)) {
149                                         ovsdbTerminationPointBuilder.setInterfaceUuid(
150                                                 new Uuid(interfIter.getUuid().toString()));
151                                         ovsdbTerminationPointBuilder.setInterfaceType(
152                                                 SouthboundMapper.createInterfaceType(type));
153                                         Set<Long> ofPorts = interfIter.getOpenFlowPortColumn().getData();
154                                         if (ofPorts != null && !ofPorts.isEmpty()) {
155                                             Iterator<Long> ofPortsIter = ofPorts.iterator();
156                                             long ofPort = ofPortsIter.next();
157                                             if (ofPort >= 0) {
158                                                 ovsdbTerminationPointBuilder
159                                                     .setOfport(ofPort);
160                                             } else {
161                                                 LOG.debug("Received negative value for ofPort from ovsdb for {} {} {}",
162                                                         bridge.getName(), interfIter.getName(),ofPort);
163                                             }
164                                         }
165                                         Set<Long> ofPortRequests = interfIter
166                                                 .getOpenFlowPortRequestColumn().getData();
167                                         if (ofPortRequests != null && !ofPortRequests.isEmpty()) {
168                                             Iterator<Long> ofPortRequestsIter = ofPortRequests.iterator();
169                                             int ofPort = ofPortRequestsIter.next().intValue();
170                                             if (ofPort >= 0) {
171                                                 ovsdbTerminationPointBuilder
172                                                     .setOfportRequest(ofPort);
173                                             } else {
174                                                 LOG.debug("Received negative value for ofPort from ovsdb for {} {} {}",
175                                                         bridge.getName(), interfIter.getName(),ofPort);
176                                             }
177                                         }
178
179                                         Map<String, String> interfaceExternalIds =
180                                                 interfIter.getExternalIdsColumn().getData();
181                                         if (interfaceExternalIds != null && !interfaceExternalIds.isEmpty()) {
182                                             Set<String> externalIdKeys = interfaceExternalIds.keySet();
183                                             List<InterfaceExternalIds> externalIdsList =
184                                                     new ArrayList<InterfaceExternalIds>();
185                                             String externalIdValue;
186                                             for (String externalIdKey : externalIdKeys) {
187                                                 externalIdValue = interfaceExternalIds.get(externalIdKey);
188                                                 if (externalIdKey != null && externalIdValue != null) {
189                                                     externalIdsList.add(new InterfaceExternalIdsBuilder()
190                                                             .setExternalIdKey(externalIdKey)
191                                                             .setExternalIdValue(externalIdValue).build());
192                                                 }
193                                             }
194                                             ovsdbTerminationPointBuilder.setInterfaceExternalIds(externalIdsList);
195                                         }
196
197                                         Map<String, String> optionsMap = interfIter.getOptionsColumn().getData();
198                                         if (optionsMap != null && !optionsMap.isEmpty()) {
199                                             List<Options> options = new ArrayList<Options>();
200                                             String optionsValueString;
201                                             OptionsKey optionsKey;
202                                             for (String optionsKeyString : optionsMap.keySet()) {
203                                                 optionsValueString = optionsMap.get(optionsKeyString);
204                                                 if (optionsKeyString != null && optionsValueString != null) {
205                                                     optionsKey = new OptionsKey(optionsKeyString);
206                                                     options.add(new OptionsBuilder()
207                                                         .setKey(optionsKey)
208                                                         .setValue(optionsValueString).build());
209                                                 }
210                                             }
211                                             ovsdbTerminationPointBuilder.setOptions(options);
212                                         }
213
214                                         break;
215                                     }
216                                 }
217                             }
218                             entry.addAugmentation(
219                                     OvsdbTerminationPointAugmentation.class,
220                                     ovsdbTerminationPointBuilder.build());
221
222                             tpList.add(entry.build());
223                             nodeBuilder.setTerminationPoint(tpList);
224                             nodeBuilder.addAugmentation(
225                                     OvsdbBridgeAugmentation.class,
226                                     node.get().getAugmentation(
227                                             OvsdbBridgeAugmentation.class));
228                             transaction.merge(LogicalDatastoreType.OPERATIONAL,
229                                     nodePath, nodeBuilder.build());
230                         }
231                     }
232                 }
233             }
234         }
235     }
236 }