2 * Copyright (c) 2015 - 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
9 package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
11 import java.util.ArrayList;
12 import java.util.List;
15 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
18 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
19 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
20 import org.opendaylight.ovsdb.lib.message.TableUpdates;
21 import org.opendaylight.ovsdb.lib.notation.UUID;
22 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
23 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
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.inet.types.rev130715.IpAddress;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchRef;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.SwitchesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIps;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.SwitchFaultStatus;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.SwitchFaultStatusBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.SwitchFaultStatusKey;
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.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
50 import org.opendaylight.yangtools.yang.binding.DataObject;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 import com.google.common.base.Optional;
56 import com.google.common.base.Preconditions;
58 public class HwvtepPhysicalSwitchUpdateCommand extends AbstractTransactionCommand {
60 private static final Logger LOG = LoggerFactory.getLogger(HwvtepPhysicalSwitchUpdateCommand.class);
61 private Map<UUID, PhysicalSwitch> updatedPSRows;
62 private Map<UUID, Tunnel> updatedTunnelRows;
63 private Map<UUID, PhysicalSwitch> oldPSRows;
65 public HwvtepPhysicalSwitchUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
66 super(key, updates, dbSchema);
67 updatedPSRows = TyperUtils.extractRowsUpdated(PhysicalSwitch.class, getUpdates(), getDbSchema());
68 oldPSRows = TyperUtils.extractRowsOld(PhysicalSwitch.class, getUpdates(), getDbSchema());
70 updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(), getDbSchema());
71 } catch (IllegalArgumentException e) {
72 LOG.debug("Tunnel Table not supported on this HWVTEP device", e.getMessage());
77 public void execute(ReadWriteTransaction transaction) {
78 for (PhysicalSwitch physicalSwitch : updatedPSRows.values()) {
79 updatePhysicalSwitch(transaction, physicalSwitch);
83 private void updatePhysicalSwitch(ReadWriteTransaction transaction, PhysicalSwitch pSwitch) {
84 final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
85 Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
86 if (connection.isPresent()) {
87 LOG.debug("Connection {} is present", connection);
88 // Update the connection node to let it know it manages this
90 Node connectionNode = buildConnectionNode(pSwitch);
91 transaction.merge(LogicalDatastoreType.OPERATIONAL, connectionIId, connectionNode);
93 // Update the Physical Switch with whatever data we are getting
94 InstanceIdentifier<Node> psIid = getInstanceIdentifier(pSwitch);
95 Node psNode = buildPhysicalSwitchNode(connection.get(), pSwitch);
96 transaction.merge(LogicalDatastoreType.OPERATIONAL, psIid, psNode);
97 getOvsdbConnectionInstance().getDeviceInfo().putPhysicalSwitch(pSwitch.getUuid(), pSwitch);
98 // TODO: Delete entries that are no longer needed
99 // TODO: Deletion of tunnels
100 // TODO: Deletion of Tunnel BFD config and params
101 //Deleting old switch fault status entries
102 deleteEntries(transaction, getSwitchFaultStatusToRemove(psIid,pSwitch));
106 private Node buildPhysicalSwitchNode(Node node, PhysicalSwitch pSwitch) {
107 NodeBuilder psNodeBuilder = new NodeBuilder();
108 NodeId psNodeId = getNodeId(pSwitch);
109 psNodeBuilder.setNodeId(psNodeId);
110 PhysicalSwitchAugmentationBuilder psAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
111 psAugmentationBuilder.setPhysicalSwitchUuid(new Uuid(pSwitch.getUuid().toString()));
112 setManagedBy(psAugmentationBuilder);
113 setPhysicalSwitchId(psAugmentationBuilder, pSwitch);
114 setManagementIps(psAugmentationBuilder, pSwitch);
115 setTunnelIps(psAugmentationBuilder, pSwitch);
116 setTunnels(psAugmentationBuilder, pSwitch);
117 setSwitchFaultStatus(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(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
126 if (updatedTunnelRows != null && pSwitch.getTunnels() != null && pSwitch.getTunnels().getData() != null
127 && !pSwitch.getTunnels().getData().isEmpty()) {
128 // Nothing to do but update deviceInfo cache
129 for(UUID uuid: pSwitch.getTunnels().getData()) {
130 getOvsdbConnectionInstance().getDeviceInfo().putPhysicalSwitchForTunnel(uuid, pSwitch.getUuid());
135 private void setManagedBy(PhysicalSwitchAugmentationBuilder psAugmentationBuilder) {
136 InstanceIdentifier<Node> connectionNodePath = getOvsdbConnectionInstance().getInstanceIdentifier();
137 psAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(connectionNodePath));
140 private void setPhysicalSwitchId(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
141 if (pSwitch.getName() != null) {
142 psAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(pSwitch.getName()));
144 if (pSwitch.getDescription() != null) {
145 psAugmentationBuilder.setHwvtepNodeDescription(pSwitch.getDescription());
149 private void setManagementIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
150 if (pSwitch.getManagementIpsColumn() != null && pSwitch.getManagementIpsColumn().getData() != null
151 && !pSwitch.getManagementIpsColumn().getData().isEmpty()) {
152 List<ManagementIps> mgmtIps = new ArrayList<>();
153 for (String mgmtIp : pSwitch.getManagementIpsColumn().getData()) {
154 IpAddress ip = new IpAddress(mgmtIp.toCharArray());
156 new ManagementIpsBuilder().setKey(new ManagementIpsKey(ip)).setManagementIpsKey(ip).build());
158 psAugmentationBuilder.setManagementIps(mgmtIps);
162 private void setTunnelIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
163 if (pSwitch.getTunnelIpsColumn() != null && pSwitch.getTunnelIpsColumn().getData() != null
164 && !pSwitch.getTunnelIpsColumn().getData().isEmpty()) {
165 List<TunnelIps> tunnelIps = new ArrayList<>();
166 for (String tunnelIp : pSwitch.getTunnelIpsColumn().getData()) {
167 IpAddress ip = new IpAddress(tunnelIp.toCharArray());
168 tunnelIps.add(new TunnelIpsBuilder().setKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build());
170 psAugmentationBuilder.setTunnelIps(tunnelIps);
174 private Node buildConnectionNode(PhysicalSwitch pSwitch) {
175 // Update node with PhysicalSwitch reference
176 NodeBuilder connectionNode = new NodeBuilder();
177 connectionNode.setNodeId(getOvsdbConnectionInstance().getNodeId());
179 HwvtepGlobalAugmentationBuilder hgAugmentationBuilder = new HwvtepGlobalAugmentationBuilder();
180 List<Switches> switches = new ArrayList<>();
181 InstanceIdentifier<Node> switchIid =
182 HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
183 hgAugmentationBuilder.setSwitches(switches);
184 Switches physicalSwitch = new SwitchesBuilder().setSwitchRef(new HwvtepPhysicalSwitchRef(switchIid)).build();
185 switches.add(physicalSwitch);
187 connectionNode.addAugmentation(HwvtepGlobalAugmentation.class, hgAugmentationBuilder.build());
189 LOG.debug("Update node with physicalswitch ref {}", hgAugmentationBuilder.getSwitches().iterator().next());
190 return connectionNode.build();
193 private InstanceIdentifier<Node> getInstanceIdentifier(PhysicalSwitch pSwitch) {
194 return HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
197 private NodeId getNodeId(PhysicalSwitch pSwitch) {
198 NodeKey nodeKey = getInstanceIdentifier(pSwitch).firstKeyOf(Node.class);
199 return nodeKey.getNodeId();
202 private <T extends DataObject> void deleteEntries(ReadWriteTransaction transaction,
203 List<InstanceIdentifier<T>> entryIids) {
204 for (InstanceIdentifier<T> entryIid : entryIids) {
205 transaction.delete(LogicalDatastoreType.OPERATIONAL, entryIid);
209 private List<InstanceIdentifier<SwitchFaultStatus>> getSwitchFaultStatusToRemove(InstanceIdentifier<Node> psIid,
210 PhysicalSwitch pSwitch) {
211 Preconditions.checkNotNull(psIid);
212 Preconditions.checkNotNull(pSwitch);
213 List<InstanceIdentifier<SwitchFaultStatus>> result = new ArrayList<>();
214 PhysicalSwitch oldSwitch = oldPSRows.get(pSwitch.getUuid());
215 if (oldSwitch != null && oldSwitch.getSwitchFaultStatusColumn() != null) {
216 for (String switchFltStat : oldSwitch.getSwitchFaultStatusColumn().getData()) {
217 if (pSwitch.getSwitchFaultStatusColumn() == null
218 || !pSwitch.getSwitchFaultStatusColumn().getData().contains(switchFltStat)) {
219 InstanceIdentifier<SwitchFaultStatus> iid = psIid.augmentation(PhysicalSwitchAugmentation.class)
220 .child(SwitchFaultStatus.class, new SwitchFaultStatusKey(switchFltStat));
228 private void setSwitchFaultStatus(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
229 if (pSwitch.getSwitchFaultStatusColumn() != null && pSwitch.getSwitchFaultStatusColumn().getData() != null
230 && !pSwitch.getSwitchFaultStatusColumn().getData().isEmpty()) {
231 List<SwitchFaultStatus> switchFaultStatusLst = new ArrayList<>();
232 for (String switchFaultStatus : pSwitch.getSwitchFaultStatusColumn().getData()) {
234 .add(new SwitchFaultStatusBuilder().setKey(new SwitchFaultStatusKey(switchFaultStatus))
235 .setSwitchFaultStatusKey(switchFaultStatus).build());
237 psAugmentationBuilder.setSwitchFaultStatus(switchFaultStatusLst);