2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.hwvtepsouthbound.transactions.md;
10 import static java.util.Objects.requireNonNull;
13 import java.util.Optional;
14 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
15 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
16 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
17 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
18 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
19 import org.opendaylight.ovsdb.lib.message.TableUpdates;
20 import org.opendaylight.ovsdb.lib.notation.UUID;
21 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
22 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
23 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
24 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
25 import org.opendaylight.ovsdb.schema.hardwarevtep.Tunnel;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.Tunnels;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelsBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdLocalConfigsBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdParamsBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdRemoteConfigsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdStatusBuilder;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class HwvtepTunnelUpdateCommand extends AbstractTransactionCommand {
43 private static final Logger LOG = LoggerFactory.getLogger(HwvtepTunnelUpdateCommand.class);
44 private Map<UUID, Tunnel> updatedTunnelRows;
46 public HwvtepTunnelUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
47 super(key, updates, dbSchema);
49 updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(), getDbSchema());
50 } catch (IllegalArgumentException e) {
51 LOG.debug("Tunnel Table not supported on this HWVTEP device", e);
56 @SuppressWarnings("checkstyle:IllegalCatch")
57 public void execute(ReadWriteTransaction transaction) {
58 if (updatedTunnelRows != null && !updatedTunnelRows.isEmpty()) {
59 for (Tunnel tunnel : updatedTunnelRows.values()) {
61 updateTunnel(transaction, tunnel);
62 } catch (RuntimeException e) {
63 LOG.warn("Exception updating tunnel {}", tunnel, e);
69 private void updateTunnel(ReadWriteTransaction transaction, Tunnel tunnel) {
70 final UUID localData = requireNonNull(tunnel.getLocalColumn().getData());
71 final UUID remoteData = requireNonNull(tunnel.getRemoteColumn().getData());
72 final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
73 //TODO remove these reads
74 Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
75 PhysicalSwitch phySwitch =
76 getOvsdbConnectionInstance().getDeviceInfo().getPhysicalSwitchForTunnel(tunnel.getUuid());
78 InstanceIdentifier<Tunnels> tunnelIid = null;
79 if (phySwitch != null) {
80 InstanceIdentifier<Node> psIid =
81 HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), phySwitch);
82 tunnelIid = getInstanceIdentifier(psIid, tunnel);
85 if (connection.isPresent() && tunnelIid != null) {
86 TunnelsBuilder builder = new TunnelsBuilder();
87 builder.setLocalLocatorRef(new HwvtepPhysicalLocatorRef(getPhysicalLocatorRefFromUUID(
88 getOvsdbConnectionInstance().getInstanceIdentifier(), localData)));
89 builder.setRemoteLocatorRef(new HwvtepPhysicalLocatorRef(getPhysicalLocatorRefFromUUID(
90 getOvsdbConnectionInstance().getInstanceIdentifier(), remoteData)));
91 builder.setTunnelUuid(new Uuid(tunnel.getUuid().toString()));
92 setBfdLocalConfigs(builder, tunnel);
93 setBfdRemoteConfigs(builder, tunnel);
94 setBfdParams(builder, tunnel);
95 setBfdStatus(builder, tunnel);
96 Tunnels updatedTunnel = builder.build();
97 LOG.trace("Built with the intent to store tunnel data {}", updatedTunnel);
98 transaction.merge(LogicalDatastoreType.OPERATIONAL, tunnelIid, updatedTunnel);
99 // TODO: Deletion of Tunnel BFD config and params
101 LOG.warn("Insuficient information. Unable to update tunnel {}", tunnel.getUuid());
105 private static void setBfdLocalConfigs(TunnelsBuilder tunnelsBuilder, Tunnel tunnel) {
106 Map<String, String> localConfigs = tunnel.getBfdConfigLocalColumn().getData();
107 if (localConfigs != null && !localConfigs.isEmpty()) {
108 var localConfigsList = localConfigs.entrySet().stream()
109 .map(entry -> new BfdLocalConfigsBuilder()
110 .setBfdLocalConfigKey(entry.getKey())
111 .setBfdLocalConfigValue(entry.getValue())
113 .collect(BindingMap.toMap());
114 tunnelsBuilder.setBfdLocalConfigs(localConfigsList);
118 private static void setBfdRemoteConfigs(TunnelsBuilder tunnelsBuilder, Tunnel tunnel) {
119 Map<String, String> remoteConfigs = tunnel.getBfdConfigRemoteColumn().getData();
120 if (remoteConfigs != null && !remoteConfigs.isEmpty()) {
121 var remoteConfigsList = remoteConfigs.entrySet().stream()
122 .map(entry -> new BfdRemoteConfigsBuilder()
123 .setBfdRemoteConfigKey(entry.getKey())
124 .setBfdRemoteConfigValue(entry.getValue())
126 .collect(BindingMap.toMap());
127 tunnelsBuilder.setBfdRemoteConfigs(remoteConfigsList);
132 private static void setBfdParams(TunnelsBuilder tunnelsBuilder, Tunnel tunnel) {
133 Map<String, String> params = tunnel.getBfdParamsColumn().getData();
134 if (params != null && !params.isEmpty()) {
135 var paramsList = params.entrySet().stream()
136 .map(entry -> new BfdParamsBuilder()
137 .setBfdParamKey(entry.getKey())
138 .setBfdParamValue(entry.getValue())
140 .collect(BindingMap.toMap());
141 tunnelsBuilder.setBfdParams(paramsList);
145 private static void setBfdStatus(TunnelsBuilder tunnelsBuilder, Tunnel tunnel) {
146 Map<String, String> status = tunnel.getBfdStatusColumn().getData();
147 if (status != null && !status.isEmpty()) {
148 var statusList = status.entrySet().stream()
149 .map(entry -> new BfdStatusBuilder()
150 .setBfdStatusKey(entry.getKey())
151 .setBfdStatusValue(entry.getValue())
153 .collect(BindingMap.toMap());
154 tunnelsBuilder.setBfdStatus(statusList);
158 private InstanceIdentifier<Tunnels> getInstanceIdentifier(InstanceIdentifier<Node> psIid, Tunnel tunnel) {
159 InstanceIdentifier<Tunnels> result = null;
160 InstanceIdentifier<TerminationPoint> localTpPath =
161 getPhysicalLocatorRefFromUUID(getOvsdbConnectionInstance().getInstanceIdentifier(),
162 tunnel.getLocalColumn().getData());
163 InstanceIdentifier<TerminationPoint> remoteTpPath =
164 getPhysicalLocatorRefFromUUID(getOvsdbConnectionInstance().getInstanceIdentifier(),
165 tunnel.getRemoteColumn().getData());
166 if (remoteTpPath != null && localTpPath != null) {
167 result = HwvtepSouthboundMapper.createInstanceIdentifier(psIid, localTpPath, remoteTpPath);
172 private InstanceIdentifier<TerminationPoint> getPhysicalLocatorRefFromUUID(InstanceIdentifier<Node> nodeIid,
174 PhysicalLocator locator = getOvsdbConnectionInstance().getDeviceInfo().getPhysicalLocator(uuid);
175 if (locator == null) {
176 LOG.trace("Available PhysicalLocators: {}",
177 getOvsdbConnectionInstance().getDeviceInfo().getPhysicalLocators());
180 return HwvtepSouthboundMapper.createInstanceIdentifier(nodeIid, locator);