Migrate to Objects.requireNonNull()
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transact / HwvtepOperationalState.java
1 /*
2  * Copyright (c) 2015, 2017 China Telecom Beijing Research Institute 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.transact;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Map.Entry;
18 import java.util.Optional;
19 import java.util.Set;
20 import java.util.concurrent.ConcurrentHashMap;
21 import org.apache.commons.lang3.tuple.Pair;
22 import org.opendaylight.mdsal.binding.api.DataBroker;
23 import org.opendaylight.mdsal.binding.api.DataTreeModification;
24 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
25 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
26 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
27 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
28 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
29 import org.opendaylight.ovsdb.lib.notation.UUID;
30 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeBase;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Acls;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacs;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacsKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacsKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalRouters;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalRoutersKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacsKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.Tunnels;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelsKey;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
57 import org.opendaylight.yangtools.yang.binding.Identifiable;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 //TODO: need to be optimized, get entry by iid not name
63 public class HwvtepOperationalState {
64
65     private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperationalState.class);
66
67     private final Map<InstanceIdentifier<Node>, Node> operationalNodes = new HashMap<>();
68     private ReadWriteTransaction transaction;
69     HashMap<InstanceIdentifier<TerminationPoint>, UUID> inflightLocators = new HashMap<>();
70     private final HwvtepDeviceInfo deviceInfo;
71     private final HwvtepConnectionInstance connectionInstance;
72     private final Map<Class<? extends Identifiable>, Map<InstanceIdentifier, UUID>> currentTxUUIDs =
73             new ConcurrentHashMap<>();
74     private final Map<Class<? extends Identifiable>, Map<InstanceIdentifier, Boolean>> currentTxDeletedKeys =
75             new ConcurrentHashMap<>();
76
77     /* stores the modified and deleted data for each child type of each node id
78        Map<nodeid , Pair < updated, deleted >
79        each updated/ deleted contains Map < child type, List<ChildData>>
80        child type is the child of hwvtep Global augmentation
81      */
82     private Map<InstanceIdentifier<Node>,
83             Pair<Map<Class<? extends Identifiable>, List<Identifiable>>,
84                     Map<Class<? extends Identifiable>, List<Identifiable>>>> modifiedData = new HashMap<>();
85     private boolean inReconciliation = false;
86     private final DataBroker db;
87     private final Collection<DataTreeModification<Node>> changes;
88     long transactionId = 0;
89
90     public HwvtepOperationalState(final DataBroker db, final HwvtepConnectionInstance connectionInstance,
91                                   final Collection<DataTreeModification<Node>> changes) {
92         this.connectionInstance = connectionInstance;
93         this.deviceInfo = connectionInstance.getDeviceInfo();
94         this.db = db;
95         this.changes = changes;
96         this.transaction = db.newReadWriteTransaction();
97     }
98
99     public HwvtepOperationalState(final HwvtepConnectionInstance connectionInstance) {
100         this.connectionInstance = connectionInstance;
101         this.deviceInfo = connectionInstance.getDeviceInfo();
102         this.db = connectionInstance.getDataBroker();
103         this.changes = null;
104         transaction = connectionInstance.getDataBroker().newReadWriteTransaction();
105         Optional<Node> readNode = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL,
106                 connectionInstance.getInstanceIdentifier());
107         if (readNode.isPresent()) {
108             operationalNodes.put(connectionInstance.getInstanceIdentifier(), readNode.get());
109         }
110     }
111
112     public HwvtepOperationalState(final DataBroker db,
113                                   final HwvtepConnectionInstance connectionInstance,
114                                   final Collection<DataTreeModification<Node>> changes,
115                                   final Node globalOperNode,
116                                   final Node psNode) {
117         this(db, connectionInstance, changes);
118         operationalNodes.put(connectionInstance.getInstanceIdentifier(), globalOperNode);
119         HwvtepGlobalAugmentation globalAugmentation = globalOperNode.augmentation(HwvtepGlobalAugmentation.class);
120         if (globalAugmentation != null) {
121             if (!HwvtepSouthboundUtil.isEmptyMap(globalAugmentation.getSwitches())) {
122                 operationalNodes.put((InstanceIdentifier<Node>)
123                         globalAugmentation.getSwitches().values().iterator().next().getSwitchRef().getValue(), psNode);
124             }
125         }
126     }
127
128     public void readOperationalNodes() {
129         if (inReconciliation) {
130             return;
131         }
132         if (changes == null) {
133             LOG.warn("Could not read operational nodes for {} as changes is",
134                     connectionInstance.getNodeId().getValue());
135             return;
136         }
137         Map<InstanceIdentifier<Node>, Node> nodeCreateOrUpdate =
138                 TransactUtils.extractCreatedOrUpdatedOrRemoved(changes, Node.class);
139         if (nodeCreateOrUpdate != null) {
140             transaction = db.newReadWriteTransaction();
141             for (Entry<InstanceIdentifier<Node>, Node> entry: nodeCreateOrUpdate.entrySet()) {
142                 Optional<Node> readNode = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL,
143                         entry.getKey());
144                 //add related globalNode or physicalSwitchNode to operationalNodes map
145                 //for example, when creating physical port, logical switch is needed
146                 //but logical switch is in HwvtepGlobalAugmentation rather than PhysicalSwitchAugmentation
147                 if (readNode.isPresent()) {
148                     operationalNodes.put(entry.getKey(), readNode.get());
149                     HwvtepGlobalAugmentation hgAugmentation =
150                             readNode.get().augmentation(HwvtepGlobalAugmentation.class);
151                     PhysicalSwitchAugmentation psAugmentation =
152                             readNode.get().augmentation(PhysicalSwitchAugmentation.class);
153                     if (hgAugmentation != null && hgAugmentation.getSwitches() != null) {
154                         for (Switches pswitch : hgAugmentation.getSwitches().values()) {
155                             @SuppressWarnings("unchecked")
156                             InstanceIdentifier<Node> psNodeIid =
157                                     (InstanceIdentifier<Node>) pswitch.getSwitchRef().getValue();
158                             Optional<Node> psNode =
159                                 new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, psNodeIid);
160                             if (psNode.isPresent()) {
161                                 operationalNodes.put(psNodeIid, psNode.get());
162                             }
163                         }
164                     }
165                     if (psAugmentation != null) {
166                         @SuppressWarnings("unchecked")
167                         InstanceIdentifier<Node> hgNodeIid =
168                                 (InstanceIdentifier<Node>) psAugmentation.getManagedBy().getValue();
169                         Optional<Node> hgNode = new MdsalUtils(db).readOptional(
170                                 LogicalDatastoreType.OPERATIONAL, hgNodeIid);
171                         if (hgNode.isPresent()) {
172                             operationalNodes.put(hgNodeIid, hgNode.get());
173                         }
174                     }
175                 }
176             }
177         }
178     }
179
180     public Optional<Node> getGlobalNode(final InstanceIdentifier<?> iid) {
181         InstanceIdentifier<Node> nodeIid = iid.firstIdentifierOf(Node.class);
182         return Optional.ofNullable(operationalNodes.get(nodeIid));
183     }
184
185     public Optional<HwvtepGlobalAugmentation> getHwvtepGlobalAugmentation(final InstanceIdentifier<?> iid) {
186         Optional<Node> nodeOptional = getGlobalNode(requireNonNull(iid));
187         if (nodeOptional.isPresent()) {
188             return Optional.ofNullable(nodeOptional.get().augmentation(HwvtepGlobalAugmentation.class));
189         }
190         return Optional.empty();
191     }
192
193     public Optional<PhysicalSwitchAugmentation> getPhysicalSwitchAugmentation(final InstanceIdentifier<?> iid) {
194         Optional<Node> nodeOptional = getGlobalNode(requireNonNull(iid));
195         if (nodeOptional.isPresent()) {
196             return Optional.ofNullable(nodeOptional.get().augmentation(PhysicalSwitchAugmentation.class));
197         }
198         return Optional.empty();
199     }
200
201     public Optional<Map<TerminationPointKey, TerminationPoint>> getTerminationPointList(
202             final InstanceIdentifier<?> iid) {
203         Optional<Node> nodeOptional = getGlobalNode(requireNonNull(iid));
204         if (nodeOptional.isPresent() && nodeOptional.get().getTerminationPoint() != null) {
205             return Optional.ofNullable(nodeOptional.get().getTerminationPoint());
206         }
207         return Optional.empty();
208     }
209
210     public Optional<LogicalSwitches> getLogicalSwitches(final InstanceIdentifier<?> iid,
211             final LogicalSwitchesKey logicalSwitchesKey) {
212         Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(requireNonNull(iid));
213         if (nodeOptional.isPresent()) {
214             LogicalSwitches lswitch = nodeOptional.get().nonnullLogicalSwitches().get(logicalSwitchesKey);
215             if (lswitch != null) {
216                 return Optional.of(lswitch);
217             }
218         }
219         return Optional.empty();
220     }
221
222     public Optional<LogicalSwitches> getLogicalSwitches(final InstanceIdentifier<LogicalSwitches> iid) {
223         return new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, iid);
224     }
225
226     public Optional<Tunnels> getTunnels(final InstanceIdentifier<?> iid, final TunnelsKey tunnelsKey) {
227         Optional<PhysicalSwitchAugmentation> psOptional = getPhysicalSwitchAugmentation(requireNonNull(iid));
228         if (psOptional.isPresent()) {
229             Tunnels tunnel = psOptional.get().nonnullTunnels().get(tunnelsKey);
230             if (tunnel != null) {
231                 return Optional.of(tunnel);
232             }
233         }
234         return Optional.empty();
235     }
236
237     public Optional<Tunnels> getTunnels(final InstanceIdentifier<Tunnels> iid) {
238         Optional<Tunnels> tunnels = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, iid);
239         return tunnels;
240     }
241
242     public Optional<HwvtepPhysicalPortAugmentation> getPhysicalPortAugmentation(final InstanceIdentifier<?> iid,
243             final HwvtepNodeName hwvtepNodeName) {
244         Optional<Map<TerminationPointKey, TerminationPoint>> nodeOptional =
245                 getTerminationPointList(requireNonNull(iid));
246         if (nodeOptional.isPresent()) {
247             for (TerminationPoint tp : nodeOptional.get().values()) {
248                 HwvtepPhysicalPortAugmentation hppAugmentation =
249                         tp.augmentation(HwvtepPhysicalPortAugmentation.class);
250                 if (hppAugmentation != null && hppAugmentation.getHwvtepNodeName().equals(hwvtepNodeName)) {
251                     return Optional.ofNullable(hppAugmentation);
252                 }
253             }
254         }
255         return Optional.empty();
256     }
257
258     public Optional<HwvtepPhysicalLocatorAugmentation> getPhysicalLocatorAugmentation(final InstanceIdentifier<?> iid,
259             final IpAddress dstIp, final Class<? extends EncapsulationTypeBase> encapType) {
260         Optional<Map<TerminationPointKey, TerminationPoint>> nodeOptional =
261                 getTerminationPointList(requireNonNull(iid));
262         if (nodeOptional.isPresent()) {
263             for (TerminationPoint tp : nodeOptional.get().values()) {
264                 HwvtepPhysicalLocatorAugmentation hppAugmentation =
265                         tp.augmentation(HwvtepPhysicalLocatorAugmentation.class);
266                 if (hppAugmentation != null && hppAugmentation.getDstIp().equals(dstIp)
267                         && hppAugmentation.getEncapsulationType().equals(encapType)) {
268                     return Optional.ofNullable(hppAugmentation);
269                 }
270             }
271         }
272         return Optional.empty();
273     }
274
275     public Optional<HwvtepPhysicalLocatorAugmentation>
276             getPhysicalLocatorAugmentation(final InstanceIdentifier<TerminationPoint> iid) {
277         Optional<TerminationPoint> tp =
278             new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, iid);
279         if (tp.isPresent()) {
280             return Optional.ofNullable(tp.get().augmentation(HwvtepPhysicalLocatorAugmentation.class));
281         }
282         return Optional.empty();
283     }
284
285     public Optional<LocalMcastMacs> getLocalMcastMacs(final InstanceIdentifier<?> iid, final LocalMcastMacsKey key) {
286         Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(requireNonNull(iid));
287         if (nodeOptional.isPresent()) {
288             LocalMcastMacs mac = nodeOptional.get().nonnullLocalMcastMacs().get(key);
289             if (mac != null) {
290                 return Optional.of(mac);
291             }
292         }
293         return Optional.empty();
294     }
295
296     public Optional<RemoteMcastMacs> getRemoteMcastMacs(final InstanceIdentifier<?> iid, final RemoteMcastMacsKey key) {
297         Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(requireNonNull(iid));
298         if (nodeOptional.isPresent()) {
299             RemoteMcastMacs mac = nodeOptional.get().nonnullRemoteMcastMacs().get(key);
300             if (mac != null) {
301                 return Optional.of(mac);
302             }
303         }
304         return Optional.empty();
305     }
306
307     public Optional<LocalUcastMacs> getLocalUcastMacs(final InstanceIdentifier<?> iid, final LocalUcastMacsKey key) {
308         Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(requireNonNull(iid));
309         if (nodeOptional.isPresent()) {
310             LocalUcastMacs mac = nodeOptional.get().nonnullLocalUcastMacs().get(key);
311             if (mac != null) {
312                 return Optional.of(mac);
313             }
314         }
315         return Optional.empty();
316     }
317
318     public Optional<RemoteUcastMacs> getRemoteUcastMacs(final InstanceIdentifier<?> iid, final RemoteUcastMacsKey key) {
319         Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(requireNonNull(iid));
320         if (nodeOptional.isPresent()) {
321             RemoteUcastMacs mac = nodeOptional.get().nonnullRemoteUcastMacs().get(key);
322             if (mac != null) {
323                 return Optional.of(mac);
324             }
325         }
326         return Optional.empty();
327     }
328
329     public Optional<LogicalRouters> getLogicalRouters(final InstanceIdentifier<?> iid,
330             final LogicalRoutersKey logicalRoutersKey) {
331         Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(requireNonNull(iid));
332         if (nodeOptional.isPresent()) {
333             LogicalRouters lrouter = nodeOptional.get().nonnullLogicalRouters().get(logicalRoutersKey);
334             if (lrouter != null) {
335                 return Optional.of(lrouter);
336             }
337         }
338         return Optional.empty();
339     }
340
341     public Optional<Acls> getAcls(final InstanceIdentifier<Acls> iid) {
342         Optional<Acls> acl = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, iid);
343         return acl;
344     }
345
346     public ReadWriteTransaction getReadWriteTransaction() {
347         return transaction;
348     }
349
350     public void setPhysicalLocatorInFlight(final InstanceIdentifier<TerminationPoint> iid,
351                                            final UUID uuid) {
352         inflightLocators.put(iid, uuid);
353     }
354
355     public UUID getPhysicalLocatorInFlight(final InstanceIdentifier<TerminationPoint> iid) {
356         return inflightLocators.get(iid);
357     }
358
359     public HwvtepConnectionInstance getConnectionInstance() {
360         return connectionInstance;
361     }
362
363     public HwvtepDeviceInfo getDeviceInfo() {
364         return deviceInfo;
365     }
366
367     public void updateCurrentTxData(final Class<? extends Identifiable> cls, final InstanceIdentifier key,
368             final UUID uuid) {
369         HwvtepSouthboundUtil.updateData(currentTxUUIDs, cls, key, uuid);
370     }
371
372     public void updateCurrentTxDeleteData(final Class<? extends Identifiable> cls, final InstanceIdentifier key) {
373         HwvtepSouthboundUtil.updateData(currentTxDeletedKeys, cls, key, Boolean.TRUE);
374     }
375
376     public UUID getUUIDFromCurrentTx(final Class<? extends Identifiable> cls, final InstanceIdentifier key) {
377         return HwvtepSouthboundUtil.getData(currentTxUUIDs, cls, key);
378     }
379
380     public boolean isKeyPartOfCurrentTx(final Class<? extends Identifiable> cls, final InstanceIdentifier key) {
381         return HwvtepSouthboundUtil.containsKey(currentTxUUIDs, cls, key);
382     }
383
384     public Set<InstanceIdentifier> getDeletedKeysInCurrentTx(final Class<? extends Identifiable> cls) {
385         if (currentTxDeletedKeys.containsKey(cls)) {
386             return currentTxDeletedKeys.get(cls).keySet();
387         }
388         return Collections.emptySet();
389     }
390
391     public List<? extends Identifiable> getUpdatedData(final InstanceIdentifier<Node> key,
392                                                        final Class<? extends Identifiable> cls) {
393         List<Identifiable> result = null;
394         if (modifiedData.get(key) != null && modifiedData.get(key).getLeft() != null) {
395             result = modifiedData.get(key).getLeft().get(cls);
396         }
397         if (result == null) {
398             result = Collections.emptyList();
399         }
400         return result;
401     }
402
403     public List<? extends Identifiable> getDeletedData(final InstanceIdentifier<Node> key,
404                                                        final Class<? extends Identifiable> cls) {
405         List<Identifiable> result = null;
406         if (modifiedData.get(key) != null && modifiedData.get(key).getRight() != null) {
407             result = modifiedData.get(key).getRight().get(cls);
408         }
409         if (result == null) {
410             result = Collections.emptyList();
411         }
412         return result;
413     }
414
415     public void setModifiedData(final Map<InstanceIdentifier<Node>,
416             Pair<Map<Class<? extends Identifiable>, List<Identifiable>>,
417                     Map<Class<? extends Identifiable>, List<Identifiable>>>> modifiedData) {
418         this.modifiedData = modifiedData;
419     }
420
421     public boolean isInReconciliation() {
422         return inReconciliation;
423     }
424
425     public void setInReconciliation(final boolean inReconciliation) {
426         this.inReconciliation = inReconciliation;
427     }
428
429     public DataBroker getDataBroker() {
430         return db;
431     }
432
433
434     public void clearIntransitKeys() {
435         currentTxUUIDs.forEach((cls, map) -> {
436             map.forEach((iid, uuid) -> deviceInfo.clearInTransit(cls, iid));
437         });
438         currentTxDeletedKeys.forEach((cls, map) -> {
439             map.forEach((iid, val) -> deviceInfo.clearInTransit(cls, iid));
440         });
441         currentTxUUIDs.clear();
442         currentTxDeletedKeys.clear();
443         deviceInfo.onOperDataAvailable();
444     }
445
446     public long getTransactionId() {
447         return transactionId;
448     }
449 }