2 * Copyright © 2015, 2017 Brocade Communications Systems, Inc. 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
8 package org.opendaylight.ovsdb.southbound.ovsdb.transact;
10 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
11 import static org.opendaylight.ovsdb.southbound.SouthboundUtil.schemaMismatchLog;
13 import com.google.common.base.Optional;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
22 import java.util.Map.Entry;
24 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
25 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
26 import org.opendaylight.ovsdb.lib.notation.Mutator;
27 import org.opendaylight.ovsdb.lib.notation.UUID;
28 import org.opendaylight.ovsdb.lib.operations.Mutate;
29 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
30 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
31 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
32 import org.opendaylight.ovsdb.schema.openvswitch.Port;
33 import org.opendaylight.ovsdb.southbound.InstanceIdentifierCodec;
34 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
35 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
36 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
37 import org.opendaylight.ovsdb.utils.yang.YangUtils;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfd;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
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.node.TerminationPoint;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.opendaylight.yangtools.yang.common.Uint16;
53 import org.opendaylight.yangtools.yang.common.Uint32;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
57 public class TerminationPointCreateCommand implements TransactCommand {
59 private static final Logger LOG = LoggerFactory.getLogger(TerminationPointCreateCommand.class);
62 public void execute(final TransactionBuilder transaction, final BridgeOperationalState state,
63 final DataChangeEvent events, final InstanceIdentifierCodec instanceIdentifierCodec) {
64 execute(transaction, state, TransactUtils.extractCreated(events, OvsdbTerminationPointAugmentation.class),
65 TransactUtils.extractCreatedOrUpdated(events, Node.class), instanceIdentifierCodec);
69 public void execute(final TransactionBuilder transaction, final BridgeOperationalState state,
70 final Collection<DataTreeModification<Node>> modifications,
71 final InstanceIdentifierCodec instanceIdentifierCodec) {
72 execute(transaction, state,
73 TransactUtils.extractCreated(modifications, OvsdbTerminationPointAugmentation.class),
74 TransactUtils.extractCreatedOrUpdated(modifications, Node.class), instanceIdentifierCodec);
77 private void execute(final TransactionBuilder transaction, final BridgeOperationalState state,
78 final Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation>
79 createdTerminationPoints,
80 final Map<InstanceIdentifier<Node>, Node> nodes, final InstanceIdentifierCodec instanceIdentifierCodec) {
81 for (Entry<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation> entry :
82 createdTerminationPoints.entrySet()) {
83 OvsdbTerminationPointAugmentation terminationPoint = entry.getValue();
84 LOG.debug("Received request to create termination point {}",
85 terminationPoint.getName());
86 InstanceIdentifier terminationPointIid = entry.getKey();
87 Optional<TerminationPoint> terminationPointOptional =
88 state.getBridgeTerminationPoint(terminationPointIid);
89 if (!terminationPointOptional.isPresent()) {
90 // Configure interface
91 String interfaceUuid = "Interface_" + SouthboundMapper.getRandomUuid();
92 Interface ovsInterface = transaction.getTypedRowWrapper(Interface.class);
93 createInterface(terminationPoint, ovsInterface);
94 transaction.add(op.insert(ovsInterface).withId(interfaceUuid));
96 stampInstanceIdentifier(transaction, entry.getKey(), ovsInterface.getName(), instanceIdentifierCodec);
98 // Configure port with the above interface details
99 String portUuid = "Port_" + SouthboundMapper.getRandomUuid();
100 Port port = transaction.getTypedRowWrapper(Port.class);
101 final String opendaylightIid = instanceIdentifierCodec.serialize(terminationPointIid);
102 createPort(terminationPoint, port, interfaceUuid, opendaylightIid);
103 transaction.add(op.insert(port).withId(portUuid));
104 LOG.info("Created Termination Point : {} with Uuid : {}",
105 terminationPoint.getName(),portUuid);
106 //Configure bridge with the above port details
107 Bridge bridge = transaction.getTypedRowWrapper(Bridge.class);
108 String bridgeName = SouthboundUtil
109 .getBridgeNameFromOvsdbNodeId(entry.getKey().firstIdentifierOf(Node.class));
110 if (bridgeName != null) {
111 LOG.trace("Updating bridge {} for newly added port {}", bridgeName, terminationPoint.getName());
112 bridge.setName(bridgeName);
113 bridge.setPorts(Collections.singleton(new UUID(portUuid)));
115 transaction.add(op.mutate(bridge)
116 .addMutation(bridge.getPortsColumn().getSchema(),
117 Mutator.INSERT, bridge.getPortsColumn().getData())
118 .where(bridge.getNameColumn().getSchema()
119 .opEqual(bridge.getNameColumn().getData())).build());
121 LOG.error("Missing BridgeName for Node {} during creation of port {}",
122 entry.getKey().firstIdentifierOf(Node.class), terminationPoint.getName());
129 private void createInterface(
130 final OvsdbTerminationPointAugmentation terminationPoint,
131 final Interface ovsInterface) {
132 ovsInterface.setName(terminationPoint.getName());
134 createInterfaceType(terminationPoint, ovsInterface);
135 createOfPort(terminationPoint, ovsInterface);
136 createOfPortRequest(terminationPoint, ovsInterface);
137 createInterfaceOptions(terminationPoint, ovsInterface);
138 createInterfaceOtherConfig(terminationPoint, ovsInterface);
139 createInterfaceExternalIds(terminationPoint, ovsInterface);
140 createInterfaceLldp(terminationPoint, ovsInterface);
141 createInterfaceBfd(terminationPoint, ovsInterface);
144 private static void createInterfaceType(final OvsdbTerminationPointAugmentation terminationPoint,
145 final Interface ovsInterface) {
146 Class<? extends InterfaceTypeBase> mdsaltype = terminationPoint.getInterfaceType();
147 if (mdsaltype != null) {
148 ovsInterface.setType(SouthboundMapper.createOvsdbInterfaceType(mdsaltype));
152 private void createPort(
153 final OvsdbTerminationPointAugmentation terminationPoint,
154 final Port port, final String interfaceUuid, final String opendaylightIid) {
156 port.setName(terminationPoint.getName());
157 port.setInterfaces(Collections.singleton(new UUID(interfaceUuid)));
158 createPortOtherConfig(terminationPoint, port);
159 createPortVlanTag(terminationPoint, port);
160 createPortVlanTrunk(terminationPoint, port);
161 createPortVlanMode(terminationPoint, port);
162 createPortExternalIds(terminationPoint, port, opendaylightIid);
165 private void createOfPort(
166 final OvsdbTerminationPointAugmentation terminationPoint,
167 final Interface ovsInterface) {
169 Uint32 ofPort = terminationPoint.getOfport();
170 if (ofPort != null) {
171 ovsInterface.setOpenFlowPort(Collections.singleton(ofPort.toJava()));
175 private void createOfPortRequest(
176 final OvsdbTerminationPointAugmentation terminationPoint,
177 final Interface ovsInterface) {
179 Uint16 ofPortRequest = terminationPoint.getOfportRequest();
180 if (ofPortRequest != null) {
181 ovsInterface.setOpenFlowPortRequest(Collections.singleton(ofPortRequest.longValue()));
185 private void createInterfaceOptions(
186 final OvsdbTerminationPointAugmentation terminationPoint,
187 final Interface ovsInterface) {
189 //Configure optional input
190 if (terminationPoint.getOptions() != null) {
192 ovsInterface.setOptions(YangUtils.convertYangKeyValueListToMap(terminationPoint.getOptions(),
193 Options::getOption, Options::getValue));
194 } catch (NullPointerException e) {
195 LOG.warn("Incomplete OVSDB interface options", e);
200 private void createInterfaceExternalIds(
201 final OvsdbTerminationPointAugmentation terminationPoint,
202 final Interface ovsInterface) {
204 List<InterfaceExternalIds> interfaceExternalIds =
205 terminationPoint.getInterfaceExternalIds();
206 if (interfaceExternalIds != null && !interfaceExternalIds.isEmpty()) {
207 interfaceExternalIds.add(SouthboundUtil.createExternalIdsForInterface(
208 SouthboundConstants.CREATED_BY, SouthboundConstants.ODL));
210 interfaceExternalIds = Arrays.asList(SouthboundUtil.createExternalIdsForInterface(
211 SouthboundConstants.CREATED_BY, SouthboundConstants.ODL));
214 ovsInterface.setExternalIds(YangUtils.convertYangKeyValueListToMap(interfaceExternalIds,
215 InterfaceExternalIds::getExternalIdKey, InterfaceExternalIds::getExternalIdValue));
216 } catch (NullPointerException e) {
217 LOG.warn("Incomplete OVSDB interface external_ids", e);
221 private void createInterfaceOtherConfig(
222 final OvsdbTerminationPointAugmentation terminationPoint,
223 final Interface ovsInterface) {
225 List<InterfaceOtherConfigs> interfaceOtherConfigs =
226 terminationPoint.getInterfaceOtherConfigs();
227 if (interfaceOtherConfigs != null && !interfaceOtherConfigs.isEmpty()) {
228 Map<String, String> otherConfigsMap = new HashMap<>();
229 for (InterfaceOtherConfigs interfaceOtherConfig : interfaceOtherConfigs) {
230 otherConfigsMap.put(interfaceOtherConfig.getOtherConfigKey(),
231 interfaceOtherConfig.getOtherConfigValue());
234 ovsInterface.setOtherConfig(otherConfigsMap);
235 } catch (NullPointerException e) {
236 LOG.warn("Incomplete OVSDB interface other_config", e);
241 private void createInterfaceLldp(
242 final OvsdbTerminationPointAugmentation terminationPoint,
243 final Interface ovsInterface) {
246 List<InterfaceLldp> interfaceLldpList =
247 terminationPoint.getInterfaceLldp();
248 if (interfaceLldpList != null && !interfaceLldpList.isEmpty()) {
250 ovsInterface.setLldp(YangUtils.convertYangKeyValueListToMap(interfaceLldpList,
251 InterfaceLldp::getLldpKey, InterfaceLldp::getLldpValue));
252 } catch (NullPointerException e) {
253 LOG.warn("Incomplete OVSDB interface lldp", e);
256 } catch (SchemaVersionMismatchException e) {
257 schemaMismatchLog("lldp", "Interface", e);
261 private void createInterfaceBfd(final OvsdbTerminationPointAugmentation terminationPoint,
262 final Interface ovsInterface) {
265 List<InterfaceBfd> interfaceBfdList = terminationPoint.getInterfaceBfd();
266 if (interfaceBfdList != null && !interfaceBfdList.isEmpty()) {
268 ovsInterface.setBfd(YangUtils.convertYangKeyValueListToMap(interfaceBfdList,
269 InterfaceBfd::getBfdKey, InterfaceBfd::getBfdValue));
270 } catch (NullPointerException e) {
271 LOG.warn("Incomplete OVSDB interface bfd", e);
274 } catch (SchemaVersionMismatchException e) {
275 schemaMismatchLog("bfd", "Interface", e);
279 private void createPortExternalIds(
280 final OvsdbTerminationPointAugmentation terminationPoint,
281 final Port port, final String opendaylightIid) {
283 // Set the iid external_id
284 List<PortExternalIds> portExternalIds = terminationPoint.getPortExternalIds();
285 if (portExternalIds != null && !portExternalIds.isEmpty()) {
286 portExternalIds.add(SouthboundUtil.createExternalIdsForPort(
287 SouthboundConstants.CREATED_BY, SouthboundConstants.ODL));
288 portExternalIds.add(SouthboundUtil.createExternalIdsForPort(
289 SouthboundConstants.IID_EXTERNAL_ID_KEY, opendaylightIid));
291 portExternalIds = new ArrayList<>();
292 portExternalIds.add(SouthboundUtil.createExternalIdsForPort(
293 SouthboundConstants.CREATED_BY, SouthboundConstants.ODL));
294 portExternalIds.add(SouthboundUtil.createExternalIdsForPort(
295 SouthboundConstants.IID_EXTERNAL_ID_KEY, opendaylightIid));
298 port.setExternalIds(YangUtils.convertYangKeyValueListToMap(portExternalIds,
299 PortExternalIds::getExternalIdKey, PortExternalIds::getExternalIdValue));
300 //YangUtils.copyYangKeyValueListToMap(externalIdMap, terminationPoint.getPortExternalIds(),
301 // PortExternalIds::getExternalIdKey, PortExternalIds::getExternalIdValue);
302 } catch (NullPointerException e) {
303 LOG.warn("Incomplete OVSDB port external_ids", e);
307 private void createPortVlanTag(
308 final OvsdbTerminationPointAugmentation terminationPoint,
311 if (terminationPoint.getVlanTag() != null) {
312 Set<Long> vlanTag = new HashSet<>();
313 vlanTag.add(terminationPoint.getVlanTag().getValue().longValue());
314 port.setTag(vlanTag);
318 private void createPortVlanTrunk(
319 final OvsdbTerminationPointAugmentation terminationPoint,
322 if (terminationPoint.getTrunks() != null && terminationPoint.getTrunks().size() > 0) {
323 Set<Long> portTrunks = new HashSet<>();
324 List<Trunks> modelTrunks = terminationPoint.getTrunks();
325 for (Trunks trunk: modelTrunks) {
326 if (trunk.getTrunk() != null) {
327 portTrunks.add(trunk.getTrunk().getValue().longValue());
330 port.setTrunks(portTrunks);
334 private void createPortVlanMode(
335 final OvsdbTerminationPointAugmentation terminationPoint,
337 if (terminationPoint.getVlanMode() != null) {
338 Set<String> portVlanMode = new HashSet<>();
339 VlanMode modelVlanMode = terminationPoint.getVlanMode();
340 portVlanMode.add(SouthboundConstants.VlanModes.values()[modelVlanMode.getIntValue() - 1].getMode());
341 port.setVlanMode(portVlanMode);
345 private void createPortOtherConfig(
346 final OvsdbTerminationPointAugmentation terminationPoint,
347 final Port ovsPort) {
348 List<PortOtherConfigs> portOtherConfigs =
349 terminationPoint.getPortOtherConfigs();
350 if (portOtherConfigs != null && !portOtherConfigs.isEmpty()) {
352 ovsPort.setOtherConfig(YangUtils.convertYangKeyValueListToMap(portOtherConfigs,
353 PortOtherConfigs::getOtherConfigKey, PortOtherConfigs::getOtherConfigValue));
354 } catch (NullPointerException e) {
355 LOG.warn("Incomplete OVSDB port other_config", e);
360 public static void stampInstanceIdentifier(final TransactionBuilder transaction,
361 final InstanceIdentifier<OvsdbTerminationPointAugmentation> iid, final String interfaceName,
362 final InstanceIdentifierCodec instanceIdentifierCodec) {
363 Port port = transaction.getTypedRowWrapper(Port.class);
364 port.setName(interfaceName);
365 port.setExternalIds(Collections.emptyMap());
366 Mutate mutate = TransactUtils.stampInstanceIdentifierMutation(transaction, iid, port.getSchema(),
367 port.getExternalIdsColumn().getSchema(), instanceIdentifierCodec);
368 transaction.add(mutate
369 .where(port.getNameColumn().getSchema().opEqual(interfaceName))