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;
12 import java.util.List;
14 import java.util.Optional;
15 import java.util.stream.Collectors;
16 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
18 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
19 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
20 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
21 import org.opendaylight.ovsdb.lib.message.TableUpdates;
22 import org.opendaylight.ovsdb.lib.notation.UUID;
23 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
24 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
25 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
26 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
27 import org.opendaylight.ovsdb.schema.hardwarevtep.Tunnel;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.Tunnels;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelsBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdLocalConfigs;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdLocalConfigsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdParams;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdParamsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdRemoteConfigs;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdRemoteConfigsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdStatus;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdStatusBuilder;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 public class HwvtepTunnelUpdateCommand extends AbstractTransactionCommand {
48 private static final Logger LOG = LoggerFactory.getLogger(HwvtepTunnelUpdateCommand.class);
49 private Map<UUID, Tunnel> updatedTunnelRows;
51 public HwvtepTunnelUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
52 super(key, updates, dbSchema);
54 updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(), getDbSchema());
55 } catch (IllegalArgumentException e) {
56 LOG.debug("Tunnel Table not supported on this HWVTEP device", e);
61 @SuppressWarnings("checkstyle:IllegalCatch")
62 public void execute(ReadWriteTransaction transaction) {
63 if (updatedTunnelRows != null && !updatedTunnelRows.isEmpty()) {
64 for (Tunnel tunnel : updatedTunnelRows.values()) {
66 updateTunnel(transaction, tunnel);
67 } catch (RuntimeException e) {
68 LOG.warn("Exception updating tunnel {}", tunnel, e);
74 private void updateTunnel(ReadWriteTransaction transaction, Tunnel tunnel) {
75 final UUID localData = requireNonNull(tunnel.getLocalColumn().getData());
76 final UUID remoteData = requireNonNull(tunnel.getRemoteColumn().getData());
77 final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
78 //TODO remove these reads
79 Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
80 PhysicalSwitch phySwitch =
81 getOvsdbConnectionInstance().getDeviceInfo().getPhysicalSwitchForTunnel(tunnel.getUuid());
83 InstanceIdentifier<Tunnels> tunnelIid = null;
84 if (phySwitch != null) {
85 InstanceIdentifier<Node> psIid =
86 HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), phySwitch);
87 tunnelIid = getInstanceIdentifier(psIid, tunnel);
90 if (connection.isPresent() && tunnelIid != null) {
91 TunnelsBuilder builder = new TunnelsBuilder();
92 builder.setLocalLocatorRef(new HwvtepPhysicalLocatorRef(getPhysicalLocatorRefFromUUID(
93 getOvsdbConnectionInstance().getInstanceIdentifier(), localData)));
94 builder.setRemoteLocatorRef(new HwvtepPhysicalLocatorRef(getPhysicalLocatorRefFromUUID(
95 getOvsdbConnectionInstance().getInstanceIdentifier(), remoteData)));
96 builder.setTunnelUuid(new Uuid(tunnel.getUuid().toString()));
97 setBfdLocalConfigs(builder, tunnel);
98 setBfdRemoteConfigs(builder, tunnel);
99 setBfdParams(builder, tunnel);
100 setBfdStatus(builder, tunnel);
101 Tunnels updatedTunnel = builder.build();
102 LOG.trace("Built with the intent to store tunnel data {}", updatedTunnel);
103 transaction.merge(LogicalDatastoreType.OPERATIONAL, tunnelIid, updatedTunnel);
104 // TODO: Deletion of Tunnel BFD config and params
106 LOG.warn("Insuficient information. Unable to update tunnel {}", tunnel.getUuid());
110 private static void setBfdLocalConfigs(TunnelsBuilder tunnelsBuilder, Tunnel tunnel) {
111 Map<String, String> localConfigs = tunnel.getBfdConfigLocalColumn().getData();
112 if (localConfigs != null && !localConfigs.isEmpty()) {
113 List<BfdLocalConfigs> localConfigsList = localConfigs.entrySet().stream().map(
114 entry -> new BfdLocalConfigsBuilder().setBfdLocalConfigKey(entry.getKey())
115 .setBfdLocalConfigValue(entry.getValue()).build()).collect(Collectors.toList());
117 tunnelsBuilder.setBfdLocalConfigs(localConfigsList);
121 private static void setBfdRemoteConfigs(TunnelsBuilder tunnelsBuilder, Tunnel tunnel) {
122 Map<String, String> remoteConfigs = tunnel.getBfdConfigRemoteColumn().getData();
123 if (remoteConfigs != null && !remoteConfigs.isEmpty()) {
124 List<BfdRemoteConfigs> remoteConfigsList = remoteConfigs.entrySet().stream().map(
125 entry -> new BfdRemoteConfigsBuilder().setBfdRemoteConfigKey(entry.getKey())
126 .setBfdRemoteConfigValue(entry.getValue()).build()).collect(Collectors.toList());
128 tunnelsBuilder.setBfdRemoteConfigs(remoteConfigsList);
133 private static void setBfdParams(TunnelsBuilder tunnelsBuilder, Tunnel tunnel) {
134 Map<String, String> params = tunnel.getBfdParamsColumn().getData();
135 if (params != null && !params.isEmpty()) {
136 List<BfdParams> paramsList = params.entrySet().stream().map(
137 entry -> new BfdParamsBuilder().setBfdParamKey(entry.getKey())
138 .setBfdParamValue(entry.getValue()).build()).collect(Collectors.toList());
140 tunnelsBuilder.setBfdParams(paramsList);
144 private static void setBfdStatus(TunnelsBuilder tunnelsBuilder, Tunnel tunnel) {
145 Map<String, String> status = tunnel.getBfdStatusColumn().getData();
146 if (status != null && !status.isEmpty()) {
147 List<BfdStatus> statusList = status.entrySet().stream().map(
148 entry -> new BfdStatusBuilder().setBfdStatusKey(entry.getKey())
149 .setBfdStatusValue(entry.getValue()).build()).collect(Collectors.toList());
151 tunnelsBuilder.setBfdStatus(statusList);
155 private InstanceIdentifier<Tunnels> getInstanceIdentifier(InstanceIdentifier<Node> psIid, Tunnel tunnel) {
156 InstanceIdentifier<Tunnels> result = null;
157 InstanceIdentifier<TerminationPoint> localTpPath =
158 getPhysicalLocatorRefFromUUID(getOvsdbConnectionInstance().getInstanceIdentifier(),
159 tunnel.getLocalColumn().getData());
160 InstanceIdentifier<TerminationPoint> remoteTpPath =
161 getPhysicalLocatorRefFromUUID(getOvsdbConnectionInstance().getInstanceIdentifier(),
162 tunnel.getRemoteColumn().getData());
163 if (remoteTpPath != null && localTpPath != null) {
164 result = HwvtepSouthboundMapper.createInstanceIdentifier(psIid, localTpPath, remoteTpPath);
169 private InstanceIdentifier<TerminationPoint> getPhysicalLocatorRefFromUUID(InstanceIdentifier<Node> nodeIid,
171 PhysicalLocator locator = getOvsdbConnectionInstance().getDeviceInfo().getPhysicalLocator(uuid);
172 if (locator == null) {
173 LOG.trace("Available PhysicalLocators: {}",
174 getOvsdbConnectionInstance().getDeviceInfo().getPhysicalLocators());
177 return HwvtepSouthboundMapper.createInstanceIdentifier(nodeIid, locator);