2 * Copyright (c) 2020 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
8 package org.opendaylight.genius.utils.hwvtep;
10 import com.google.common.collect.ImmutableList;
11 import com.google.common.collect.ImmutableMap;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.HashSet;
16 import java.util.List;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.LinkedBlockingQueue;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
22 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 public class HwvtepHACache {
29 private static final Logger LOG = LoggerFactory.getLogger(HwvtepHACache.class);
31 private static final int MAX_EVENT_BUFFER_SIZE = 500000;
32 private static final int EVENT_DRAIN_BUFFER_SIZE = 100000;
34 private static HwvtepHACache instance = new HwvtepHACache();
36 private final ConcurrentHashMap<InstanceIdentifier<Node>, Set<InstanceIdentifier<Node>>>
37 parentToChildMap = new ConcurrentHashMap<>();
39 private final ConcurrentHashMap<InstanceIdentifier<Node>, InstanceIdentifier<Node>>
40 childToParentMap = new ConcurrentHashMap<>();
42 private final ConcurrentHashMap<String, Boolean> childNodeIds = new ConcurrentHashMap<>();
44 private final ConcurrentHashMap<String, Boolean> connectedNodes = new ConcurrentHashMap<>();
46 private final LinkedBlockingQueue<DebugEvent> debugEvents = new LinkedBlockingQueue<>(MAX_EVENT_BUFFER_SIZE);
47 private final Map<InstanceIdentifier<Node>, IpAddress> tepIps = new ConcurrentHashMap<>();
48 private final Map<IpAddress, InstanceIdentifier<Node>> nodeIds = new ConcurrentHashMap<>();
50 public HwvtepHACache() {
53 public static HwvtepHACache getInstance() {
57 public synchronized void addChild(InstanceIdentifier<Node> parent, InstanceIdentifier<Node> child) {
58 if (parent == null || child == null) {
62 parentToChildMap.computeIfAbsent(parent, key -> new HashSet<>()).add(child);
63 childToParentMap.put(child, parent);
64 String childNodeId = child.firstKeyOf(Node.class).getNodeId().getValue();
65 childNodeIds.put(childNodeId, Boolean.TRUE);
66 addDebugEvent(new NodeEvent.ChildAddedEvent(childNodeId));
69 public IpAddress getTepIpOfNode(InstanceIdentifier<Node> iid) {
70 return this.tepIps.get(iid);
73 public InstanceIdentifier<Node> getNodeIdFromTepIp(IpAddress ipAddress) {
74 return this.nodeIds.get(ipAddress);
77 public void setTepIpOfNode(InstanceIdentifier<Node> iid, IpAddress ipAddress) {
78 this.tepIps.put(iid, ipAddress);
79 if (this.isHAParentNode(iid)) {
80 this.nodeIds.put(ipAddress, iid);
82 this.nodeIds.putIfAbsent(ipAddress, iid);
87 public boolean isHAEnabledDevice(InstanceIdentifier<?> iid) {
91 boolean enabled = childToParentMap.containsKey(iid.firstIdentifierOf(Node.class));
93 String psNodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
94 int idx = psNodeId.indexOf(HwvtepSouthboundConstants.PSWITCH_URI_PREFIX);
96 String globalNodeId = psNodeId.substring(0, idx - 1);
97 return childNodeIds.containsKey(globalNodeId);
103 public boolean isHAParentNode(InstanceIdentifier<Node> node) {
104 return parentToChildMap.containsKey(node);
107 public Set<InstanceIdentifier<Node>> getChildrenForHANode(InstanceIdentifier<Node> parent) {
108 if (parent != null && parentToChildMap.containsKey(parent)) {
109 return new HashSet<>(parentToChildMap.get(parent));
111 return Collections.emptySet();
115 public Set<InstanceIdentifier<Node>> getHAParentNodes() {
116 return parentToChildMap.keySet();
119 public Set<InstanceIdentifier<Node>> getHAChildNodes() {
120 return childToParentMap.keySet();
123 public InstanceIdentifier<Node> getParent(InstanceIdentifier<Node> child) {
125 return childToParentMap.get(child);
130 public synchronized void cleanupParent(InstanceIdentifier<Node> parent) {
131 if (parent == null) {
135 if (parentToChildMap.get(parent) != null) {
136 Set<InstanceIdentifier<Node>> childs = parentToChildMap.get(parent);
137 for (InstanceIdentifier<Node> child : childs) {
138 childToParentMap.remove(child);
139 String childNodeId = child.firstKeyOf(Node.class).getNodeId().getValue();
140 childNodeIds.remove(childNodeId);
143 parentToChildMap.remove(parent);
146 public void updateConnectedNodeStatus(InstanceIdentifier<Node> iid) {
147 String nodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
148 connectedNodes.put(nodeId, true);
149 DebugEvent event = new NodeEvent.NodeConnectedEvent(nodeId);
150 addDebugEvent(event);
153 public void updateDisconnectedNodeStatus(InstanceIdentifier<Node> iid) {
154 String nodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
155 connectedNodes.put(nodeId, false);
156 DebugEvent event = new NodeEvent.NodeDisconnectedEvent(nodeId);
157 addDebugEvent(event);
160 public Map<String, Boolean> getConnectedNodes() {
161 return ImmutableMap.copyOf(connectedNodes);
164 public void addDebugEvent(DebugEvent debugEvent) {
165 //Try adding the event to event queue
166 if (!debugEvents.offer(debugEvent)) {
167 //buffer is exhausted
168 Collection<DebugEvent> list = new ArrayList<>();
169 //do not clear all events , make some place by clearing few old events
170 debugEvents.drainTo(list, EVENT_DRAIN_BUFFER_SIZE);
172 if (!debugEvents.offer(debugEvent)) {
173 LOG.debug("Unable to add debug event");
178 public List<DebugEvent> getNodeEvents() {
179 return ImmutableList.copyOf(debugEvents);