bug 6579 added dependency queue
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / HwvtepDeviceInfo.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;
10
11 import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependencyQueue;
12 import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependentJob;
13 import org.opendaylight.ovsdb.lib.notation.UUID;
14 import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
15 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
16 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
17 import org.opendaylight.yangtools.yang.binding.Identifiable;
18 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.concurrent.ConcurrentHashMap;
25
26 /*
27  * HwvtepDeviceInfo is used to store some of the table entries received
28  * in updates from a Hwvtep device. There will be one instance of this per
29  * Hwvtep device connected. Table entries are stored in a map keyed by
30  * uuids of respective rows.
31  *
32  * Purpose of this class is to provide data present in tables which
33  * were updated in a previous transaction and are not available in
34  * current updatedRows. This allows us to handle updates for Tables
35  * which reference other tables and need information in those tables
36  * to add data to Operational data store.
37  *
38  * e.g. Mac-entries in data store use logical-switch-ref as one of the
39  * keys. Mac-entry updates from switch rarely contain Logical_Switch
40  * table entries. To add mac-entries we need table entries from
41  * Logical_Switch table which were created in an earlier update.
42  *
43  */
44 public class HwvtepDeviceInfo {
45
46     private static final Logger LOG = LoggerFactory.getLogger(HwvtepDeviceInfo.class);
47
48     public enum DeviceDataStatus {
49         IN_TRANSIT,
50         UNAVAILABLE,
51         AVAILABLE
52     }
53
54     public static class DeviceData {
55         private final InstanceIdentifier key;
56         private final UUID uuid;
57         private final Object data;
58         private final DeviceDataStatus status;
59
60         DeviceData(InstanceIdentifier key, UUID uuid, Object data, DeviceDataStatus status) {
61             this.data = data;
62             this.key = key;
63             this.status = status;
64             this.uuid = uuid;
65         }
66
67         public Object getData() {
68             return data;
69         }
70
71         public DeviceDataStatus getStatus() {
72             return status;
73         }
74
75         public UUID getUuid() {
76             return uuid;
77         }
78     }
79
80     //TODO remove this
81     private Map<UUID, LogicalSwitch> logicalSwitches = null;
82     private Map<UUID, PhysicalSwitch> physicalSwitches = null;
83     private Map<UUID, PhysicalLocator> physicalLocators = null;
84     private Map<UUID, UUID> mapTunnelToPhysicalSwitch = null;
85
86     private HwvtepConnectionInstance connectionInstance;
87
88     private Map<Class<? extends Identifiable>, Map<InstanceIdentifier, DeviceData>> configKeyVsData = new ConcurrentHashMap<>();
89     private Map<Class<? extends Identifiable>, Map<InstanceIdentifier, DeviceData>> opKeyVsData = new ConcurrentHashMap<>();
90     private Map<Class<? extends Identifiable>, Map<UUID, Object>> uuidVsData = new ConcurrentHashMap<>();
91     private DependencyQueue dependencyQueue;
92
93     public HwvtepDeviceInfo(HwvtepConnectionInstance hwvtepConnectionInstance) {
94         this.connectionInstance = hwvtepConnectionInstance;
95         this.logicalSwitches = new HashMap<>();
96         this.physicalSwitches = new HashMap<>();
97         this.physicalLocators = new HashMap<>();
98         this.mapTunnelToPhysicalSwitch = new HashMap<>();
99         this.dependencyQueue = new DependencyQueue(this);
100     }
101
102     public void putLogicalSwitch(UUID uuid, LogicalSwitch lSwitch) {
103         logicalSwitches.put(uuid, lSwitch);
104     }
105
106     public LogicalSwitch getLogicalSwitch(UUID uuid) {
107         return logicalSwitches.get(uuid);
108     }
109
110     public LogicalSwitch removeLogicalSwitch(UUID uuid) {
111         return logicalSwitches.remove(uuid);
112     }
113
114     public Map<UUID, LogicalSwitch> getLogicalSwitches() {
115         return logicalSwitches;
116     }
117
118     public void putPhysicalSwitch(UUID uuid, PhysicalSwitch pSwitch) {
119         physicalSwitches.put(uuid, pSwitch);
120     }
121
122     public PhysicalSwitch getPhysicalSwitch(UUID uuid) {
123         return physicalSwitches.get(uuid);
124     }
125
126     public PhysicalSwitch removePhysicalSwitch(UUID uuid) {
127         return physicalSwitches.remove(uuid);
128     }
129
130     public Map<UUID, PhysicalSwitch> getPhysicalSwitches() {
131         return physicalSwitches;
132     }
133
134     public void putPhysicalLocator(UUID uuid, PhysicalLocator pLocator) {
135         physicalLocators.put(uuid, pLocator);
136     }
137
138     public PhysicalLocator getPhysicalLocator(UUID uuid) {
139         return physicalLocators.get(uuid);
140     }
141
142     public PhysicalLocator removePhysicalLocator(UUID uuid) {
143         return physicalLocators.remove(uuid);
144     }
145
146     public Map<UUID, PhysicalLocator> getPhysicalLocators() {
147         return physicalLocators;
148     }
149
150     public void putPhysicalSwitchForTunnel(UUID uuid, UUID psUUID) {
151         mapTunnelToPhysicalSwitch.put(uuid, psUUID);
152     }
153
154     public PhysicalSwitch getPhysicalSwitchForTunnel(UUID uuid) {
155         return physicalSwitches.get(mapTunnelToPhysicalSwitch.get(uuid));
156     }
157
158     public void removePhysicalSwitchForTunnel(UUID uuid) {
159         mapTunnelToPhysicalSwitch.remove(uuid);
160     }
161
162     public Map<UUID, UUID> getPhysicalSwitchesForTunnels() {
163         return mapTunnelToPhysicalSwitch;
164     }
165
166     public boolean isKeyInTransit(Class<? extends Identifiable> cls, InstanceIdentifier key) {
167         DeviceData deviceData = HwvtepSouthboundUtil.getData(opKeyVsData, cls, key);
168         return deviceData != null && DeviceDataStatus.IN_TRANSIT == deviceData.status;
169     }
170
171     public boolean isConfigDataAvailable(Class<? extends Identifiable> cls, InstanceIdentifier key) {
172         return HwvtepSouthboundUtil.getData(configKeyVsData, cls, key) != null;
173     }
174
175     public void updateConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key, Object data) {
176         HwvtepSouthboundUtil.updateData(configKeyVsData, cls, key,
177                 new DeviceData(key, null, data, DeviceDataStatus.AVAILABLE));
178     }
179
180     public void clearConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
181         HwvtepSouthboundUtil.clearData(configKeyVsData, cls, key);
182     }
183
184     public void markKeyAsInTransit(Class<? extends Identifiable> cls, InstanceIdentifier key) {
185         HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key,
186                 new DeviceData(key, null, null, DeviceDataStatus.IN_TRANSIT));
187     }
188
189     public void updateDeviceOpData(Class<? extends Identifiable> cls, InstanceIdentifier key, UUID uuid, Object data) {
190         HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key,
191                 new DeviceData(key, uuid, data, DeviceDataStatus.AVAILABLE));
192         HwvtepSouthboundUtil.updateData(uuidVsData, cls, uuid, data);
193     }
194
195     public void clearDeviceOpData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
196         DeviceData deviceData = HwvtepSouthboundUtil.getData(opKeyVsData, cls, key);
197         if (deviceData != null && deviceData.uuid != null) {
198             HwvtepSouthboundUtil.clearData(uuidVsData, cls, deviceData.uuid);
199         }
200         HwvtepSouthboundUtil.clearData(opKeyVsData, cls, key);
201     }
202
203     public Object getDeviceOpData(Class<? extends Identifiable> cls, UUID uuid) {
204         return HwvtepSouthboundUtil.getData(uuidVsData, cls, uuid);
205     }
206
207     public DeviceData getDeviceOpData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
208         return HwvtepSouthboundUtil.getData(opKeyVsData, cls, key);
209     }
210
211     public UUID getUUID(Class<? extends Identifiable> cls, InstanceIdentifier key) {
212         DeviceData data = HwvtepSouthboundUtil.getData(opKeyVsData, cls, key);
213         if (data != null) {
214             return data.uuid;
215         }
216         return null;
217     }
218
219     public <T extends Identifiable> void addJobToQueue(DependentJob<T> job) {
220         dependencyQueue.addToQueue(job);
221     }
222
223     public void onConfigDataAvailable() {
224         dependencyQueue.processReadyJobsFromConfigQueue(connectionInstance);
225     }
226
227     public void onOpDataAvailable() {
228         dependencyQueue.processReadyJobsFromOpQueue(connectionInstance);
229     }
230 }