Add uuid for mac-entries, improved logging
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transactions / md / PhysicalSwitchUpdateCommand.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
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;
63
64 import com.google.common.base.Optional;
65
66 public class PhysicalSwitchUpdateCommand extends AbstractTransactionCommand {
67
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;
72
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());
78     }
79
80     @Override
81     public void execute(ReadWriteTransaction transaction) {
82         for (PhysicalSwitch physicalSwitch : updatedPSRows.values()) {
83             updatePhysicalSwitch(transaction, physicalSwitch);
84         }
85     }
86
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
93             // Physical Switch
94             Node connectionNode = buildConnectionNode(pSwitch);
95             transaction.merge(LogicalDatastoreType.OPERATIONAL, connectionIId, connectionNode);
96
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
104         }
105     }
106
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);
118
119         psNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, psAugmentationBuilder.build());
120
121         LOG.trace("Built with the intent to store PhysicalSwitch data {}", psAugmentationBuilder.build());
122         return psNodeBuilder.build();
123     }
124
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));
140                 }
141                 tBuilder.setTunnelUuid(new Uuid(uuid.toString()));
142                 setBfdLocalConfigs(tBuilder, tunnel);
143                 setBfdRemoteConfigs(tBuilder, tunnel);
144                 setBfdParams(tBuilder, tunnel);
145                 setBfdStatus(tBuilder, tunnel);
146
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));
153                 }
154                 tunnelList.add(tBuilder.build());
155             }
156             psAugmentationBuilder.setTunnels(tunnelList);
157         }
158
159     }
160
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)
173                         .build());
174                 }
175             }
176             tBuilder.setBfdLocalConfigs(localConfigsList);
177         }
178     }
179
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)
192                         .build());
193                 }
194             }
195             tBuilder.setBfdRemoteConfigs(remoteConfigsList);
196         }
197     }
198
199
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)
212                         .build());
213                 }
214             }
215             tBuilder.setBfdParams(paramsList);
216         }
217     }
218
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)
231                         .build());
232                 }
233             }
234             tBuilder.setBfdStatus(statusList);
235         }
236     }
237
238     private void setManagedBy(PhysicalSwitchAugmentationBuilder psAugmentationBuilder) {
239         InstanceIdentifier<Node> connectionNodePath = getOvsdbConnectionInstance().getInstanceIdentifier();
240         psAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(connectionNodePath));
241     }
242
243     private void setPhysicalSwitchId(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
244         if (pSwitch.getName() != null) {
245             psAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(pSwitch.getName()));
246         }
247         if (pSwitch.getDescription() != null) {
248             psAugmentationBuilder.setHwvtepNodeDescription(pSwitch.getDescription());
249         }
250     }
251
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());
258                 mgmtIps.add(
259                         new ManagementIpsBuilder().setKey(new ManagementIpsKey(ip)).setManagementIpsKey(ip).build());
260             }
261             psAugmentationBuilder.setManagementIps(mgmtIps);
262         }
263     }
264
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());
272             }
273             psAugmentationBuilder.setTunnelIps(tunnelIps);
274         }
275     }
276
277     private Node buildConnectionNode(PhysicalSwitch pSwitch) {
278         // Update node with PhysicalSwitch reference
279         NodeBuilder connectionNode = new NodeBuilder();
280         connectionNode.setNodeId(getOvsdbConnectionInstance().getNodeId());
281
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);
289
290         connectionNode.addAugmentation(HwvtepGlobalAugmentation.class, hgAugmentationBuilder.build());
291
292         LOG.debug("Update node with physicalswitch ref {}", hgAugmentationBuilder.getSwitches().iterator().next());
293         return connectionNode.build();
294     }
295
296     private InstanceIdentifier<Node> getInstanceIdentifier(PhysicalSwitch pSwitch) {
297         return HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
298     }
299
300     private NodeId getNodeId(PhysicalSwitch pSwitch) {
301         NodeKey nodeKey = getInstanceIdentifier(pSwitch).firstKeyOf(Node.class);
302         return nodeKey.getNodeId();
303     }
304 }