Migrate to Objects.requireNonNull()
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transactions / md / HwvtepTunnelUpdateCommand.java
1 /*
2  * Copyright (c) 2016 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 package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.util.List;
13 import java.util.Map;
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;
45
46 public class HwvtepTunnelUpdateCommand extends AbstractTransactionCommand {
47
48     private static final Logger LOG = LoggerFactory.getLogger(HwvtepTunnelUpdateCommand.class);
49     private Map<UUID, Tunnel> updatedTunnelRows;
50
51     public HwvtepTunnelUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
52         super(key, updates, dbSchema);
53         try {
54             updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(), getDbSchema());
55         } catch (IllegalArgumentException e) {
56             LOG.debug("Tunnel Table not supported on this HWVTEP device", e);
57         }
58     }
59
60     @Override
61     @SuppressWarnings("checkstyle:IllegalCatch")
62     public void execute(ReadWriteTransaction transaction) {
63         if (updatedTunnelRows != null && !updatedTunnelRows.isEmpty()) {
64             for (Tunnel tunnel : updatedTunnelRows.values()) {
65                 try {
66                     updateTunnel(transaction, tunnel);
67                 } catch (RuntimeException e) {
68                     LOG.warn("Exception updating tunnel {}", tunnel, e);
69                 }
70             }
71         }
72     }
73
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());
82
83         InstanceIdentifier<Tunnels> tunnelIid = null;
84         if (phySwitch != null) {
85             InstanceIdentifier<Node> psIid =
86                     HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), phySwitch);
87             tunnelIid = getInstanceIdentifier(psIid, tunnel);
88         }
89
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
105         } else {
106             LOG.warn("Insuficient information. Unable to update tunnel {}", tunnel.getUuid());
107         }
108     }
109
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());
116
117             tunnelsBuilder.setBfdLocalConfigs(localConfigsList);
118         }
119     }
120
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());
127
128             tunnelsBuilder.setBfdRemoteConfigs(remoteConfigsList);
129         }
130     }
131
132
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());
139
140             tunnelsBuilder.setBfdParams(paramsList);
141         }
142     }
143
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());
150
151             tunnelsBuilder.setBfdStatus(statusList);
152         }
153     }
154
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);
165         }
166         return result;
167     }
168
169     private InstanceIdentifier<TerminationPoint> getPhysicalLocatorRefFromUUID(InstanceIdentifier<Node> nodeIid,
170                                                                                UUID uuid) {
171         PhysicalLocator locator = getOvsdbConnectionInstance().getDeviceInfo().getPhysicalLocator(uuid);
172         if (locator == null) {
173             LOG.trace("Available PhysicalLocators: {}",
174                             getOvsdbConnectionInstance().getDeviceInfo().getPhysicalLocators());
175             return null;
176         }
177         return HwvtepSouthboundMapper.createInstanceIdentifier(nodeIid, locator);
178     }
179 }