2 * Copyright (C) 2013 Red Hat, Inc.
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 * Authors : Madhu Venugopal, Brent Salisbury
10 package org.opendaylight.ovsdb.plugin.impl;
12 import java.net.InetAddress;
13 import java.util.HashMap;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.concurrent.ConcurrentMap;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Executors;
20 import java.util.concurrent.ScheduledExecutorService;
22 import org.opendaylight.controller.sal.core.Node;
23 import org.opendaylight.controller.sal.core.NodeConnector;
24 import org.opendaylight.controller.sal.core.Property;
25 import org.opendaylight.controller.sal.core.UpdateType;
26 import org.opendaylight.ovsdb.lib.message.TableUpdate;
27 import org.opendaylight.ovsdb.lib.message.TableUpdates;
28 import org.opendaylight.ovsdb.lib.notation.Row;
29 import org.opendaylight.ovsdb.lib.notation.UUID;
30 import org.opendaylight.ovsdb.plugin.internal.NodeDatabase;
31 import org.opendaylight.ovsdb.plugin.api.OvsVswitchdSchemaConstants;
32 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
33 import org.opendaylight.ovsdb.plugin.api.OvsdbInventoryListener;
34 import org.opendaylight.ovsdb.plugin.api.OvsdbInventoryService;
36 import com.google.common.collect.Sets;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 import com.google.common.collect.Maps;
43 * Stub Implementation for IPluginInReadService used by SAL
47 public class InventoryServiceImpl implements OvsdbInventoryService {
48 private static final Logger logger = LoggerFactory
49 .getLogger(InventoryServiceImpl.class);
50 private ConcurrentMap<Node, Map<String, Property>> nodeProps = new ConcurrentHashMap<Node, Map<String, Property>>();
51 private ConcurrentMap<Node, NodeDatabase> dbCache = Maps.newConcurrentMap();
52 private ScheduledExecutorService executor;
53 private OvsdbConfigurationService ovsdbConfigurationService;
55 private Set<OvsdbInventoryListener> ovsdbInventoryListeners = Sets.newCopyOnWriteArraySet();
58 * Function called by the dependency manager when all the required
59 * dependencies are satisfied
63 this.executor = Executors.newSingleThreadScheduledExecutor();
67 * Function called by the dependency manager when at least one dependency
68 * become unsatisfied or when the component is shutting down because for
69 * example bundle is being stopped.
72 public void destroy() {
76 * Function called by dependency manager after "init ()" is called and after
77 * the services provided by the class are registered in the service registry
84 * Function called by the dependency manager before the services exported by
85 * the component are unregistered, this will be followed by a "destroy ()"
90 this.executor.shutdownNow();
93 public void setOvsdbConfigurationService(OvsdbConfigurationService service) {
94 ovsdbConfigurationService = service;
97 public void unsetConfigurationService(OvsdbConfigurationService service) {
98 ovsdbConfigurationService = null;
102 public ConcurrentMap<String, ConcurrentMap<String, Row>> getCache(Node n, String databaseName) {
103 NodeDatabase db = dbCache.get(n);
104 if (db == null) return null;
105 return db.getDatabase(databaseName);
110 public ConcurrentMap<String, Row> getTableCache(Node n, String databaseName, String tableName) {
111 NodeDatabase db = dbCache.get(n);
112 if (db == null) return null;
113 return db.getTableCache(databaseName, tableName);
118 public Row getRow(Node n, String databaseName, String tableName, String uuid) {
119 NodeDatabase db = dbCache.get(n);
120 if (db == null) return null;
121 return db.getRow(databaseName, tableName, uuid);
125 public void updateRow(Node n, String databaseName, String tableName, String uuid, Row row) {
126 NodeDatabase db = dbCache.get(n);
128 db = new NodeDatabase();
131 db.updateRow(databaseName, tableName, uuid, row);
135 public void removeRow(Node n, String databaseName, String tableName, String uuid) {
136 NodeDatabase db = dbCache.get(n);
137 if (db != null) db.removeRow(databaseName, tableName, uuid);
141 public void processTableUpdates(Node n, String databaseName, TableUpdates tableUpdates) {
142 NodeDatabase db = dbCache.get(n);
144 db = new NodeDatabase();
148 for (String tableName : tableUpdates.getUpdates().keySet()) {
149 Map<String, Row> tCache = db.getTableCache(databaseName, tableName);
150 TableUpdate update = tableUpdates.getUpdates().get(tableName);
151 for (UUID uuid : (Set<UUID>)update.getRows().keySet()) {
153 if (update.getNew(uuid) != null) {
154 boolean isNewRow = (tCache == null || tCache.get(uuid.toString()) == null) ? true : false;
155 db.updateRow(databaseName, tableName, uuid.toString(), update.getNew(uuid));
157 this.handleOpenVSwitchSpecialCase(n, databaseName, tableName, uuid);
158 if (!ovsdbInventoryListeners.isEmpty()) {
159 for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
160 listener.rowAdded(n, tableName, uuid.toString(), update.getNew(uuid));
164 if (!ovsdbInventoryListeners.isEmpty()) {
165 for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
166 listener.rowUpdated(n, tableName, uuid.toString(), update.getOld(uuid), update.getNew(uuid));
170 } else if (update.getOld(uuid) != null){
171 if (tCache != null) {
172 if (!ovsdbInventoryListeners.isEmpty()) {
173 for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
174 listener.rowRemoved(n, tableName, uuid.toString(), update.getOld(uuid), update.getNew(uuid));
178 db.removeRow(databaseName, tableName, uuid.toString());
184 private void handleOpenVSwitchSpecialCase(final Node node, final String databaseName, final String tableName, final UUID uuid) {
185 if (OvsVswitchdSchemaConstants.shouldConfigureController(databaseName, tableName)) {
186 Runnable updateControllerRunnable = new Runnable() {
190 if (ovsdbConfigurationService != null) ovsdbConfigurationService.setOFController(node, uuid.toString());
191 } catch (InterruptedException | ExecutionException e) {
196 executor.execute(updateControllerRunnable);
201 public void printCache(Node n) {
202 if ((dbCache != null) && (!dbCache.isEmpty())) {
203 NodeDatabase db = dbCache.get(n);
205 db.printTableCache();
211 public void addNode(Node node, Set<Property> props) {
212 addNodeProperty(node, UpdateType.ADDED, props);
216 public void notifyNodeAdded(Node node, InetAddress address, int port) {
217 if (!ovsdbInventoryListeners.isEmpty()) {
218 for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
219 listener.nodeAdded(node, address, port);
225 public void addNodeProperty(Node node, UpdateType type, Set<Property> props) {
226 Map<String, Property> nProp = nodeProps.get(node);
227 if (nProp == null) nProp = new HashMap<String, Property>();
228 for (Property prop : props) {
229 nProp.put(prop.getName(), prop);
231 nodeProps.put(node, nProp);
233 * TODO: Remove following code. It updates to sal about newly added node and
234 * it's property. To move this bundle to MD-SAL we need to store this data in
235 * md-sal config/operational data store.
236 for (IPluginOutInventoryService service : pluginOutInventoryServices) {
237 service.updateNode(node, type, props);
243 public void removeNode(Node node) {
244 if (!ovsdbInventoryListeners.isEmpty()) {
245 for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
246 listener.nodeRemoved(node);
251 * TODO: Remove following code. It updates to sal about newly added node and
252 * it's property. To move this bundle to MD-SAL we need to store this data in
253 * md-sal config/operational data store.
254 for (IPluginOutInventoryService service : pluginOutInventoryServices) {
255 service.updateNode(node, UpdateType.REMOVED, null);
258 nodeProps.remove(node);
259 dbCache.remove(node);
262 private void listenerAdded(OvsdbInventoryListener listener) {
263 this.ovsdbInventoryListeners.add(listener);
266 private void listenerRemoved(OvsdbInventoryListener listener) {
267 this.ovsdbInventoryListeners.remove(listener);