4766ad45d8a01f7cdbf7208b62435a746095dbd6
[ovsdb.git] / plugin / src / main / java / org / opendaylight / ovsdb / plugin / impl / InventoryServiceImpl.java
1 /*
2  * Copyright (C) 2013 Red Hat, Inc.
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  * Authors : Madhu Venugopal, Brent Salisbury
9  */
10 package org.opendaylight.ovsdb.plugin.impl;
11
12 import java.net.InetAddress;
13 import java.util.Map;
14 import java.util.Set;
15 import java.util.concurrent.ConcurrentMap;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.Executors;
18 import java.util.concurrent.ScheduledExecutorService;
19
20 import org.opendaylight.ovsdb.lib.message.TableUpdate;
21 import org.opendaylight.ovsdb.lib.message.TableUpdates;
22 import org.opendaylight.ovsdb.lib.notation.Row;
23 import org.opendaylight.ovsdb.lib.notation.UUID;
24 import org.opendaylight.ovsdb.plugin.internal.NodeDatabase;
25 import org.opendaylight.ovsdb.plugin.api.OvsVswitchdSchemaConstants;
26 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
27 import org.opendaylight.ovsdb.plugin.api.OvsdbInventoryListener;
28 import org.opendaylight.ovsdb.plugin.api.OvsdbInventoryService;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
30
31 import com.google.common.collect.Sets;
32
33 import com.google.common.collect.Maps;
34
35 /**
36  * Stub Implementation for IPluginInReadService used by SAL
37  *
38  *
39  */
40 public class InventoryServiceImpl implements OvsdbInventoryService {
41     private ConcurrentMap<Node, NodeDatabase> dbCache = Maps.newConcurrentMap();
42     private ScheduledExecutorService executor;
43     private OvsdbConfigurationService ovsdbConfigurationService;
44
45     private Set<OvsdbInventoryListener> ovsdbInventoryListeners = Sets.newCopyOnWriteArraySet();
46
47     /**
48      * Function called by the dependency manager when all the required
49      * dependencies are satisfied
50      *
51      */
52     public void init() {
53         this.executor = Executors.newSingleThreadScheduledExecutor();
54     }
55
56     /**
57      * Function called by the dependency manager when at least one dependency
58      * become unsatisfied or when the component is shutting down because for
59      * example bundle is being stopped.
60      *
61      */
62     public void destroy() {
63     }
64
65     /**
66      * Function called by dependency manager after "init ()" is called and after
67      * the services provided by the class are registered in the service registry
68      *
69      */
70     public void start() {
71     }
72
73     /**
74      * Function called by the dependency manager before the services exported by
75      * the component are unregistered, this will be followed by a "destroy ()"
76      * calls
77      *
78      */
79     public void stop() {
80         this.executor.shutdownNow();
81     }
82
83     public void setOvsdbConfigurationService(OvsdbConfigurationService service) {
84         ovsdbConfigurationService = service;
85     }
86
87     public void unsetConfigurationService(OvsdbConfigurationService service) {
88         ovsdbConfigurationService = null;
89     }
90
91     @Override
92     public ConcurrentMap<String, ConcurrentMap<String, Row>> getCache(Node n, String databaseName) {
93         NodeDatabase db = dbCache.get(n);
94         if (db == null) {
95             return null;
96         }
97         return db.getDatabase(databaseName);
98     }
99
100
101     @Override
102     public ConcurrentMap<String, Row> getTableCache(Node n, String databaseName, String tableName) {
103         NodeDatabase db = dbCache.get(n);
104         if (db == null) {
105             return null;
106         }
107         return db.getTableCache(databaseName, tableName);
108     }
109
110
111     @Override
112     public Row getRow(Node n, String databaseName, String tableName, String uuid) {
113         NodeDatabase db = dbCache.get(n);
114         if (db == null) {
115             return null;
116         }
117         return db.getRow(databaseName, tableName, uuid);
118     }
119
120     @Override
121     public void updateRow(Node n, String databaseName, String tableName, String uuid, Row row) {
122         NodeDatabase db = dbCache.get(n);
123         if (db == null) {
124             db = new NodeDatabase();
125             dbCache.put(n, db);
126         }
127         db.updateRow(databaseName, tableName, uuid, row);
128     }
129
130     @Override
131     public void removeRow(Node n, String databaseName, String tableName, String uuid) {
132         NodeDatabase db = dbCache.get(n);
133         if (db != null) {
134             db.removeRow(databaseName, tableName, uuid);
135         }
136     }
137
138     @Override
139     public void processTableUpdates(Node n, String databaseName, TableUpdates tableUpdates) {
140         NodeDatabase db = dbCache.get(n);
141         if (db == null) {
142             db = new NodeDatabase();
143             dbCache.put(n, db);
144         }
145
146         for (String tableName : tableUpdates.getUpdates().keySet()) {
147             Map<String, Row> tCache = db.getTableCache(databaseName, tableName);
148             TableUpdate update = tableUpdates.getUpdates().get(tableName);
149             for (UUID uuid : (Set<UUID>)update.getRows().keySet()) {
150
151             if (update.getNew(uuid) != null) {
152                 boolean isNewRow = (tCache == null || tCache.get(uuid.toString()) == null) ? true : false;
153                 db.updateRow(databaseName, tableName, uuid.toString(), update.getNew(uuid));
154                 if (isNewRow) {
155                     this.handleOpenVSwitchSpecialCase(n, databaseName, tableName, uuid);
156                     if (!ovsdbInventoryListeners.isEmpty()) {
157                         for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
158                             listener.rowAdded(n, tableName, uuid.toString(), update.getNew(uuid));
159                         }
160                     }
161                 } else {
162                     if (!ovsdbInventoryListeners.isEmpty()) {
163                         for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
164                             listener.rowUpdated(n, tableName, uuid.toString(), update.getOld(uuid), update.getNew(uuid));
165                         }
166                     }
167                 }
168             } else if (update.getOld(uuid) != null){
169                 if (tCache != null) {
170                     if (!ovsdbInventoryListeners.isEmpty()) {
171                         for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
172                             listener.rowRemoved(n, tableName, uuid.toString(), update.getOld(uuid), update.getNew(uuid));
173                         }
174                     }
175                 }
176                 db.removeRow(databaseName, tableName, uuid.toString());
177             }
178             }
179         }
180     }
181
182     private void handleOpenVSwitchSpecialCase(final Node node, final String databaseName, final String tableName, final UUID uuid) {
183         if (OvsVswitchdSchemaConstants.shouldConfigureController(databaseName, tableName)) {
184             Runnable updateControllerRunnable = new Runnable() {
185                 @Override
186                 public void run() {
187                     try {
188                         if (ovsdbConfigurationService != null) {
189                             ovsdbConfigurationService.setOFController(node, uuid.toString());
190                         }
191                     } catch (InterruptedException | ExecutionException e) {
192                         e.printStackTrace();
193                     }
194                 }
195             };
196             executor.execute(updateControllerRunnable);
197         }
198     }
199
200     @Override
201     public void printCache(Node n) {
202         if ((dbCache != null) && (!dbCache.isEmpty())) {
203             NodeDatabase db = dbCache.get(n);
204             if (db != null) {
205                 db.printTableCache();
206             }
207         }
208     }
209
210     @Override
211     public void notifyNodeAdded(Node node, InetAddress address, int port) {
212         if (!ovsdbInventoryListeners.isEmpty()) {
213             for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
214                 listener.nodeAdded(node, address, port);
215             }
216         }
217     }
218
219     @Override
220     public void removeNode(Node node) {
221         if (!ovsdbInventoryListeners.isEmpty()) {
222             for (OvsdbInventoryListener listener : ovsdbInventoryListeners) {
223                 listener.nodeRemoved(node);
224             }
225         }
226
227         dbCache.remove(node);
228     }
229
230     private void listenerAdded(OvsdbInventoryListener listener) {
231         this.ovsdbInventoryListeners.add(listener);
232     }
233
234     private void listenerRemoved(OvsdbInventoryListener listener) {
235         this.ovsdbInventoryListeners.remove(listener);
236     }
237 }