2 * Copyright (c) 2015 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
9 package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
11 import java.util.ArrayList;
12 import java.util.List;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.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.inet.types.rev100924.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchRef;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.SwitchesBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIps;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.Tunnels;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelsBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdLocalConfigs;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdLocalConfigsBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdParams;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdParamsBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdRemoteConfigs;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdRemoteConfigsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdStatus;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.tunnel.attributes.BfdStatusBuilder;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
59 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
60 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
64 import com.google.common.base.Optional;
66 public class PhysicalSwitchUpdateCommand extends AbstractTransactionCommand {
68 private static final Logger LOG = LoggerFactory.getLogger(PhysicalSwitchUpdateCommand.class);
69 private Map<UUID, PhysicalSwitch> updatedPSRows;
70 private Map<UUID, Tunnel> updatedTunnelRows;
71 private Map<UUID, PhysicalLocator> updatedPLocRows;
73 public PhysicalSwitchUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
74 super(key, updates, dbSchema);
75 updatedPSRows = TyperUtils.extractRowsUpdated(PhysicalSwitch.class, getUpdates(), getDbSchema());
76 updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(), getDbSchema());
77 updatedPLocRows = TyperUtils.extractRowsUpdated(PhysicalLocator.class, getUpdates(), getDbSchema());
81 public void execute(ReadWriteTransaction transaction) {
82 for (PhysicalSwitch physicalSwitch : updatedPSRows.values()) {
83 updatePhysicalSwitch(transaction, physicalSwitch);
87 private void updatePhysicalSwitch(ReadWriteTransaction transaction, PhysicalSwitch pSwitch) {
88 final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
89 Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
90 if (connection.isPresent()) {
91 LOG.debug("Connection {} is present", connection);
92 // Update the connection node to let it know it manages this
94 Node connectionNode = buildConnectionNode(pSwitch);
95 transaction.merge(LogicalDatastoreType.OPERATIONAL, connectionIId, connectionNode);
97 // Update the Physical Switch with whatever data we are getting
98 InstanceIdentifier<Node> psIid = getInstanceIdentifier(pSwitch);
99 Node psNode = buildPhysicalSwitchNode(connection.get(), pSwitch);
100 transaction.merge(LogicalDatastoreType.OPERATIONAL, psIid, psNode);
101 // TODO: Delete entries that are no longer needed
102 // TODO: Deletion of tunnels
103 // TODO: Deletion of Tunnel BFD config and params
107 private Node buildPhysicalSwitchNode(Node node, PhysicalSwitch pSwitch) {
108 NodeBuilder psNodeBuilder = new NodeBuilder();
109 NodeId psNodeId = getNodeId(pSwitch);
110 psNodeBuilder.setNodeId(psNodeId);
111 PhysicalSwitchAugmentationBuilder psAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
112 psAugmentationBuilder.setPhysicalSwitchUuid(new Uuid(pSwitch.getUuid().toString()));
113 setManagedBy(psAugmentationBuilder);
114 setPhysicalSwitchId(psAugmentationBuilder, pSwitch);
115 setManagementIps(psAugmentationBuilder, pSwitch);
116 setTunnelIps(psAugmentationBuilder, pSwitch);
117 setTunnels(node, psAugmentationBuilder, pSwitch);
119 psNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, psAugmentationBuilder.build());
121 LOG.trace("Built with the intent to store PhysicalSwitch data {}", psAugmentationBuilder.build());
122 return psNodeBuilder.build();
125 private void setTunnels(Node node, PhysicalSwitchAugmentationBuilder psAugmentationBuilder,
126 PhysicalSwitch pSwitch) {
127 if (pSwitch.getTunnels() != null && pSwitch.getTunnels().getData() != null
128 && !pSwitch.getTunnels().getData().isEmpty()) {
129 Set<UUID> uuidList = pSwitch.getTunnels().getData();
130 List<Tunnels> tunnelList = new ArrayList<>();
131 TunnelsBuilder tBuilder = new TunnelsBuilder();
132 for (UUID uuid : uuidList) {
133 Tunnel tunnel = updatedTunnelRows.get(uuid);
134 if (tunnel.getLocalColumn().getData() != null) {
135 PhysicalLocator pLoc = updatedPLocRows.get(tunnel.getLocalColumn().getData());
136 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint> tpPath =
137 HwvtepSouthboundMapper.createInstanceIdentifier(
138 HwvtepSouthboundMapper.createInstanceIdentifier(node.getNodeId()), pLoc);
139 tBuilder.setLocalLocatorRef(new HwvtepPhysicalLocatorRef(tpPath));
141 tBuilder.setTunnelUuid(new Uuid(uuid.toString()));
142 setBfdLocalConfigs(tBuilder, tunnel);
143 setBfdRemoteConfigs(tBuilder, tunnel);
144 setBfdParams(tBuilder, tunnel);
145 setBfdStatus(tBuilder, tunnel);
147 if (tunnel.getRemoteColumn().getData() != null) {
148 PhysicalLocator pLoc = updatedPLocRows.get(tunnel.getRemoteColumn().getData());
149 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint> tpPath =
150 HwvtepSouthboundMapper.createInstanceIdentifier(
151 HwvtepSouthboundMapper.createInstanceIdentifier(node.getNodeId()), pLoc);
152 tBuilder.setRemoteLocatorRef(new HwvtepPhysicalLocatorRef(tpPath));
154 tunnelList.add(tBuilder.build());
156 psAugmentationBuilder.setTunnels(tunnelList);
161 private void setBfdLocalConfigs(TunnelsBuilder tBuilder, Tunnel tunnel) {
162 Map<String, String> localConfigs = tunnel.getBfdConfigLocalColumn().getData();
163 if(localConfigs != null && !localConfigs.isEmpty()) {
164 Set<String> localConfigKeys = localConfigs.keySet();
165 List<BfdLocalConfigs> localConfigsList = new ArrayList<>();
166 String localConfigValue = null;
167 for(String localConfigKey: localConfigKeys) {
168 localConfigValue = localConfigs.get(localConfigKey);
169 if(localConfigValue != null && localConfigKey != null) {
170 localConfigsList.add(new BfdLocalConfigsBuilder()
171 .setBfdLocalConfigKey(localConfigKey)
172 .setBfdLocalConfigValue(localConfigValue)
176 tBuilder.setBfdLocalConfigs(localConfigsList);
180 private void setBfdRemoteConfigs(TunnelsBuilder tBuilder, Tunnel tunnel) {
181 Map<String, String> remoteConfigs = tunnel.getBfdConfigRemoteColumn().getData();
182 if(remoteConfigs != null && !remoteConfigs.isEmpty()) {
183 Set<String> remoteConfigKeys = remoteConfigs.keySet();
184 List<BfdRemoteConfigs> remoteConfigsList = new ArrayList<>();
185 String remoteConfigValue = null;
186 for(String remoteConfigKey: remoteConfigKeys) {
187 remoteConfigValue = remoteConfigs.get(remoteConfigKey);
188 if(remoteConfigValue != null && remoteConfigKey != null) {
189 remoteConfigsList.add(new BfdRemoteConfigsBuilder()
190 .setBfdRemoteConfigKey(remoteConfigKey)
191 .setBfdRemoteConfigValue(remoteConfigValue)
195 tBuilder.setBfdRemoteConfigs(remoteConfigsList);
200 private void setBfdParams(TunnelsBuilder tBuilder, Tunnel tunnel) {
201 Map<String, String> params = tunnel.getBfdParamsColumn().getData();
202 if(params != null && !params.isEmpty()) {
203 Set<String> paramKeys = params.keySet();
204 List<BfdParams> paramsList = new ArrayList<>();
205 String paramValue = null;
206 for(String paramKey: paramKeys) {
207 paramValue = params.get(paramKey);
208 if(paramValue != null && paramKey != null) {
209 paramsList.add(new BfdParamsBuilder()
210 .setBfdParamKey(paramKey)
211 .setBfdParamValue(paramValue)
215 tBuilder.setBfdParams(paramsList);
219 private void setBfdStatus(TunnelsBuilder tBuilder, Tunnel tunnel) {
220 Map<String, String> status = tunnel.getBfdStatusColumn().getData();
221 if(status != null && !status.isEmpty()) {
222 Set<String> paramKeys = status.keySet();
223 List<BfdStatus> statusList = new ArrayList<>();
224 String paramValue = null;
225 for(String paramKey: paramKeys) {
226 paramValue = status.get(paramKey);
227 if(paramValue != null && paramKey != null) {
228 statusList.add(new BfdStatusBuilder()
229 .setBfdStatusKey(paramKey)
230 .setBfdStatusValue(paramValue)
234 tBuilder.setBfdStatus(statusList);
238 private void setManagedBy(PhysicalSwitchAugmentationBuilder psAugmentationBuilder) {
239 InstanceIdentifier<Node> connectionNodePath = getOvsdbConnectionInstance().getInstanceIdentifier();
240 psAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(connectionNodePath));
243 private void setPhysicalSwitchId(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
244 if (pSwitch.getName() != null) {
245 psAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(pSwitch.getName()));
247 if (pSwitch.getDescription() != null) {
248 psAugmentationBuilder.setHwvtepNodeDescription(pSwitch.getDescription());
252 private void setManagementIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
253 if (pSwitch.getManagementIpsColumn() != null && pSwitch.getManagementIpsColumn().getData() != null
254 && !pSwitch.getManagementIpsColumn().getData().isEmpty()) {
255 List<ManagementIps> mgmtIps = new ArrayList<>();
256 for (String mgmtIp : pSwitch.getManagementIpsColumn().getData()) {
257 IpAddress ip = new IpAddress(mgmtIp.toCharArray());
259 new ManagementIpsBuilder().setKey(new ManagementIpsKey(ip)).setManagementIpsKey(ip).build());
261 psAugmentationBuilder.setManagementIps(mgmtIps);
265 private void setTunnelIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
266 if (pSwitch.getTunnelIpsColumn() != null && pSwitch.getTunnelIpsColumn().getData() != null
267 && !pSwitch.getTunnelIpsColumn().getData().isEmpty()) {
268 List<TunnelIps> tunnelIps = new ArrayList<>();
269 for (String tunnelIp : pSwitch.getTunnelIpsColumn().getData()) {
270 IpAddress ip = new IpAddress(tunnelIp.toCharArray());
271 tunnelIps.add(new TunnelIpsBuilder().setKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build());
273 psAugmentationBuilder.setTunnelIps(tunnelIps);
277 private Node buildConnectionNode(PhysicalSwitch pSwitch) {
278 // Update node with PhysicalSwitch reference
279 NodeBuilder connectionNode = new NodeBuilder();
280 connectionNode.setNodeId(getOvsdbConnectionInstance().getNodeId());
282 HwvtepGlobalAugmentationBuilder hgAugmentationBuilder = new HwvtepGlobalAugmentationBuilder();
283 List<Switches> switches = new ArrayList<>();
284 InstanceIdentifier<Node> switchIid =
285 HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
286 hgAugmentationBuilder.setSwitches(switches);
287 Switches physicalSwitch = new SwitchesBuilder().setSwitchRef(new HwvtepPhysicalSwitchRef(switchIid)).build();
288 switches.add(physicalSwitch);
290 connectionNode.addAugmentation(HwvtepGlobalAugmentation.class, hgAugmentationBuilder.build());
292 LOG.debug("Update node with physicalswitch ref {}", hgAugmentationBuilder.getSwitches().iterator().next());
293 return connectionNode.build();
296 private InstanceIdentifier<Node> getInstanceIdentifier(PhysicalSwitch pSwitch) {
297 return HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
300 private NodeId getNodeId(PhysicalSwitch pSwitch) {
301 NodeKey nodeKey = getInstanceIdentifier(pSwitch).firstKeyOf(Node.class);
302 return nodeKey.getNodeId();