bug 6579 added dependency queue
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transact / UnMetDependencyGetter.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.transact;
10
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
13 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
14 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
16 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
17 import org.opendaylight.yangtools.yang.binding.DataObject;
18 import org.opendaylight.yangtools.yang.binding.Identifiable;
19 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
20
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 /**
27  * Utility class to retrieve the unmet dependencies (config/operational) of the given object
28  * @param <T>
29  */
30 public abstract class UnMetDependencyGetter<T extends Identifiable> {
31
32     private final ConfigDependencyGetter configDependencyGetter = new ConfigDependencyGetter();
33     private final InTransitDependencyGetter inTransitDependencyGetter = new InTransitDependencyGetter();
34
35     /**
36      * Returns the iids this data depends upon
37      * which are already intransit in the previous transaction if any
38      * @param opState   The operatonal state
39      * @param data      The data object
40      * @return          The depenencies
41      */
42     public Map<Class<? extends Identifiable>, List<InstanceIdentifier>> getInTransitDependencies(
43             HwvtepOperationalState opState, T data) {
44         return inTransitDependencyGetter.retrieveUnMetDependencies(opState, opState.getDeviceInfo(), data);
45     }
46
47     /**
48      * Returns the iids this data depends upon
49      * which are not yet present in the config data store if any
50      * @param opState   The operatonal state
51      * @param data      The data object
52      * @return the      depenencies
53      */
54     public Map<Class<? extends Identifiable>, List<InstanceIdentifier>> getUnMetConfigDependencies(
55             HwvtepOperationalState opState, T data) {
56         return configDependencyGetter.retrieveUnMetDependencies(opState, opState.getDeviceInfo(), data);
57     }
58
59     abstract class DependencyGetter {
60
61         Map<Class<? extends Identifiable>, List<InstanceIdentifier>> retrieveUnMetDependencies(
62                 HwvtepOperationalState opState, HwvtepDeviceInfo deviceInfo, T data) {
63
64             Map<Class<? extends Identifiable>, List<InstanceIdentifier>> result = new HashMap<>();
65             Map<Class<? extends Identifiable>, List<InstanceIdentifier<?>>> allKeys = new HashMap<>();
66             allKeys.put(LogicalSwitches.class, getLogicalSwitchDependencies(data));
67             allKeys.put(TerminationPoint.class, getTerminationPointDependencies(data));
68
69             for (Class<? extends Identifiable> cls : allKeys.keySet()) {
70                 List<InstanceIdentifier<? extends DataObject>> keysToCheck = allKeys.get(cls);
71                 for (InstanceIdentifier<? extends DataObject> key : keysToCheck) {
72                     if (!isDependencyMet(opState, deviceInfo, cls, key)) {
73                         result = addToResultMap(result, cls, key);
74                     }
75                 }
76             }
77             return result;
78         }
79
80         Map<Class<? extends Identifiable>, List<InstanceIdentifier>> addToResultMap(
81                 Map<Class<? extends Identifiable>, List<InstanceIdentifier>> result,
82                 Class<? extends Identifiable> cls, InstanceIdentifier<? extends DataObject> key) {
83             if (null == result) {
84                 result = new HashMap<>();
85             }
86             if (!result.containsKey(cls)) {
87                 result.put(cls, new ArrayList<>());
88             }
89             result.get(cls).add(key);
90             return result;
91         }
92
93         abstract boolean isDependencyMet(HwvtepOperationalState opState, HwvtepDeviceInfo deviceInfo,
94                                          Class<? extends Identifiable> cls, InstanceIdentifier<? extends DataObject> key);
95     }
96
97     class ConfigDependencyGetter extends DependencyGetter {
98         boolean isDependencyMet(HwvtepOperationalState opState, HwvtepDeviceInfo deviceInfo,
99                                 Class<? extends Identifiable> cls, InstanceIdentifier<? extends DataObject> key) {
100             return deviceInfo.isConfigDataAvailable(cls, key) || isConfigDataAvailable(opState, key);
101         }
102
103         boolean isConfigDataAvailable(HwvtepOperationalState opState, InstanceIdentifier<? extends DataObject> key) {
104             DataBroker db = opState.getConnectionInstance().getDataBroker();
105             MdsalUtils mdsalUtils = new MdsalUtils(db);
106             return mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, key) != null;
107         }
108     }
109
110     class InTransitDependencyGetter extends DependencyGetter {
111         boolean isDependencyMet(HwvtepOperationalState opState, HwvtepDeviceInfo deviceInfo,
112                                 Class<? extends Identifiable> cls, InstanceIdentifier<? extends DataObject> key) {
113             return opState.isKeyPartOfCurrentTx(cls, key) || !deviceInfo.isKeyInTransit(cls, key);
114         }
115     }
116
117     public abstract List<InstanceIdentifier<?>> getLogicalSwitchDependencies(T data);
118
119     public abstract List<InstanceIdentifier<?>> getTerminationPointDependencies(T data);
120 }