YuanyouZhang
Committed by Gerrit Code Review

[ONOS-2162][ONOS-2259]-- OVSDB- The implementation of OvsdbProviderService

and OvsdbClientService.

Change-Id: I3e04d7c111adf16201f8ad7ec732eb81de05b960
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
31 <artifactId>netty-transport-native-epoll</artifactId> 31 <artifactId>netty-transport-native-epoll</artifactId>
32 <version>${netty4.version}</version> 32 <version>${netty4.version}</version>
33 </dependency> 33 </dependency>
34 + <dependency>
35 + <groupId>org.onosproject</groupId>
36 + <artifactId>onos-ovsdb-rfc</artifactId>
37 + <version>${project.version}</version>
38 + </dependency>
34 </dependencies> 39 </dependencies>
35 40
36 </project> 41 </project>
......
...@@ -15,14 +15,24 @@ ...@@ -15,14 +15,24 @@
15 */ 15 */
16 package org.onosproject.ovsdb.controller; 16 package org.onosproject.ovsdb.controller;
17 17
18 +import java.util.List;
18 import java.util.Set; 19 import java.util.Set;
19 20
20 import org.onlab.packet.IpAddress; 21 import org.onlab.packet.IpAddress;
21 22
23 +import org.onosproject.ovsdb.rfc.jsonrpc.OvsdbRPC;
24 +import org.onosproject.ovsdb.rfc.message.OperationResult;
25 +import org.onosproject.ovsdb.rfc.message.TableUpdates;
26 +import org.onosproject.ovsdb.rfc.notation.Row;
27 +import org.onosproject.ovsdb.rfc.operations.Operation;
28 +import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
29 +
30 +import com.google.common.util.concurrent.ListenableFuture;
31 +
22 /** 32 /**
23 * Represents to provider facing side of a node. 33 * Represents to provider facing side of a node.
24 */ 34 */
25 -public interface OvsdbClientService { 35 +public interface OvsdbClientService extends OvsdbRPC {
26 /** 36 /**
27 * Gets the node identifier. 37 * Gets the node identifier.
28 * 38 *
...@@ -104,4 +114,111 @@ public interface OvsdbClientService { ...@@ -104,4 +114,111 @@ public interface OvsdbClientService {
104 */ 114 */
105 boolean isConnected(); 115 boolean isConnected();
106 116
117 + /**
118 + * Gets the Bridge uuid.
119 + *
120 + * @param bridgeName bridge name
121 + * @return bridge uuid, empty if no uuid is find
122 + */
123 + String getBridgeUuid(String bridgeName);
124 +
125 + /**
126 + * Gets the Port uuid.
127 + *
128 + * @param portName port name
129 + * @param bridgeUuid bridge uuid
130 + * @return port uuid, empty if no uuid is find
131 + */
132 + String getPortUuid(String portName, String bridgeUuid);
133 +
134 + /**
135 + * Gets the Interface uuid.
136 + *
137 + * @param portUuid port uuid
138 + * @param portName port name
139 + * @return interface uuid, empty if no uuid is find
140 + */
141 + String getInterfaceUuid(String portUuid, String portName);
142 +
143 + /**
144 + * Gets the Controller uuid.
145 + *
146 + * @param controllerName controller name
147 + * @param controllerTarget controller target
148 + * @return controller uuid, empty if no uuid is find
149 + */
150 + String getControllerUuid(String controllerName, String controllerTarget);
151 +
152 + /**
153 + * Gets the Ovs uuid.
154 + *
155 + * @param dbName database name
156 + * @return ovs uuid, empty if no uuid is find
157 + */
158 + String getOvsUuid(String dbName);
159 +
160 + /**
161 + * Gets the ovsdb database schema.
162 + *
163 + * @param dbName database name
164 + * @return database schema
165 + */
166 + ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName);
167 +
168 + /**
169 + * Gets the ovsdb table updates.
170 + *
171 + * @param dbName database name
172 + * @param id random uuid
173 + * @return table updates
174 + */
175 + ListenableFuture<TableUpdates> monitorTables(String dbName, String id);
176 +
177 + /**
178 + * Gets the ovsdb config operation result.
179 + *
180 + * @param dbName database name
181 + * @param operations the list of operations
182 + * @return operation results
183 + */
184 + ListenableFuture<List<OperationResult>> transactConfig(String dbName,
185 + List<Operation> operations);
186 +
187 + /**
188 + * Gets the ovsdb database schema from local.
189 + *
190 + * @param dbName database name
191 + * @return database schema
192 + */
193 + DatabaseSchema getDatabaseSchema(String dbName);
194 +
195 + /**
196 + * Gets the ovsdb row from the local ovsdb store.
197 + *
198 + * @param dbName database name
199 + * @param tableName table name
200 + * @param uuid row uuid
201 + * @return row ovsdb row
202 + */
203 + Row getRow(String dbName, String tableName, String uuid);
204 +
205 + /**
206 + * Removes the ovsdb row from the local ovsdb store.
207 + *
208 + * @param dbName database name
209 + * @param tableName table name
210 + * @param uuid row uuid
211 + */
212 + void removeRow(String dbName, String tableName, String uuid);
213 +
214 + /**
215 + * Update the local ovsdb store.
216 + *
217 + * @param dbName database name
218 + * @param tableName table name
219 + * @param uuid row uuid
220 + * @param row ovsdb row
221 + */
222 + void updateOvsdbStore(String dbName, String tableName, String uuid, Row row);
223 +
107 } 224 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.ovsdb.controller;
17 +
18 +/**
19 + * Ovsdb related constants.
20 + */
21 +public final class OvsdbConstant {
22 +
23 + /**
24 + * Default constructor.
25 + *
26 + * The constructor is private to prevent creating an instance of this
27 + * utility class.
28 + */
29 + private OvsdbConstant() {
30 + }
31 +
32 + /** Ovsdb database Open_vSwitch. */
33 + public static final String DATABASENAME = "Open_vSwitch";
34 +
35 + /** Ovsdb table Bridge. */
36 + public static final String BRIDGE = "Bridge";
37 +
38 + /** Ovsdb table Interface. */
39 + public static final String INTERFACE = "Interface";
40 +
41 + /** Ovsdb table Controller. */
42 + public static final String CONTROLLER = "Controller";
43 +
44 + /** Ovsdb table Port. */
45 + public static final String PORT = "Port";
46 +
47 + /** Ovsdb bridge name. */
48 + public static final String INTEGRATION_BRIDGE = "br-int";
49 +
50 + /** Ovsdb vxlan tunnel type. */
51 + public static final String TYPEVXLAN = "vxlan";
52 +
53 + /** Openflow version. */
54 + public static final String OPENFLOW13 = "OpenFlow13";
55 +
56 + /** Ovsdb external_id_interface_id.. */
57 + public static final String EXTERNAL_ID_INTERFACE_ID = "iface-id";
58 +
59 + /** Ovsdb external_id_vm_mac. */
60 + public static final String EXTERNAL_ID_VM_MAC = "attached-mac";
61 +
62 + /** Openflow port. */
63 + public static final int OFPORT = 6633;
64 +
65 + /** Ovsdb port. */
66 + public static final int OVSDBPORT = 6640;
67 +
68 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.ovsdb.controller;
17 +
18 +import java.util.concurrent.ConcurrentMap;
19 +
20 +import org.onosproject.ovsdb.rfc.notation.Row;
21 +
22 +import com.google.common.collect.Maps;
23 +
24 +/**
25 + * The class representing a table data.
26 + */
27 +public class OvsdbRowStore {
28 +
29 + private final ConcurrentMap<String, Row> rowStore = Maps.newConcurrentMap();
30 +
31 + /**
32 + * Gets the row.
33 + *
34 + * @param uuid the key of the rowStore
35 + * @return row the row of the rowStore
36 + */
37 + public Row getRow(String uuid) {
38 + return rowStore.get(uuid);
39 + }
40 +
41 + /**
42 + * Inserts a row to rowStore.
43 + *
44 + * @param uuid key of the row
45 + * @param row a row of the table
46 + */
47 + public void insertRow(String uuid, Row row) {
48 + rowStore.put(uuid, row);
49 + }
50 +
51 + /**
52 + * Deletes a row to rowStore.
53 + *
54 + * @param uuid key of the row
55 + */
56 + public void deleteRow(String uuid) {
57 + rowStore.remove(uuid);
58 + }
59 +
60 + /**
61 + * Gets the rowStore.
62 + *
63 + * @return rowStore
64 + */
65 + public ConcurrentMap<String, Row> getRowStore() {
66 + return rowStore;
67 + }
68 +
69 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.ovsdb.controller;
17 +
18 +import java.util.concurrent.ConcurrentMap;
19 +
20 +import com.google.common.collect.Maps;
21 +
22 +/**
23 + * The cache for local ovsdb database.
24 + */
25 +public class OvsdbStore {
26 +
27 + private final ConcurrentMap<String, OvsdbTableStore> ovsdbStore = Maps.newConcurrentMap();
28 +
29 + /**
30 + * Gets the OvsdbTableStore.
31 + *
32 + * @param dbName ovsdb database name
33 + * @return tableStore OvsdbTableStore
34 + */
35 + public OvsdbTableStore getOvsdbTableStore(String dbName) {
36 + OvsdbTableStore tableStore = ovsdbStore.get(dbName);
37 + if (tableStore == null) {
38 + return null;
39 + }
40 + return tableStore;
41 + }
42 +
43 + /**
44 + * Create or Update a value to ovsdbStore.
45 + *
46 + * @param dbName ovsdb database name
47 + * @param tableStore a database tableStore.
48 + */
49 + public void createOrUpdateOvsdbStore(String dbName, OvsdbTableStore tableStore) {
50 + ovsdbStore.put(dbName, tableStore);
51 + }
52 +
53 + /**
54 + * Drops a value to rowStore.
55 + *
56 + * @param dbName ovsdb database name
57 + */
58 + public void dropOvsdbStore(String dbName) {
59 + ovsdbStore.remove(dbName);
60 + }
61 +
62 + /**
63 + * Gets the ovsdbStore.
64 + *
65 + * @return ovsdbStore
66 + */
67 + public ConcurrentMap<String, OvsdbTableStore> getOvsdbStore() {
68 + return ovsdbStore;
69 + }
70 +
71 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.ovsdb.controller;
17 +
18 +import java.util.concurrent.ConcurrentMap;
19 +
20 +import com.google.common.collect.Maps;
21 +
22 +/**
23 + * The class representing a database data.
24 + */
25 +public class OvsdbTableStore {
26 +
27 + private final ConcurrentMap<String, OvsdbRowStore> tableStore = Maps.newConcurrentMap();
28 +
29 + /**
30 + * Gets the ovsdbRowStore.
31 + *
32 + * @param tableName a ovsdb table name
33 + * @return OvsdbRowStore the data of the table
34 + */
35 + public OvsdbRowStore getRows(String tableName) {
36 + return tableStore.get(tableName);
37 + }
38 +
39 + /**
40 + * Create or update a value to tableStore.
41 + *
42 + * @param tableName key of the tableName
43 + * @param rowStore a row of the table
44 + */
45 + public void createOrUpdateTable(String tableName, OvsdbRowStore rowStore) {
46 + tableStore.put(tableName, rowStore);
47 + }
48 +
49 + /**
50 + * Drops a value to table data.
51 + *
52 + * @param tableName key of the tableName
53 + */
54 + public void dropTable(String tableName) {
55 + tableStore.remove(tableName);
56 + }
57 +
58 + /**
59 + * Gets the tableStore.
60 + *
61 + * @return tableStore
62 + */
63 + public ConcurrentMap<String, OvsdbRowStore> getTableStore() {
64 + return tableStore;
65 + }
66 +
67 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.ovsdb.controller.driver;
17 +
18 +import io.netty.channel.Channel;
19 +
20 +import java.net.InetSocketAddress;
21 +import java.util.ArrayList;
22 +import java.util.HashSet;
23 +import java.util.List;
24 +import java.util.Map;
25 +import java.util.Set;
26 +import java.util.concurrent.ConcurrentMap;
27 +import java.util.concurrent.ExecutionException;
28 +
29 +import org.onlab.packet.IpAddress;
30 +import org.onosproject.ovsdb.controller.OvsdbBridge;
31 +import org.onosproject.ovsdb.controller.OvsdbClientService;
32 +import org.onosproject.ovsdb.controller.OvsdbConstant;
33 +import org.onosproject.ovsdb.controller.OvsdbNodeId;
34 +import org.onosproject.ovsdb.controller.OvsdbPort;
35 +import org.onosproject.ovsdb.controller.OvsdbRowStore;
36 +import org.onosproject.ovsdb.controller.OvsdbStore;
37 +import org.onosproject.ovsdb.controller.OvsdbTableStore;
38 +import org.onosproject.ovsdb.controller.OvsdbTunnel;
39 +import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
40 +import org.onosproject.ovsdb.rfc.message.OperationResult;
41 +import org.onosproject.ovsdb.rfc.message.TableUpdates;
42 +import org.onosproject.ovsdb.rfc.notation.Condition;
43 +import org.onosproject.ovsdb.rfc.notation.Mutation;
44 +import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
45 +import org.onosproject.ovsdb.rfc.notation.Row;
46 +import org.onosproject.ovsdb.rfc.notation.UUID;
47 +import org.onosproject.ovsdb.rfc.operations.Delete;
48 +import org.onosproject.ovsdb.rfc.operations.Insert;
49 +import org.onosproject.ovsdb.rfc.operations.Mutate;
50 +import org.onosproject.ovsdb.rfc.operations.Operation;
51 +import org.onosproject.ovsdb.rfc.operations.Update;
52 +import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
53 +import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
54 +import org.onosproject.ovsdb.rfc.schema.TableSchema;
55 +import org.onosproject.ovsdb.rfc.table.Bridge;
56 +import org.onosproject.ovsdb.rfc.table.Controller;
57 +import org.onosproject.ovsdb.rfc.table.Interface;
58 +import org.onosproject.ovsdb.rfc.table.OpenVSwitch;
59 +import org.onosproject.ovsdb.rfc.table.OvsdbTable;
60 +import org.onosproject.ovsdb.rfc.table.Port;
61 +import org.onosproject.ovsdb.rfc.table.TableGenerator;
62 +import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
63 +import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
64 +import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
65 +import org.onosproject.ovsdb.rfc.utils.MutationUtil;
66 +import org.slf4j.Logger;
67 +import org.slf4j.LoggerFactory;
68 +
69 +import com.fasterxml.jackson.databind.JsonNode;
70 +import com.google.common.base.Function;
71 +import com.google.common.collect.Lists;
72 +import com.google.common.collect.Maps;
73 +import com.google.common.util.concurrent.Futures;
74 +import com.google.common.util.concurrent.ListenableFuture;
75 +import com.google.common.util.concurrent.SettableFuture;
76 +
77 +/**
78 + * An representation of an ovsdb client.
79 + */
80 +public class DefaultOvsdbClient
81 + implements OvsdbProviderService, OvsdbClientService {
82 +
83 + private final Logger log = LoggerFactory
84 + .getLogger(DefaultOvsdbClient.class);
85 +
86 + private Channel channel;
87 +
88 + private OvsdbAgent agent;
89 + private boolean connected;
90 + private OvsdbNodeId nodeId;
91 + private Callback monitorCallBack;
92 +
93 + private OvsdbStore ovsdbStore = new OvsdbStore();
94 +
95 + private final Map<String, String> requestMethod = Maps.newHashMap();
96 + private final Map<String, SettableFuture<? extends Object>> requestResult = Maps
97 + .newHashMap();
98 +
99 + private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
100 + private final Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
101 + private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
102 + private final Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
103 +
104 + /**
105 + * Creates an OvsdbClient.
106 + *
107 + * @param nodeId ovsdb node id
108 + */
109 + public DefaultOvsdbClient(OvsdbNodeId nodeId) {
110 + this.nodeId = nodeId;
111 + }
112 +
113 + @Override
114 + public OvsdbNodeId nodeId() {
115 + return nodeId;
116 + }
117 +
118 + @Override
119 + public void setAgent(OvsdbAgent agent) {
120 + if (this.agent == null) {
121 + this.agent = agent;
122 + }
123 + }
124 +
125 + @Override
126 + public void setChannel(Channel channel) {
127 + this.channel = channel;
128 + }
129 +
130 + @Override
131 + public void setConnection(boolean connected) {
132 + this.connected = connected;
133 + }
134 +
135 + @Override
136 + public boolean isConnected() {
137 + return this.connected;
138 + }
139 +
140 + @Override
141 + public void nodeAdded() {
142 + this.agent.addConnectedNode(nodeId, this);
143 + }
144 +
145 + @Override
146 + public void nodeRemoved() {
147 + this.agent.removeConnectedNode(nodeId);
148 + channel.disconnect();
149 + }
150 +
151 + /**
152 + * Gets the ovsdb table store.
153 + *
154 + * @param dbName the ovsdb database name
155 + * @return ovsTableStore, empty if table store is find
156 + */
157 + private OvsdbTableStore getTableStore(String dbName) {
158 + if (ovsdbStore == null) {
159 + return null;
160 + }
161 + return ovsdbStore.getOvsdbTableStore(dbName);
162 + }
163 +
164 + /**
165 + * Gets the ovsdb row store.
166 + *
167 + * @param dbName the ovsdb database name
168 + * @param tableName the ovsdb table name
169 + *
170 + * @return ovsRowStore, empty if row store is find
171 + */
172 + private OvsdbRowStore getRowStore(String dbName, String tableName) {
173 + OvsdbTableStore tableStore = getTableStore(dbName);
174 + if (tableStore == null) {
175 + return null;
176 + }
177 + return tableStore.getRows(tableName);
178 + }
179 +
180 + /**
181 + * Gets the ovsdb row.
182 + *
183 + * @param dbName the ovsdb database name
184 + * @param tableName the ovsdb table name
185 + * @param uuid the key of the row
186 + * @return row, empty if row is find
187 + */
188 + @Override
189 + public Row getRow(String dbName, String tableName, String uuid) {
190 + OvsdbTableStore tableStore = getTableStore(dbName);
191 + if (tableStore == null) {
192 + return null;
193 + }
194 + OvsdbRowStore rowStore = tableStore.getRows(tableName);
195 + if (rowStore == null) {
196 + return null;
197 + }
198 + return rowStore.getRow(uuid);
199 + }
200 +
201 + @Override
202 + public void removeRow(String dbName, String tableName, String uuid) {
203 + OvsdbTableStore tableStore = getTableStore(dbName);
204 + if (tableStore == null) {
205 + return;
206 + }
207 + OvsdbRowStore rowStore = tableStore.getRows(tableName);
208 + if (rowStore == null) {
209 + return;
210 + }
211 + rowStore.deleteRow(uuid);
212 + }
213 +
214 + @Override
215 + public void updateOvsdbStore(String dbName, String tableName, String uuid,
216 + Row row) {
217 + OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
218 + if (tableStore == null) {
219 + tableStore = new OvsdbTableStore();
220 + }
221 + OvsdbRowStore rowStore = tableStore.getRows(tableName);
222 + if (rowStore == null) {
223 + rowStore = new OvsdbRowStore();
224 + }
225 + rowStore.insertRow(uuid, row);
226 + tableStore.createOrUpdateTable(tableName, rowStore);
227 + ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
228 + }
229 +
230 + @Override
231 + public String getPortUuid(String portName, String bridgeUuid) {
232 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
233 +
234 + Row bridgeRow = getRow(OvsdbConstant.DATABASENAME,
235 + OvsdbConstant.BRIDGE, bridgeUuid);
236 +
237 + Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
238 + OvsdbTable.BRIDGE);
239 + if (bridge != null) {
240 + OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
241 + @SuppressWarnings("unchecked")
242 + Set<UUID> ports = setPorts.set();
243 + if (ports == null || ports.size() == 0) {
244 + log.warn("The port uuid is null");
245 + return null;
246 + }
247 +
248 + for (UUID uuid : ports) {
249 + Row portRow = getRow(OvsdbConstant.DATABASENAME,
250 + OvsdbConstant.PORT, uuid.value());
251 + if (portRow == null) {
252 + continue;
253 + }
254 + Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
255 + OvsdbTable.PORT);
256 + if (port != null && portName.equalsIgnoreCase(port.getName())) {
257 + return uuid.value();
258 + }
259 + }
260 +
261 + }
262 + return null;
263 + }
264 +
265 + @Override
266 + public String getInterfaceUuid(String portUuid, String portName) {
267 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
268 +
269 + Row portRow = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.PORT,
270 + portUuid);
271 + Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
272 + OvsdbTable.PORT);
273 +
274 + if (port != null) {
275 + OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
276 + @SuppressWarnings("unchecked")
277 + Set<UUID> interfaces = setInterfaces.set();
278 +
279 + if (interfaces == null || interfaces.size() == 0) {
280 + log.warn("The interface uuid is null");
281 + return null;
282 + }
283 +
284 + for (UUID uuid : interfaces) {
285 + Row intfRow = getRow(OvsdbConstant.DATABASENAME,
286 + OvsdbConstant.INTERFACE, uuid.value());
287 + if (intfRow == null) {
288 + continue;
289 + }
290 + Interface intf = (Interface) TableGenerator
291 + .getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
292 + if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
293 + return uuid.value();
294 + }
295 + }
296 +
297 + }
298 +
299 + return null;
300 + }
301 +
302 + @Override
303 + public String getBridgeUuid(String bridgeName) {
304 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
305 +
306 + OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
307 + OvsdbConstant.BRIDGE);
308 + if (rowStore == null) {
309 + log.debug("The bridge uuid is null");
310 + return null;
311 + }
312 +
313 + ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
314 + if (bridgeTableRows == null) {
315 + log.debug("The bridge uuid is null");
316 + return null;
317 + }
318 +
319 + for (String uuid : bridgeTableRows.keySet()) {
320 + Bridge bridge = (Bridge) TableGenerator
321 + .getTable(dbSchema, bridgeTableRows.get(uuid),
322 + OvsdbTable.BRIDGE);
323 +
324 + if (bridge.getName().equals(bridgeName)) {
325 + return uuid;
326 + }
327 +
328 + }
329 + return null;
330 + }
331 +
332 + @Override
333 + public String getControllerUuid(String controllerName,
334 + String controllerTarget) {
335 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
336 + OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
337 + OvsdbConstant.CONTROLLER);
338 + if (rowStore == null) {
339 + log.debug("The controller uuid is null");
340 + return null;
341 + }
342 +
343 + ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
344 + if (controllerTableRows != null) {
345 + for (String uuid : controllerTableRows.keySet()) {
346 +
347 + Controller controller = (Controller) TableGenerator
348 + .getTable(dbSchema, controllerTableRows.get(uuid),
349 + OvsdbTable.CONTROLLER);
350 + String target = (String) controller.getTargetColumn().data();
351 + if (target.equalsIgnoreCase(controllerTarget)) {
352 + return uuid;
353 + }
354 +
355 + }
356 + }
357 + return null;
358 + }
359 +
360 + @Override
361 + public String getOvsUuid(String dbName) {
362 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
363 + OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
364 + OvsdbConstant.DATABASENAME);
365 + if (rowStore == null) {
366 + log.debug("The bridge uuid is null");
367 + return null;
368 + }
369 + ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
370 +
371 + if (ovsTableRows != null) {
372 +
373 + for (String uuid : ovsTableRows.keySet()) {
374 +
375 + OpenVSwitch ovs = (OpenVSwitch) TableGenerator
376 + .getTable(dbSchema, ovsTableRows.get(uuid),
377 + OvsdbTable.OPENVSWITCH);
378 +
379 + if (((TableSchema) ovs.getTbSchema()).name().equals(dbName)) {
380 + return uuid;
381 + }
382 + }
383 +
384 + }
385 +
386 + return null;
387 + }
388 +
389 + @Override
390 + public void createPort(String bridgeName, String portName) {
391 + String bridgeUuid = getBridgeUuid(bridgeName);
392 + if (bridgeUuid == null) {
393 + log.error("Can't find bridge {} in {}", bridgeName,
394 + nodeId.getIpAddress());
395 + return;
396 + }
397 +
398 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
399 + String portUuid = getPortUuid(portName, bridgeUuid);
400 +
401 + Port port = (Port) TableGenerator
402 + .createTable(dbSchema, OvsdbTable.PORT);
403 +
404 + port.setName(portName);
405 + if (portUuid == null) {
406 + insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
407 + "ports", bridgeUuid, port.getRow());
408 + } else {
409 + updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
410 + }
411 +
412 + return;
413 + }
414 +
415 + @Override
416 + public void dropPort(String bridgeName, String portName) {
417 + String bridgeUuid = getBridgeUuid(bridgeName);
418 + if (bridgeUuid == null) {
419 + log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
420 + return;
421 + }
422 +
423 + String portUuid = getPortUuid(portName, bridgeUuid);
424 + if (portUuid != null) {
425 + log.info("Port {} delete", portName);
426 + deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
427 + OvsdbConstant.BRIDGE, "ports");
428 + }
429 + }
430 +
431 + @Override
432 + public void createBridge(String bridgeName) {
433 + log.debug("create bridge {}", bridgeName);
434 +
435 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
436 + if (dbSchema == null) {
437 + log.warn("The schema is null");
438 + return;
439 + }
440 +
441 + Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
442 + OvsdbTable.BRIDGE);
443 + if (bridge == null) {
444 + log.debug("Can not create bridge");
445 + return;
446 + }
447 +
448 + Set<String> failModes = new HashSet<>();
449 + failModes.add("secure");
450 + bridge.setFailMode(failModes);
451 +
452 + Set<String> protocols = new HashSet<>();
453 + protocols.add(OvsdbConstant.OPENFLOW13);
454 + bridge.setProtocols(protocols);
455 +
456 + String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
457 + if (ovsUuid == null) {
458 + log.warn("The Open_vSwitch is null");
459 + return;
460 + }
461 +
462 + String bridgeUuid = getBridgeUuid(bridgeName);
463 + if (bridgeUuid == null) {
464 + log.debug("Create a new bridge");
465 +
466 + bridge.setName(bridgeName);
467 + bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
468 + OvsdbConstant.DATABASENAME, "bridges",
469 + ovsUuid, bridge.getRow());
470 +
471 + if (bridgeUuid != null) {
472 + Port port = (Port) TableGenerator.createTable(dbSchema,
473 + OvsdbTable.PORT);
474 + if (port != null) {
475 + log.debug("the port is not null");
476 + port.setName(bridgeName);
477 +
478 + insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
479 + port.getRow());
480 + }
481 + }
482 +
483 + } else {
484 + log.info("Update a bridge");
485 + updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
486 + }
487 +
488 + setController(bridgeUuid);
489 + log.info("Create bridge success");
490 + }
491 +
492 + /**
493 + * Sets the Controller.
494 + *
495 + * @param bridgeUuid bridge uuid
496 + */
497 + private void setController(String bridgeUuid) {
498 + String controllerUuid = null;
499 + String iPAddress = IpAddress.valueOf(((InetSocketAddress) channel
500 + .localAddress())
501 + .getAddress()
502 + .getHostAddress())
503 + .toString();
504 +
505 + String target = "tcp:" + iPAddress + ":" + OvsdbConstant.OFPORT;
506 + log.debug("controller IP {}: port {}", iPAddress, OvsdbConstant.OFPORT);
507 +
508 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
509 + Controller controller = (Controller) TableGenerator
510 + .createTable(dbSchema, OvsdbTable.CONTROLLER);
511 +
512 + if (controller != null) {
513 + controller.setTarget(target);
514 + controllerUuid = getControllerUuid(OvsdbConstant.CONTROLLER, target);
515 + if (controllerUuid == null) {
516 +
517 + insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
518 + OvsdbConstant.BRIDGE, "controller", bridgeUuid,
519 + controller.getRow());
520 +
521 + } else {
522 +
523 + Bridge bridge = (Bridge) TableGenerator
524 + .createTable(dbSchema, OvsdbTable.BRIDGE);
525 + Set<UUID> controllerUuids = new HashSet<>();
526 + controllerUuids.add(UUID.uuid(controllerUuid));
527 + bridge.setController(controllerUuids);
528 + updateConfig(OvsdbConstant.CONTROLLER, "_uuid", bridgeUuid, bridge.getRow());
529 +
530 + }
531 + }
532 +
533 + }
534 +
535 + @Override
536 + public void dropBridge(String bridgeName) {
537 + String bridgeUUID = getBridgeUuid(bridgeName);
538 + if (bridgeUUID == null) {
539 + log.warn("Could not find bridge in node", nodeId.getIpAddress());
540 + return;
541 + }
542 + deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUUID,
543 + OvsdbConstant.DATABASENAME, "bridges");
544 + }
545 +
546 + @Override
547 + public void createTunnel(IpAddress srcIp, IpAddress dstIp) {
548 + String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
549 + if (bridgeUuid == null) {
550 + log.warn("Could not find bridge {} and Could not create tunnel. ",
551 + OvsdbConstant.INTEGRATION_BRIDGE);
552 + return;
553 + }
554 +
555 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
556 + String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
557 + String portUuid = getPortUuid(portName, bridgeUuid);
558 +
559 + Port port = (Port) TableGenerator
560 + .createTable(dbSchema, OvsdbTable.PORT);
561 + if (port != null) {
562 + port.setName(portName);
563 + }
564 +
565 + if (portUuid == null) {
566 + portUuid = insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
567 + "ports", bridgeUuid, port.getRow());
568 + } else {
569 + updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
570 + }
571 +
572 + // When a tunnel is created, A row is inserted into port table and
573 + // interface table of the ovsdb node.
574 + // and the following step is to get the interface uuid from local store
575 + // in controller node.
576 + // but it need spend some time synchronising data between node and
577 + // controller.
578 + // so loop to judge if interfaceUUid is null is necessary.
579 + String interfaceUuid = null;
580 + for (int i = 0; i < 10; i++) {
581 + interfaceUuid = getInterfaceUuid(portUuid, portName);
582 + if (interfaceUuid == null) {
583 + try {
584 + Thread.sleep(500);
585 + } catch (InterruptedException e) {
586 + log.warn("Interrupted while waiting to get interfaceUuid");
587 + Thread.currentThread().interrupt();
588 + }
589 + } else {
590 + break;
591 + }
592 + }
593 +
594 + if (interfaceUuid != null) {
595 + OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
596 + OvsdbConstant.INTERFACE);
597 + if (rowStore == null) {
598 + log.debug("The bridge uuid is null");
599 + return;
600 + }
601 +
602 + ConcurrentMap<String, Row> intfTableRows = rowStore.getRowStore();
603 + if (intfTableRows == null) {
604 + log.debug("The bridge uuid is null");
605 + return;
606 + }
607 +
608 + Interface tunInterface = (Interface) TableGenerator
609 + .getTable(dbSchema, intfTableRows.get(interfaceUuid),
610 + OvsdbTable.INTERFACE);
611 + if (tunInterface != null) {
612 +
613 + tunInterface.setType(OvsdbConstant.TYPEVXLAN);
614 + Map<String, String> options = Maps.newHashMap();
615 + options.put("key", "flow");
616 + options.put("local_ip", srcIp.toString());
617 + options.put("remote_ip", dstIp.toString());
618 + tunInterface.setOptions(options);
619 + updateConfig(OvsdbConstant.INTERFACE, "_uuid", interfaceUuid,
620 + tunInterface.getRow());
621 + log.info("Tunnel added success", tunInterface);
622 +
623 + }
624 + }
625 +
626 + return;
627 + }
628 +
629 + @Override
630 + public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
631 + String bridgeName = OvsdbConstant.INTEGRATION_BRIDGE;
632 + String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
633 + String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
634 + if (bridgeUuid == null) {
635 + log.warn("Could not find bridge {} in {}", bridgeName,
636 + nodeId.getIpAddress());
637 + return;
638 + }
639 +
640 + String portUUID = getPortUuid(portName, bridgeUuid);
641 + if (portUUID != null) {
642 + log.info("Delete tunnel");
643 + deleteConfig(OvsdbConstant.PORT, "_uuid", portUUID,
644 + OvsdbConstant.BRIDGE, "ports");
645 + }
646 +
647 + return;
648 + }
649 +
650 + /**
651 + * Delete transact config.
652 + *
653 + * @param childTableName child table name
654 + * @param childColumnName child column name
655 + * @param childRowUuid child row uuid
656 + * @param parentTableName parent table name
657 + * @param parentColumnName parent column
658 + *
659 + */
660 + private void deleteConfig(String childTableName, String childColumnName,
661 + String childUuid, String parentTableName,
662 + String parentColumnName) {
663 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
664 + TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
665 +
666 + ArrayList<Operation> operations = Lists.newArrayList();
667 + if (parentTableName != null && parentColumnName != null) {
668 + TableSchema parentTableSchema = dbSchema
669 + .getTableSchema(parentTableName);
670 + ColumnSchema parentColumnSchema = parentTableSchema
671 + .getColumnSchema(parentColumnName);
672 + List<Mutation> mutations = Lists.newArrayList();
673 + Mutation mutation = MutationUtil.delete(parentColumnSchema.name(),
674 + UUID.uuid(childUuid));
675 + mutations.add(mutation);
676 + List<Condition> conditions = Lists.newArrayList();
677 + Condition condition = ConditionUtil.includes(parentColumnName,
678 + UUID.uuid(childUuid));
679 + conditions.add(condition);
680 + Mutate op = new Mutate(parentTableSchema, conditions, mutations);
681 + operations.add(op);
682 + }
683 +
684 + List<Condition> conditions = Lists.newArrayList();
685 + Condition condition = ConditionUtil.equals(childColumnName, UUID.uuid(childUuid));
686 + conditions.add(condition);
687 + Delete del = new Delete(childTableSchema, conditions);
688 + operations.add(del);
689 + transactConfig(OvsdbConstant.DATABASENAME, operations);
690 +
691 + return;
692 + }
693 +
694 + /**
695 + * Update transact config.
696 + *
697 + * @param tableName table name
698 + * @param columnName column name
699 + * @param uuid uuid
700 + * @param row the config data
701 + *
702 + */
703 + private void updateConfig(String tableName, String columnName, String uuid,
704 + Row row) {
705 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
706 + TableSchema tableSchema = dbSchema.getTableSchema(tableName);
707 +
708 + List<Condition> conditions = Lists.newArrayList();
709 + Condition condition = ConditionUtil.equals(columnName, UUID.uuid(uuid));
710 + conditions.add(condition);
711 +
712 + Update update = new Update(tableSchema, row, conditions);
713 +
714 + ArrayList<Operation> operations = Lists.newArrayList();
715 + operations.add(update);
716 +
717 + transactConfig(OvsdbConstant.DATABASENAME, operations);
718 + }
719 +
720 + /**
721 + * Insert transact config.
722 + *
723 + * @param childTable child table name
724 + * @param childColumnName child column name
725 + * @param childRowUuid child row uuid
726 + * @param parentTableName parent table name
727 + * @param parentColumnName parent column
728 + * @param row the config data
729 + *
730 + * @return uuid, empty if no uuid is find
731 + */
732 + private String insertConfig(String childtableName, String childColumnName,
733 + String parentTableName, String parentColumnName,
734 + String parentUuid, Row row) {
735 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
736 + TableSchema tableSchema = dbSchema.getTableSchema(childtableName);
737 +
738 + String namedUuid = childtableName;
739 + Insert insert = new Insert(tableSchema, namedUuid, row);
740 +
741 + ArrayList<Operation> operations = Lists.newArrayList();
742 + operations.add(insert);
743 +
744 + if (parentTableName != null && parentColumnName != null) {
745 + TableSchema parentTableSchema = dbSchema
746 + .getTableSchema(parentTableName);
747 + ColumnSchema parentColumnSchema = parentTableSchema
748 + .getColumnSchema(parentColumnName);
749 +
750 + List<Mutation> mutations = Lists.newArrayList();
751 + Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
752 + UUID.uuid(namedUuid));
753 + mutations.add(mutation);
754 +
755 + List<Condition> conditions = Lists.newArrayList();
756 + Condition condition = ConditionUtil.equals("_uuid",
757 + UUID.uuid(parentUuid));
758 + conditions.add(condition);
759 +
760 + Mutate op = new Mutate(parentTableSchema, conditions, mutations);
761 + operations.add(op);
762 + }
763 + if (childtableName.equalsIgnoreCase(OvsdbConstant.PORT)) {
764 + log.info("Handle port insert");
765 + Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE,
766 + row);
767 +
768 + if (intfInsert != null) {
769 + operations.add(intfInsert);
770 + }
771 +
772 + Insert ins = (Insert) operations.get(0);
773 + ins.getRow().put("interfaces",
774 + UUID.uuid(OvsdbConstant.INTERFACE));
775 + }
776 +
777 + List<OperationResult> results;
778 + try {
779 + results = transactConfig(OvsdbConstant.DATABASENAME, operations)
780 + .get();
781 +
782 + return results.get(0).getUuid().value();
783 + } catch (InterruptedException e) {
784 + log.warn("Interrupted while waiting to get result");
785 + Thread.currentThread().interrupt();
786 + } catch (ExecutionException e) {
787 + log.error("Exception thrown while to get result");
788 + }
789 +
790 + return null;
791 + }
792 +
793 + /**
794 + * Handles port insert.
795 + *
796 + * @param tableName ovsdb table interface
797 + * @param portRow row of port
798 + *
799 + * @return insert, empty if null
800 + */
801 + private Insert handlePortInsertTable(String tableName, Row portRow) {
802 + DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
803 +
804 + TableSchema portTableSchema = dbSchema
805 + .getTableSchema(OvsdbConstant.PORT);
806 + ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
807 +
808 + String portName = (String) portRow.getColumn(portColumnSchema).data();
809 +
810 + Interface inf = (Interface) TableGenerator
811 + .createTable(dbSchema, OvsdbTable.INTERFACE);
812 +
813 + inf.setName(portName);
814 +
815 + TableSchema intfTableSchema = dbSchema
816 + .getTableSchema(OvsdbConstant.INTERFACE);
817 + Insert insert = new Insert(intfTableSchema, OvsdbConstant.INTERFACE,
818 + inf.getRow());
819 + return insert;
820 + }
821 +
822 + /**
823 + * Gets tunnel name.
824 + *
825 + * @param tunnelType
826 + * @param dstIp the remote ip address
827 + *
828 + * @return tunnel name
829 + */
830 + private String getTunnelName(String tunnelType, IpAddress dstIp) {
831 + return tunnelType + "-" + dstIp.toString();
832 + }
833 +
834 + @Override
835 + public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
836 + if (dbName == null) {
837 + return null;
838 + }
839 + DatabaseSchema databaseSchema = schema.get(dbName);
840 + if (databaseSchema == null) {
841 + List<String> dbNames = new ArrayList<String>();
842 + dbNames.add(dbName);
843 + Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() {
844 + @Override
845 + public DatabaseSchema apply(JsonNode input) {
846 + log.info("Get ovsdb database schema", dbName);
847 + DatabaseSchema dbSchema = FromJsonUtil
848 + .jsonNodeToDbSchema(dbName, input);
849 + if (dbSchema == null) {
850 + log.debug("Get ovsdb database schema error");
851 + return null;
852 + }
853 + schema.put(dbName, dbSchema);
854 +
855 + return dbSchema;
856 + }
857 + };
858 +
859 + ListenableFuture<JsonNode> input = getSchema(dbNames);
860 + if (input != null) {
861 + try {
862 + log.info("input message: {}", input.get().toString());
863 + } catch (InterruptedException e) {
864 + log.warn("Interrupted while waiting to get message");
865 + Thread.currentThread().interrupt();
866 + } catch (ExecutionException e) {
867 + log.error("Exception thrown while to get message");
868 + }
869 + }
870 + return Futures.transform(input, rowFunction);
871 + } else {
872 + return Futures.immediateFuture(databaseSchema);
873 + }
874 + }
875 +
876 + @Override
877 + public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
878 + if (dbName == null) {
879 + return null;
880 + }
881 + DatabaseSchema dbSchema = schema.get(dbName);
882 + if (dbSchema != null) {
883 + Function<JsonNode, TableUpdates> rowFunction = new Function<JsonNode, TableUpdates>() {
884 + @Override
885 + public TableUpdates apply(JsonNode input) {
886 + log.info("Get table updates");
887 + TableUpdates updates = FromJsonUtil
888 + .jsonNodeToTableUpdates(input, dbSchema);
889 + if (updates == null) {
890 + log.debug("Get table updates error");
891 + return null;
892 + }
893 + return updates;
894 + }
895 + };
896 + return Futures.transform(monitor(dbSchema, id), rowFunction);
897 + }
898 + return null;
899 + }
900 +
901 + @Override
902 + public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
903 + List<Operation> operations) {
904 + if (dbName == null) {
905 + return null;
906 + }
907 + DatabaseSchema dbSchema = schema.get(dbName);
908 + if (dbSchema != null) {
909 + Function<List<JsonNode>, List<OperationResult>> rowFunction =
910 + new Function<List<JsonNode>, List<OperationResult>>() {
911 + @Override
912 + public List<OperationResult> apply(List<JsonNode> input) {
913 + log.info("Get ovsdb operation result");
914 + List<OperationResult> result = FromJsonUtil
915 + .jsonNodeToOperationResult(input, operations);
916 +
917 + if (result == null) {
918 + log.debug("The operation result is null");
919 + return null;
920 + }
921 + return result;
922 + }
923 + };
924 + return Futures.transform(transact(dbSchema, operations),
925 + rowFunction);
926 + }
927 + return null;
928 + }
929 +
930 + @Override
931 + public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
932 + String id = java.util.UUID.randomUUID().toString();
933 + String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
934 +
935 + SettableFuture<JsonNode> sf = SettableFuture.create();
936 + requestResult.put(id, sf);
937 + requestMethod.put(id, "getSchema");
938 +
939 + channel.writeAndFlush(getSchemaString);
940 + return sf;
941 +
942 + }
943 +
944 + @Override
945 + public ListenableFuture<List<String>> echo() {
946 + String id = java.util.UUID.randomUUID().toString();
947 + String echoString = JsonRpcWriterUtil.echoStr(id);
948 +
949 + SettableFuture<List<String>> sf = SettableFuture.create();
950 + requestResult.put(id, sf);
951 + requestMethod.put(id, "echo");
952 +
953 + channel.writeAndFlush(echoString);
954 + return sf;
955 +
956 + }
957 +
958 + @Override
959 + public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
960 + String monitorId) {
961 + String id = java.util.UUID.randomUUID().toString();
962 + String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
963 + dbSchema);
964 +
965 + SettableFuture<JsonNode> sf = SettableFuture.create();
966 + requestResult.put(id, sf);
967 + requestMethod.put(id, "monitor");
968 +
969 + channel.writeAndFlush(monitorString);
970 + return sf;
971 +
972 + }
973 +
974 + @Override
975 + public ListenableFuture<List<String>> listDbs() {
976 + String id = java.util.UUID.randomUUID().toString();
977 + String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
978 +
979 + SettableFuture<List<String>> sf = SettableFuture.create();
980 + requestResult.put(id, sf);
981 + requestMethod.put(id, "listDbs");
982 +
983 + channel.writeAndFlush(listDbsString);
984 + return sf;
985 +
986 + }
987 +
988 + @Override
989 + public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
990 + List<Operation> operations) {
991 + String id = java.util.UUID.randomUUID().toString();
992 + String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
993 + operations);
994 +
995 + SettableFuture<List<JsonNode>> sf = SettableFuture.create();
996 + requestResult.put(id, sf);
997 + requestMethod.put(id, "transact");
998 +
999 + channel.writeAndFlush(transactString);
1000 + return sf;
1001 +
1002 + }
1003 +
1004 + @SuppressWarnings({ "rawtypes", "unchecked" })
1005 + @Override
1006 + public void processResult(JsonNode response) {
1007 + log.debug("Handle result");
1008 + String requestId = response.get("id").asText();
1009 + SettableFuture sf = requestResult.get(requestId);
1010 + if (sf == null) {
1011 + log.debug("No such future to process");
1012 + return;
1013 + }
1014 + String methodName = requestMethod.get(requestId);
1015 +
1016 + Object result;
1017 + result = FromJsonUtil.jsonResultParser(response, methodName);
1018 +
1019 + sf.set(result);
1020 + return;
1021 + }
1022 +
1023 + @Override
1024 + public void processRequest(JsonNode requestJson) {
1025 + log.debug("Handle request");
1026 + if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
1027 + log.debug("handle echo request");
1028 +
1029 + String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
1030 + channel.writeAndFlush(replyString);
1031 +
1032 + return;
1033 + } else {
1034 + FromJsonUtil
1035 + .jsonCallbackRequestParser(requestJson, monitorCallBack);
1036 + return;
1037 + }
1038 + }
1039 +
1040 + @Override
1041 + public void setCallback(Callback monitorCallback) {
1042 + this.monitorCallBack = monitorCallback;
1043 + }
1044 +
1045 + @Override
1046 + public Set<OvsdbTunnel> getTunnels() {
1047 + return ovsdbTunnels;
1048 + }
1049 +
1050 + @Override
1051 + public Set<OvsdbBridge> getBridges() {
1052 + return ovsdbBridges;
1053 + }
1054 +
1055 + @Override
1056 + public Set<OvsdbPort> getPorts() {
1057 + return ovsdbPorts;
1058 + }
1059 +
1060 + @Override
1061 + public DatabaseSchema getDatabaseSchema(String dbName) {
1062 + return schema.get(dbName);
1063 + }
1064 +
1065 +}
...@@ -17,6 +17,10 @@ package org.onosproject.ovsdb.controller.driver; ...@@ -17,6 +17,10 @@ package org.onosproject.ovsdb.controller.driver;
17 17
18 import io.netty.channel.Channel; 18 import io.netty.channel.Channel;
19 19
20 +import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
21 +
22 +import com.fasterxml.jackson.databind.JsonNode;
23 +
20 /** 24 /**
21 * Represents the driver side of an ovsdb node. This interface should never be 25 * Represents the driver side of an ovsdb node. This interface should never be
22 * exposed to consumers. 26 * exposed to consumers.
...@@ -52,4 +56,26 @@ public interface OvsdbProviderService { ...@@ -52,4 +56,26 @@ public interface OvsdbProviderService {
52 * @param connected whether the node is connected 56 * @param connected whether the node is connected
53 */ 57 */
54 void setConnection(boolean connected); 58 void setConnection(boolean connected);
59 +
60 + /**
61 + * Processes result from ovsdb.
62 + *
63 + * @param response JsonNode response from ovsdb
64 + */
65 + void processResult(JsonNode response);
66 +
67 + /**
68 + * processes request from ovsdb.
69 + *
70 + * @param request JsonNode request from ovsdb
71 + */
72 + void processRequest(JsonNode request);
73 +
74 + /**
75 + * Sets call back.
76 + *
77 + * @param monitorCallback the callback to set
78 + */
79 + void setCallback(Callback monitorCallback);
80 +
55 } 81 }
......