Committed by
Gerrit Code Review
[ONOS-2162][ONOS-2259]-- OVSDB- The implementation of OvsdbProviderService
and OvsdbClientService. Change-Id: I3e04d7c111adf16201f8ad7ec732eb81de05b960
Showing
8 changed files
with
1489 additions
and
1 deletions
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment