Merge "Bug 5876 - OVSDB library: Retry when SSL handshake doesn't begin yet"
[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
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.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 import com.google.common.base.Optional;
47 import com.google.common.base.Preconditions;
48
49 public class HwvtepTunnelUpdateCommand extends AbstractTransactionCommand {
50
51     private static final Logger LOG = LoggerFactory.getLogger(HwvtepTunnelUpdateCommand.class);
52     private Map<UUID, Tunnel> updatedTunnelRows;
53
54     public HwvtepTunnelUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
55         super(key, updates, dbSchema);
56         try {
57             updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(), getDbSchema());
58         } catch (IllegalArgumentException e) {
59             LOG.debug("Tunnel Table not supported on this HWVTEP device", e.getMessage());
60         }
61     }
62
63     @Override
64     public void execute(ReadWriteTransaction transaction) {
65         if(updatedTunnelRows != null && !updatedTunnelRows.isEmpty()) {
66             for (Tunnel tunnel : updatedTunnelRows.values()) {
67                 try {
68                     updateTunnel(transaction, tunnel);
69                 } catch (Exception e) {
70                     LOG.warn("Exception updating tunnel {}", tunnel, e);
71                 }
72             }
73         }
74     }
75
76     private void updateTunnel(ReadWriteTransaction transaction, Tunnel tunnel) {
77         Preconditions.checkNotNull(tunnel.getLocalColumn().getData());
78         Preconditions.checkNotNull(tunnel.getRemoteColumn().getData());
79         final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
80         Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
81         PhysicalSwitch pSwitch =
82                         getOvsdbConnectionInstance().getDeviceInfo().getPhysicalSwitchForTunnel(tunnel.getUuid());
83         InstanceIdentifier<Node> psIid =
84                         HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
85         InstanceIdentifier<Tunnels> tunnelIid = getInstanceIdentifier(psIid, tunnel);
86         if (connection.isPresent() && pSwitch != null && tunnelIid != null) {
87             TunnelsBuilder tBuilder = new TunnelsBuilder();
88             tBuilder.setLocalLocatorRef(new HwvtepPhysicalLocatorRef(getPhysicalLocatorRefFromUUID(
89                     getOvsdbConnectionInstance().getInstanceIdentifier(), (tunnel.getLocalColumn().getData()))));
90             tBuilder.setRemoteLocatorRef(new HwvtepPhysicalLocatorRef(getPhysicalLocatorRefFromUUID(
91                     getOvsdbConnectionInstance().getInstanceIdentifier(), (tunnel.getRemoteColumn().getData()))));
92             tBuilder.setTunnelUuid(new Uuid(tunnel.getUuid().toString()));
93             setBfdLocalConfigs(tBuilder, tunnel);
94             setBfdRemoteConfigs(tBuilder, tunnel);
95             setBfdParams(tBuilder, tunnel);
96             setBfdStatus(tBuilder, tunnel);
97             Tunnels updatedTunnel = tBuilder.build();
98             LOG.trace("Built with the intent to store tunnel data {}", updatedTunnel);
99             transaction.merge(LogicalDatastoreType.OPERATIONAL, tunnelIid, updatedTunnel);
100             // TODO: Deletion of Tunnel BFD config and params
101         } else {
102             LOG.warn("Insuficient information. Unable to update tunnel {}", tunnel.getUuid());
103         }
104     }
105
106     private void setBfdLocalConfigs(TunnelsBuilder tBuilder, Tunnel tunnel) {
107         Map<String, String> localConfigs = tunnel.getBfdConfigLocalColumn().getData();
108         if(localConfigs != null && !localConfigs.isEmpty()) {
109             Set<String> localConfigKeys = localConfigs.keySet();
110             List<BfdLocalConfigs> localConfigsList = new ArrayList<>();
111             String localConfigValue = null;
112             for(String localConfigKey: localConfigKeys) {
113                 localConfigValue = localConfigs.get(localConfigKey);
114                 if(localConfigValue != null && localConfigKey != null) {
115                     localConfigsList.add(new BfdLocalConfigsBuilder()
116                         .setBfdLocalConfigKey(localConfigKey)
117                         .setBfdLocalConfigValue(localConfigValue)
118                         .build());
119                 }
120             }
121             tBuilder.setBfdLocalConfigs(localConfigsList);
122         }
123     }
124
125     private void setBfdRemoteConfigs(TunnelsBuilder tBuilder, Tunnel tunnel) {
126         Map<String, String> remoteConfigs = tunnel.getBfdConfigRemoteColumn().getData();
127         if(remoteConfigs != null && !remoteConfigs.isEmpty()) {
128             Set<String> remoteConfigKeys = remoteConfigs.keySet();
129             List<BfdRemoteConfigs> remoteConfigsList = new ArrayList<>();
130             String remoteConfigValue = null;
131             for(String remoteConfigKey: remoteConfigKeys) {
132                 remoteConfigValue = remoteConfigs.get(remoteConfigKey);
133                 if(remoteConfigValue != null && remoteConfigKey != null) {
134                     remoteConfigsList.add(new BfdRemoteConfigsBuilder()
135                         .setBfdRemoteConfigKey(remoteConfigKey)
136                         .setBfdRemoteConfigValue(remoteConfigValue)
137                         .build());
138                 }
139             }
140             tBuilder.setBfdRemoteConfigs(remoteConfigsList);
141         }
142     }
143
144
145     private void setBfdParams(TunnelsBuilder tBuilder, Tunnel tunnel) {
146         Map<String, String> params = tunnel.getBfdParamsColumn().getData();
147         if(params != null && !params.isEmpty()) {
148             Set<String> paramKeys = params.keySet();
149             List<BfdParams> paramsList = new ArrayList<>();
150             String paramValue = null;
151             for(String paramKey: paramKeys) {
152                 paramValue = params.get(paramKey);
153                 if(paramValue != null && paramKey != null) {
154                     paramsList.add(new BfdParamsBuilder()
155                         .setBfdParamKey(paramKey)
156                         .setBfdParamValue(paramValue)
157                         .build());
158                 }
159             }
160             tBuilder.setBfdParams(paramsList);
161         }
162     }
163
164     private void setBfdStatus(TunnelsBuilder tBuilder, Tunnel tunnel) {
165         Map<String, String> status = tunnel.getBfdStatusColumn().getData();
166         if(status != null && !status.isEmpty()) {
167             Set<String> paramKeys = status.keySet();
168             List<BfdStatus> statusList = new ArrayList<>();
169             String paramValue = null;
170             for(String paramKey: paramKeys) {
171                 paramValue = status.get(paramKey);
172                 if(paramValue != null && paramKey != null) {
173                     statusList.add(new BfdStatusBuilder()
174                         .setBfdStatusKey(paramKey)
175                         .setBfdStatusValue(paramValue)
176                         .build());
177                 }
178             }
179             tBuilder.setBfdStatus(statusList);
180         }
181     }
182
183     private InstanceIdentifier<Tunnels> getInstanceIdentifier(InstanceIdentifier<Node> psIid, Tunnel tunnel) {
184         InstanceIdentifier<Tunnels> result = null;
185         InstanceIdentifier<TerminationPoint> localTpPath =
186                         getPhysicalLocatorRefFromUUID(getOvsdbConnectionInstance().getInstanceIdentifier(),
187                                                         (tunnel.getLocalColumn().getData()));
188         InstanceIdentifier<TerminationPoint> remoteTpPath =
189                         getPhysicalLocatorRefFromUUID(getOvsdbConnectionInstance().getInstanceIdentifier(),
190                                                         (tunnel.getRemoteColumn().getData()));
191         if(remoteTpPath != null && localTpPath != null ) {
192             result = HwvtepSouthboundMapper.createInstanceIdentifier(psIid, localTpPath, remoteTpPath);
193         }
194         return result;
195     }
196
197     private InstanceIdentifier<TerminationPoint> getPhysicalLocatorRefFromUUID(InstanceIdentifier<Node> nodeIid,
198                                                                                UUID uuid) {
199         PhysicalLocator pLoc = getOvsdbConnectionInstance().getDeviceInfo().getPhysicalLocator(uuid);
200         if(pLoc == null) {
201             LOG.trace("Available PhysicalLocators: ",
202                             getOvsdbConnectionInstance().getDeviceInfo().getPhysicalLocators());
203             return null;
204         }
205         return HwvtepSouthboundMapper.createInstanceIdentifier(nodeIid, pLoc);
206     }
207
208 }