2 * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. 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;
11 import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependencyQueue;
12 import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependentJob;
13 import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactCommand;
14 import org.opendaylight.ovsdb.lib.notation.UUID;
15 import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
16 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
17 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
19 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
20 import org.opendaylight.yangtools.yang.binding.Identifiable;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 import java.util.HashMap;
26 import java.util.Iterator;
28 import java.util.concurrent.ConcurrentHashMap;
31 * HwvtepDeviceInfo is used to store some of the table entries received
32 * in updates from a Hwvtep device. There will be one instance of this per
33 * Hwvtep device connected. Table entries are stored in a map keyed by
34 * uuids of respective rows.
36 * Purpose of this class is to provide data present in tables which
37 * were updated in a previous transaction and are not available in
38 * current updatedRows. This allows us to handle updates for Tables
39 * which reference other tables and need information in those tables
40 * to add data to Operational data store.
42 * e.g. Mac-entries in data store use logical-switch-ref as one of the
43 * keys. Mac-entry updates from switch rarely contain Logical_Switch
44 * table entries. To add mac-entries we need table entries from
45 * Logical_Switch table which were created in an earlier update.
48 public class HwvtepDeviceInfo {
50 private static final Logger LOG = LoggerFactory.getLogger(HwvtepDeviceInfo.class);
52 public enum DeviceDataStatus {
58 public static class DeviceData {
59 private final InstanceIdentifier key;
60 private final UUID uuid;
61 private final Object data;
62 private final DeviceDataStatus status;
64 DeviceData(InstanceIdentifier key, UUID uuid, Object data, DeviceDataStatus status) {
71 public Object getData() {
75 public DeviceDataStatus getStatus() {
79 public UUID getUuid() {
85 private Map<UUID, LogicalSwitch> logicalSwitches = null;
86 private Map<UUID, PhysicalSwitch> physicalSwitches = null;
87 private Map<UUID, PhysicalLocator> physicalLocators = null;
88 private Map<UUID, UUID> mapTunnelToPhysicalSwitch = null;
90 private HwvtepConnectionInstance connectionInstance;
92 private Map<Class<? extends Identifiable>, Map<InstanceIdentifier, DeviceData>> configKeyVsData = new ConcurrentHashMap<>();
93 private Map<Class<? extends Identifiable>, Map<InstanceIdentifier, DeviceData>> opKeyVsData = new ConcurrentHashMap<>();
94 private Map<Class<? extends Identifiable>, Map<UUID, Object>> uuidVsData = new ConcurrentHashMap<>();
95 private DependencyQueue dependencyQueue;
97 public HwvtepDeviceInfo(HwvtepConnectionInstance hwvtepConnectionInstance) {
98 this.connectionInstance = hwvtepConnectionInstance;
99 this.logicalSwitches = new HashMap<>();
100 this.physicalSwitches = new HashMap<>();
101 this.physicalLocators = new HashMap<>();
102 this.mapTunnelToPhysicalSwitch = new HashMap<>();
103 this.dependencyQueue = new DependencyQueue(this);
106 public LogicalSwitch getLogicalSwitch(UUID uuid) {
107 return (LogicalSwitch) getDeviceOperData(LogicalSwitches.class, uuid);
110 public Map<UUID, LogicalSwitch> getLogicalSwitches() {
111 Map<UUID, Object> switches = uuidVsData.get(LogicalSwitches.class);
112 Map<UUID, LogicalSwitch> result = new HashMap<>();
113 if (switches != null) {
114 for (Map.Entry<UUID, Object> entry : switches.entrySet()) {
115 result.put(entry.getKey(), (LogicalSwitch) entry.getValue());
121 public void putPhysicalSwitch(UUID uuid, PhysicalSwitch pSwitch) {
122 physicalSwitches.put(uuid, pSwitch);
125 public PhysicalSwitch getPhysicalSwitch(UUID uuid) {
126 return physicalSwitches.get(uuid);
129 public PhysicalSwitch removePhysicalSwitch(UUID uuid) {
130 return physicalSwitches.remove(uuid);
133 public Map<UUID, PhysicalSwitch> getPhysicalSwitches() {
134 return physicalSwitches;
137 public PhysicalLocator getPhysicalLocator(UUID uuid) {
138 return (PhysicalLocator) getDeviceOperData(TerminationPoint.class, uuid);
141 public Map<UUID, PhysicalLocator> getPhysicalLocators() {
142 Map<UUID, Object> locators = uuidVsData.get(LogicalSwitches.class);
143 Map<UUID, PhysicalLocator> result = new HashMap<>();
144 if (locators != null) {
145 for (Map.Entry<UUID, Object> entry : locators.entrySet()) {
146 result.put(entry.getKey(), (PhysicalLocator) entry.getValue());
152 public void putPhysicalSwitchForTunnel(UUID uuid, UUID psUUID) {
153 mapTunnelToPhysicalSwitch.put(uuid, psUUID);
156 public PhysicalSwitch getPhysicalSwitchForTunnel(UUID uuid) {
157 return physicalSwitches.get(mapTunnelToPhysicalSwitch.get(uuid));
160 public void removePhysicalSwitchForTunnel(UUID uuid) {
161 mapTunnelToPhysicalSwitch.remove(uuid);
164 public Map<UUID, UUID> getPhysicalSwitchesForTunnels() {
165 return mapTunnelToPhysicalSwitch;
168 public boolean isKeyInTransit(Class<? extends Identifiable> cls, InstanceIdentifier key) {
169 DeviceData deviceData = HwvtepSouthboundUtil.getData(opKeyVsData, cls, key);
170 return deviceData != null && DeviceDataStatus.IN_TRANSIT == deviceData.status;
173 public boolean isConfigDataAvailable(Class<? extends Identifiable> cls, InstanceIdentifier key) {
174 return HwvtepSouthboundUtil.getData(configKeyVsData, cls, key) != null;
177 public void updateConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key, Object data) {
178 HwvtepSouthboundUtil.updateData(configKeyVsData, cls, key,
179 new DeviceData(key, null, data, DeviceDataStatus.AVAILABLE));
182 public Object getConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
183 return HwvtepSouthboundUtil.getData(configKeyVsData, cls, key);
186 public void clearConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
187 HwvtepSouthboundUtil.clearData(configKeyVsData, cls, key);
190 public void markKeyAsInTransit(Class<? extends Identifiable> cls, InstanceIdentifier key) {
191 LOG.debug("Marking device data as intransit {}", key);
192 DeviceData deviceData = getDeviceOperData(cls, key);
195 if (deviceData != null) {
196 uuid = deviceData.getUuid();
197 data = deviceData.getData();
199 HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key,
200 new DeviceData(key, uuid, data, DeviceDataStatus.IN_TRANSIT));
203 public void updateDeviceOperData(Class<? extends Identifiable> cls, InstanceIdentifier key, UUID uuid, Object data) {
204 LOG.debug("Updating device data {}", key);
205 HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key,
206 new DeviceData(key, uuid, data, DeviceDataStatus.AVAILABLE));
207 HwvtepSouthboundUtil.updateData(uuidVsData, cls, uuid, data);
210 public void clearDeviceOperData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
211 DeviceData deviceData = HwvtepSouthboundUtil.getData(opKeyVsData, cls, key);
212 if (deviceData != null && deviceData.uuid != null) {
213 HwvtepSouthboundUtil.clearData(uuidVsData, cls, deviceData.uuid);
215 HwvtepSouthboundUtil.clearData(opKeyVsData, cls, key);
218 public Object getDeviceOperData(Class<? extends Identifiable> cls, UUID uuid) {
219 return HwvtepSouthboundUtil.getData(uuidVsData, cls, uuid);
222 public DeviceData getDeviceOperData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
223 return HwvtepSouthboundUtil.getData(opKeyVsData, cls, key);
226 public UUID getUUID(Class<? extends Identifiable> cls, InstanceIdentifier key) {
227 DeviceData data = HwvtepSouthboundUtil.getData(opKeyVsData, cls, key);
234 public <T extends Identifiable> void addJobToQueue(DependentJob<T> job) {
235 dependencyQueue.addToQueue(job);
238 public void onConfigDataAvailable() {
239 dependencyQueue.processReadyJobsFromConfigQueue(connectionInstance);
242 public void onOperDataAvailable() {
243 dependencyQueue.processReadyJobsFromOpQueue(connectionInstance);
246 public void scheduleTransaction(final TransactCommand transactCommand) {
247 dependencyQueue.submit(() -> connectionInstance.transact(transactCommand));
250 public void clearInTransitData() {
251 //TODO restore old data
252 for (Map<InstanceIdentifier, DeviceData> map : opKeyVsData.values()) {
253 Iterator<Map.Entry<InstanceIdentifier, DeviceData>> iterator = map.entrySet().iterator();
254 while ( iterator.hasNext() ) {
255 Map.Entry<InstanceIdentifier, DeviceData> entry = iterator.next();
256 if (entry.getValue().getStatus() == DeviceDataStatus.IN_TRANSIT) {
261 onOperDataAvailable();