2 * Copyright (c) 2015, 2017 China Telecom Beijing Research Institute 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.transact;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.collect.Maps;
14 import org.apache.commons.lang3.tuple.Pair;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
17 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
18 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
19 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
20 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
21 import org.opendaylight.ovsdb.lib.notation.UUID;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeBase;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacs;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacsKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacsKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacsKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.Tunnels;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelsKey;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
44 import org.opendaylight.yangtools.yang.binding.Identifiable;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 import java.util.Collection;
50 import java.util.Collections;
51 import java.util.HashMap;
52 import java.util.List;
54 import java.util.Map.Entry;
56 import java.util.concurrent.ConcurrentHashMap;
58 //TODO: need to be optimized, get entry by iid not name
59 public class HwvtepOperationalState {
61 private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperationalState.class);
63 private Map<InstanceIdentifier<Node>, Node> operationalNodes = new HashMap<>();
64 private ReadWriteTransaction transaction;
65 HashMap<InstanceIdentifier<TerminationPoint>, UUID> inflightLocators = Maps.newHashMap();
66 private HwvtepDeviceInfo deviceInfo;
67 private HwvtepConnectionInstance connectionInstance;
68 private Map<Class<? extends Identifiable>, Map<InstanceIdentifier, UUID>> currentTxUUIDs = new ConcurrentHashMap<>();
69 private Map<Class<? extends Identifiable>, Map<InstanceIdentifier, Boolean>> currentTxDeletedKeys = new ConcurrentHashMap<>();
71 /* stores the modified and deleted data for each child type of each node id
72 Map<nodeid , Pair < updated, deleted >
73 each updated/ deleted contains Map < child type, List<ChildData>>
74 child type is the child of hwvtep Global augmentation
76 private Map<InstanceIdentifier<Node>,
77 Pair<Map<Class<? extends Identifiable>, List<Identifiable>>,
78 Map<Class<? extends Identifiable>, List<Identifiable>>>> modifiedData = new HashMap<>();
79 private boolean inReconciliation = false;
81 public HwvtepOperationalState(DataBroker db, HwvtepConnectionInstance connectionInstance,
82 Collection<DataTreeModification<Node>> changes) {
83 this.connectionInstance = connectionInstance;
84 this.deviceInfo = connectionInstance.getDeviceInfo();
85 Map<InstanceIdentifier<Node>, Node> nodeCreateOrUpdate =
86 TransactUtils.extractCreatedOrUpdatedOrRemoved(changes, Node.class);
87 if (nodeCreateOrUpdate != null) {
88 transaction = db.newReadWriteTransaction();
89 for (Entry<InstanceIdentifier<Node>, Node> entry: nodeCreateOrUpdate.entrySet()) {
90 Optional<Node> readNode = HwvtepSouthboundUtil.readNode(transaction, entry.getKey());
91 //add related globalNode or physicalSwitchNode to operationalNodes map
92 //for example, when creating physical port, logical switch is needed
93 //but logical switch is in HwvtepGlobalAugmentation rather than PhysicalSwitchAugmentation
94 if (readNode.isPresent()) {
95 operationalNodes.put(entry.getKey(), readNode.get());
96 HwvtepGlobalAugmentation hgAugmentation = readNode.get().getAugmentation(HwvtepGlobalAugmentation.class);
97 PhysicalSwitchAugmentation psAugmentation = readNode.get().getAugmentation(PhysicalSwitchAugmentation.class);
98 if (hgAugmentation != null && hgAugmentation.getSwitches() != null) {
99 for (Switches pswitch : hgAugmentation.getSwitches()) {
100 @SuppressWarnings("unchecked")
101 InstanceIdentifier<Node> psNodeIid = (InstanceIdentifier<Node>) pswitch.getSwitchRef().getValue();
102 Optional<Node> psNode = HwvtepSouthboundUtil.readNode(transaction, psNodeIid);
103 if (psNode.isPresent()) {
104 operationalNodes.put(psNodeIid, psNode.get());
108 if (psAugmentation != null) {
109 @SuppressWarnings("unchecked")
110 InstanceIdentifier<Node> hgNodeIid = (InstanceIdentifier<Node>) psAugmentation.getManagedBy().getValue();
111 Optional<Node> hgNode = HwvtepSouthboundUtil.readNode(transaction, hgNodeIid);
112 if (hgNode.isPresent()) {
113 operationalNodes.put(hgNodeIid, hgNode.get());
121 public HwvtepOperationalState(HwvtepConnectionInstance connectionInstance) {
122 this.connectionInstance = connectionInstance;
123 this.deviceInfo = connectionInstance.getDeviceInfo();
124 transaction = connectionInstance.getDataBroker().newReadWriteTransaction();
125 Optional<Node> readNode = HwvtepSouthboundUtil.readNode(transaction, connectionInstance.getInstanceIdentifier());
126 if (readNode.isPresent()) {
127 operationalNodes.put(connectionInstance.getInstanceIdentifier(), readNode.get());
131 public Optional<Node> getGlobalNode(InstanceIdentifier<?> iid) {
132 InstanceIdentifier<Node> nodeIid = iid.firstIdentifierOf(Node.class);
133 return Optional.fromNullable(operationalNodes.get(nodeIid));
136 public Optional<HwvtepGlobalAugmentation> getHwvtepGlobalAugmentation(InstanceIdentifier<?> iid) {
137 Preconditions.checkNotNull(iid);
138 Optional<Node> nodeOptional = getGlobalNode(iid);
139 if (nodeOptional.isPresent()) {
140 return Optional.fromNullable(nodeOptional.get().getAugmentation(HwvtepGlobalAugmentation.class));
142 return Optional.absent();
145 public Optional<PhysicalSwitchAugmentation> getPhysicalSwitchAugmentation(InstanceIdentifier<?> iid) {
146 Preconditions.checkNotNull(iid);
147 Optional<Node> nodeOptional = getGlobalNode(iid);
148 if (nodeOptional.isPresent()) {
149 return Optional.fromNullable(nodeOptional.get().getAugmentation(PhysicalSwitchAugmentation.class));
151 return Optional.absent();
154 public Optional<List<TerminationPoint>> getTerminationPointList(InstanceIdentifier<?> iid) {
155 Preconditions.checkNotNull(iid);
156 Optional<Node> nodeOptional = getGlobalNode(iid);
157 if (nodeOptional.isPresent() && nodeOptional.get().getTerminationPoint() != null) {
158 return Optional.fromNullable(nodeOptional.get().getTerminationPoint());
160 return Optional.absent();
163 public Optional<LogicalSwitches> getLogicalSwitches(InstanceIdentifier<?> iid, LogicalSwitchesKey logicalSwitchesKey) {
164 Preconditions.checkNotNull(iid);
165 Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
166 if (nodeOptional.isPresent()) {
167 HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
168 List<LogicalSwitches> lswitchList = null;
169 if (hgAugmentation != null) {
170 lswitchList = hgAugmentation.getLogicalSwitches();
172 if (lswitchList != null) {
173 for (LogicalSwitches lswitch: lswitchList) {
174 if (lswitch.getKey().equals(logicalSwitchesKey)) {
175 return Optional.fromNullable(lswitch);
180 return Optional.absent();
183 public Optional<Tunnels> getTunnels(InstanceIdentifier<?> iid, TunnelsKey tunnelsKey) {
184 Preconditions.checkNotNull(iid);
185 Optional<PhysicalSwitchAugmentation> psOptional = getPhysicalSwitchAugmentation(iid);
186 if (psOptional.isPresent()) {
187 PhysicalSwitchAugmentation psAugmentation = psOptional.get();
188 List<Tunnels> tunnelList = null;
189 if (psAugmentation != null) {
190 tunnelList = psAugmentation.getTunnels();
192 if (tunnelList != null) {
193 for (Tunnels tunnel: tunnelList) {
194 if (tunnel.getKey().equals(tunnelsKey)) {
195 return Optional.fromNullable(tunnel);
200 return Optional.absent();
203 public Optional<HwvtepPhysicalPortAugmentation> getPhysicalPortAugmentation(InstanceIdentifier<?> iid,
204 HwvtepNodeName hwvtepNodeName) {
205 Preconditions.checkNotNull(iid);
206 Optional<List<TerminationPoint>> nodeOptional = getTerminationPointList(iid);
207 if (nodeOptional.isPresent()) {
208 List<TerminationPoint> tpList = nodeOptional.get();
209 for (TerminationPoint tp : tpList) {
210 HwvtepPhysicalPortAugmentation hppAugmentation = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
211 if (hppAugmentation != null && hppAugmentation.getHwvtepNodeName().equals(hwvtepNodeName)) {
212 return Optional.fromNullable(hppAugmentation);
216 return Optional.absent();
219 public Optional<HwvtepPhysicalLocatorAugmentation> getPhysicalLocatorAugmentation(InstanceIdentifier<?> iid,
220 IpAddress dstIp, Class<? extends EncapsulationTypeBase> encapType) {
221 Preconditions.checkNotNull(iid);
222 Optional<List<TerminationPoint>> nodeOptional = getTerminationPointList(iid);
223 if (nodeOptional.isPresent()) {
224 List<TerminationPoint> tpList = nodeOptional.get();
225 for (TerminationPoint tp : tpList) {
226 HwvtepPhysicalLocatorAugmentation hppAugmentation = tp.getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
227 if (hppAugmentation != null && hppAugmentation.getDstIp().equals(dstIp)
228 && hppAugmentation.getEncapsulationType().equals(encapType)) {
229 return Optional.fromNullable(hppAugmentation);
233 return Optional.absent();
236 public Optional<LocalMcastMacs> getLocalMcastMacs(InstanceIdentifier<?> iid, LocalMcastMacsKey key) {
237 Preconditions.checkNotNull(iid);
238 Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
239 if (nodeOptional.isPresent()) {
240 HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
241 List<LocalMcastMacs> macList = null;
242 if (hgAugmentation != null) {
243 macList = hgAugmentation.getLocalMcastMacs();
245 if (macList != null) {
246 for (LocalMcastMacs mac: macList) {
247 if (mac.getKey().equals(key)) {
248 return Optional.fromNullable(mac);
253 return Optional.absent();
256 public Optional<RemoteMcastMacs> getRemoteMcastMacs(InstanceIdentifier<?> iid, RemoteMcastMacsKey key) {
257 Preconditions.checkNotNull(iid);
258 Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
259 if (nodeOptional.isPresent()) {
260 HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
261 List<RemoteMcastMacs> macList = null;
262 if (hgAugmentation != null) {
263 macList = hgAugmentation.getRemoteMcastMacs();
265 if (macList != null) {
266 for (RemoteMcastMacs mac: macList) {
267 if (mac.getKey().equals(key)) {
268 return Optional.fromNullable(mac);
273 return Optional.absent();
276 public Optional<LocalUcastMacs> getLocalUcastMacs(InstanceIdentifier<?> iid, LocalUcastMacsKey key) {
277 Preconditions.checkNotNull(iid);
278 Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
279 if (nodeOptional.isPresent()) {
280 HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
281 List<LocalUcastMacs> macList = null;
282 if (hgAugmentation != null) {
283 macList = hgAugmentation.getLocalUcastMacs();
285 if (macList != null) {
286 for (LocalUcastMacs mac: macList) {
287 if (mac.getKey().equals(key)) {
288 return Optional.fromNullable(mac);
293 return Optional.absent();
296 public Optional<RemoteUcastMacs> getRemoteUcastMacs(InstanceIdentifier<?> iid, RemoteUcastMacsKey key) {
297 Preconditions.checkNotNull(iid);
298 Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
299 if (nodeOptional.isPresent()) {
300 HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
301 List<RemoteUcastMacs> macList = null;
302 if (hgAugmentation != null) {
303 macList = hgAugmentation.getRemoteUcastMacs();
305 if (macList != null) {
306 for (RemoteUcastMacs mac: macList) {
307 if (mac.getKey().equals(key)) {
308 return Optional.fromNullable(mac);
313 return Optional.absent();
316 public Optional<HwvtepPhysicalLocatorAugmentation> getPhysicalLocatorAugmentation(InstanceIdentifier<TerminationPoint> iid) {
317 Optional<TerminationPoint> tp = HwvtepSouthboundUtil.readNode(transaction, iid);
318 if (tp.isPresent()) {
319 return Optional.fromNullable(tp.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class));
321 return Optional.absent();
324 public Optional<LogicalSwitches> getLogicalSwitches(InstanceIdentifier<LogicalSwitches> iid) {
325 Optional<LogicalSwitches> lswitch = HwvtepSouthboundUtil.readNode(transaction, iid);
329 public Optional<Tunnels> getTunnels(InstanceIdentifier<Tunnels> iid) {
330 Optional<Tunnels> tunnels = HwvtepSouthboundUtil.readNode(transaction, iid);
334 public ReadWriteTransaction getReadWriteTransaction() {
338 public void setPhysicalLocatorInFlight(InstanceIdentifier<TerminationPoint> iid,
340 inflightLocators.put(iid, uuid);
343 public UUID getPhysicalLocatorInFlight(InstanceIdentifier<TerminationPoint> iid) {
344 return inflightLocators.get(iid);
347 public HwvtepConnectionInstance getConnectionInstance() {
348 return connectionInstance;
351 public HwvtepDeviceInfo getDeviceInfo() {
355 public void updateCurrentTxData(Class<? extends Identifiable> cls, InstanceIdentifier key, UUID uuid) {
356 HwvtepSouthboundUtil.updateData(currentTxUUIDs, cls, key, uuid);
359 public void updateCurrentTxDeleteData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
360 HwvtepSouthboundUtil.updateData(currentTxDeletedKeys, cls, key, Boolean.TRUE);
363 public UUID getUUIDFromCurrentTx(Class<? extends Identifiable> cls, InstanceIdentifier key) {
364 return HwvtepSouthboundUtil.getData(currentTxUUIDs, cls, key);
367 public boolean isKeyPartOfCurrentTx(Class<? extends Identifiable> cls, InstanceIdentifier key) {
368 return HwvtepSouthboundUtil.containsKey(currentTxUUIDs, cls, key);
371 public Set<InstanceIdentifier> getDeletedKeysInCurrentTx(Class<? extends Identifiable> cls) {
372 if (currentTxDeletedKeys.containsKey(cls)) {
373 return currentTxDeletedKeys.get(cls).keySet();
375 return Collections.EMPTY_SET;
378 public List<? extends Identifiable> getUpdatedData(final InstanceIdentifier<Node> key,
379 final Class<? extends Identifiable> cls) {
380 List<Identifiable> result = null;
381 if (modifiedData.get(key) != null && modifiedData.get(key).getLeft() != null) {
382 result = modifiedData.get(key).getLeft().get(cls);
384 if (result == null) {
385 result = Collections.EMPTY_LIST;
390 public List<? extends Identifiable> getDeletedData(final InstanceIdentifier<Node> key,
391 final Class<? extends Identifiable> cls) {
392 List<Identifiable> result = null;
393 if (modifiedData.get(key) != null && modifiedData.get(key).getRight() != null) {
394 result = modifiedData.get(key).getRight().get(cls);
396 if (result == null) {
397 result = Collections.EMPTY_LIST;
402 public void setModifiedData(final Map<InstanceIdentifier<Node>,
403 Pair<Map<Class<? extends Identifiable>, List<Identifiable>>,
404 Map<Class<? extends Identifiable>, List<Identifiable>>>> modifiedData) {
405 this.modifiedData = modifiedData;
408 public boolean isInReconciliation() {
409 return inReconciliation;
412 public void setInReconciliation(boolean inReconciliation) {
413 this.inReconciliation = inReconciliation;