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