2 * Copyright (c) 2014 André Martins 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.l2switch.hosttracker.plugin.internal;
10 import java.util.Collection;
11 import java.util.Iterator;
12 import java.util.List;
14 import java.util.Map.Entry;
15 import java.util.concurrent.ConcurrentHashMap;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.l2switch.hosttracker.plugin.inventory.Host;
18 import org.opendaylight.l2switch.hosttracker.plugin.util.Utilities;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostId;
20 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
26 * This will (try to) submit all writes and deletes in to the MD-SAL database.
27 * The removeLocally and putLocally methods should be used when dataChanges are dealt locally and not update to MD-SAL.
29 public class ConcurrentClusterAwareHostHashMap {
30 private static final Logger LOG = LoggerFactory.getLogger(ConcurrentClusterAwareHostHashMap.class);
32 private final OperationProcessor opProcessor;
33 private final String topologyId;
36 * The instance identifiers for each host submitted to MD-SAL.
38 private final ConcurrentHashMap<InstanceIdentifier<Node>, HostId> instanceIDs = new ConcurrentHashMap<>();
41 * The local Hosts' HashMap.
43 private final ConcurrentHashMap<HostId, Host> hostHashMap = new ConcurrentHashMap<>();
45 public ConcurrentClusterAwareHostHashMap(OperationProcessor opProcessor, String topologyId) {
46 this.opProcessor = opProcessor;
47 this.topologyId = topologyId;
51 * Removes, if exists, the Host with the given
52 * InstanceIdentifier<Node> from this local HashMap. Ideally used for
53 * host data listener events.
56 * the InstanceIdentifier<Node> of the Host to remove.
57 * @return the removed Host if exits, null if it doesn't exist.
59 public synchronized Host removeLocally(InstanceIdentifier<Node> iiN) {
60 HostId hostId = this.instanceIDs.remove(iiN);
62 return this.hostHashMap.remove(hostId);
68 * Removes, if exists, the Host with the given Key (HostId) from this local
69 * HashMap. Ideally used for host data listener events.
72 * the key (HostId) of the Host to remove.
73 * @return the removed Host if exits, null if it doesn't exist.
75 public synchronized Host removeLocally(HostId key) {
76 Iterator<Entry<InstanceIdentifier<Node>, HostId>> iterator = this.instanceIDs.entrySet().iterator();
77 while (iterator.hasNext()) {
78 if (iterator.next().getValue().equals(key)) {
83 return hostHashMap.remove(key);
87 * Puts the given value (Host) only in this local HashMap. Ideally used for
88 * host data listener events.
91 * the value's (Host's) InstanceIdentifier<Node>
93 * the Host to store locally.
94 * @return the previous value associated with <tt>key</tt>, or <tt>null</tt>
95 * if there was no mapping for <tt>key</tt>
97 public synchronized Host putLocally(InstanceIdentifier<Node> ii, Host value) {
99 LOG.trace("Putting locally {}", host.getId());
100 this.instanceIDs.put(ii, host.getId());
101 return this.hostHashMap.put(host.getId(), value);
105 * Removes the given hosts both locally and on MD-SAL database.
108 * the hosts to remove.
110 public synchronized void removeAll(List<Host> hosts) {
111 for (final Map.Entry<InstanceIdentifier<Node>, HostId> e : this.instanceIDs.entrySet()) {
112 for (Host h : hosts) {
113 if (e.getValue().equals(h.getId())) {
114 this.opProcessor.enqueueOperation(tx -> tx.delete(LogicalDatastoreType.OPERATIONAL, e.getKey()));
115 this.hostHashMap.remove(e.getValue());
123 * Forces the local Host with the given HostId to be merged into MD-SAL
127 * the Host's hostId that will be merged into MD-SAL database.
129 public synchronized void submit(HostId hostid) {
130 Host host = this.hostHashMap.get(hostid);
131 final Node hostNode = host.getHostNode();
132 final InstanceIdentifier<Node> buildNodeIID = Utilities.buildNodeIID(hostNode.getKey(), topologyId);
133 this.opProcessor.enqueueOperation(tx -> tx.merge(LogicalDatastoreType.OPERATIONAL, buildNodeIID,
135 putLocally(buildNodeIID, host);
136 this.instanceIDs.put(buildNodeIID, host.getId());
137 LOG.trace("Enqueued for MD-SAL transaction {}", hostNode.getNodeId());
141 * Puts all the given hosts into this local HashMap and into MD-SAL
145 * the hosts to be sent into MD-SAL database.
147 public synchronized void putAll(List<Host> hosts) {
148 for (Host h : hosts) {
149 final Node hostNode = h.getHostNode();
150 final InstanceIdentifier<Node> buildNodeIID = Utilities.buildNodeIID(hostNode.getKey(), topologyId);
151 this.opProcessor.enqueueOperation(tx -> tx.merge(LogicalDatastoreType.OPERATIONAL, buildNodeIID,
153 putLocally(buildNodeIID, h);
154 this.instanceIDs.put(buildNodeIID, h.getId());
155 LOG.trace("Putting MD-SAL {}", hostNode.getNodeId());
160 * Puts the given host in the this local HashMap and into MD-SAL database.
163 * the key for the map
165 * the value for the map
166 * @return the old value from the local cache if present, null otherwise.
168 public synchronized Host put(HostId hostId, Host host) {
169 final Node hostNode = host.getHostNode();
170 final InstanceIdentifier<Node> buildNodeIID = Utilities.buildNodeIID(hostNode.getKey(), topologyId);
171 this.opProcessor.enqueueOperation(tx -> tx.merge(LogicalDatastoreType.OPERATIONAL, buildNodeIID,
173 LOG.trace("Putting MD-SAL {}", hostNode.getNodeId());
174 return putLocally(buildNodeIID, host);
178 * Removes the value (Host) with the given hostId from this local HashMap
179 * and MD-SAL database.
182 * the Host's hostId to remove
183 * @return the old value from the local cache if present, null otherwise.
185 public synchronized Host remove(HostId hostId) {
186 Host removedValue = this.hostHashMap.remove(hostId);
187 if (removedValue != null) {
188 Node hostNode = removedValue.getHostNode();
189 final InstanceIdentifier<Node> hnIID = Utilities.buildNodeIID(hostNode.getKey(), topologyId);
190 this.opProcessor.enqueueOperation(tx -> tx.delete(LogicalDatastoreType.OPERATIONAL, hnIID));
191 this.instanceIDs.remove(hnIID);
196 public boolean containsKey(Object key) {
197 return this.hostHashMap.containsKey(key);
200 public Host get(HostId key) {
201 return this.hostHashMap.get(key);
205 * Removes all of the mappings from this local HashMap and from MD-SAL. The
206 * local HashMap will be empty after this call returns.
208 public synchronized void clear() {
209 for (final Map.Entry<? extends InstanceIdentifier<Node>, HostId> e : this.instanceIDs.entrySet()) {
210 this.opProcessor.enqueueOperation(tx -> tx.delete(LogicalDatastoreType.OPERATIONAL, e.getKey()));
212 this.hostHashMap.clear();
216 * Returns the Values from this local HashMap.
218 * @return the Values from this local HashMap.
220 public Collection<Host> values() {
221 return this.hostHashMap.values();