1 package org.opendaylight.ovsdb.plugin;
3 import java.math.BigInteger;
4 import java.net.InetAddress;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.HashMap;
8 import java.util.LinkedHashMap;
12 import org.eclipse.osgi.framework.console.CommandInterpreter;
13 import org.eclipse.osgi.framework.console.CommandProvider;
14 import org.opendaylight.controller.sal.connection.ConnectionConstants;
15 import org.opendaylight.controller.sal.core.Node;
16 import org.opendaylight.controller.sal.core.NodeConnector;
17 import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants;
18 import org.opendaylight.controller.sal.networkconfig.bridgedomain.IPluginInBridgeDomainConfigService;
19 import org.opendaylight.controller.sal.utils.Status;
20 import org.opendaylight.controller.sal.utils.StatusCode;
21 import org.opendaylight.ovsdb.lib.database.OVSInstance;
22 import org.opendaylight.ovsdb.lib.database.OvsdbType;
23 import org.opendaylight.ovsdb.lib.message.TransactBuilder;
24 import org.opendaylight.ovsdb.lib.message.operations.InsertOperation;
25 import org.opendaylight.ovsdb.lib.message.operations.MutateOperation;
26 import org.opendaylight.ovsdb.lib.message.operations.Operation;
27 import org.opendaylight.ovsdb.lib.message.operations.OperationResult;
28 import org.opendaylight.ovsdb.lib.message.operations.UpdateOperation;
29 import org.opendaylight.ovsdb.lib.notation.Condition;
30 import org.opendaylight.ovsdb.lib.notation.Function;
31 import org.opendaylight.ovsdb.lib.notation.Mutation;
32 import org.opendaylight.ovsdb.lib.notation.Mutator;
33 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
34 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
35 import org.opendaylight.ovsdb.lib.notation.UUID;
36 import org.opendaylight.ovsdb.lib.table.Bridge;
37 import org.opendaylight.ovsdb.lib.table.Capability;
38 import org.opendaylight.ovsdb.lib.table.Controller;
39 import org.opendaylight.ovsdb.lib.table.Interface;
40 import org.opendaylight.ovsdb.lib.table.Manager;
41 import org.opendaylight.ovsdb.lib.table.Mirror;
42 import org.opendaylight.ovsdb.lib.table.NetFlow;
43 import org.opendaylight.ovsdb.lib.table.Open_vSwitch;
44 import org.opendaylight.ovsdb.lib.table.Port;
45 import org.opendaylight.ovsdb.lib.table.Qos;
46 import org.opendaylight.ovsdb.lib.table.Queue;
47 import org.opendaylight.ovsdb.lib.table.SFlow;
48 import org.opendaylight.ovsdb.lib.table.SSL;
49 import org.opendaylight.ovsdb.lib.table.internal.Table;
50 import org.osgi.framework.BundleContext;
51 import org.osgi.framework.FrameworkUtil;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 import com.fasterxml.jackson.databind.ObjectMapper;
56 import com.google.common.util.concurrent.ListenableFuture;
58 public class ConfigurationService implements IPluginInBridgeDomainConfigService, OVSDBConfigService,
61 private static final Logger logger = LoggerFactory
62 .getLogger(ConfigurationService.class);
64 IConnectionServiceInternal connectionService;
65 InventoryServiceInternal inventoryServiceInternal;
66 boolean forceConnect = false;
72 * Function called by the dependency manager when at least one dependency
73 * become unsatisfied or when the component is shutting down because for
74 * example bundle is being stopped.
81 * Function called by dependency manager after "init ()" is called and after
82 * the services provided by the class are registered in the service registry
86 registerWithOSGIConsole();
89 private void registerWithOSGIConsole() {
90 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
92 bundleContext.registerService(CommandProvider.class.getName(), this,
97 * Function called by the dependency manager before the services exported by
98 * the component are unregistered, this will be followed by a "destroy ()"
105 public void setConnectionServiceInternal(IConnectionServiceInternal connectionService) {
106 this.connectionService = connectionService;
109 public void unsetConnectionServiceInternal(IConnectionServiceInternal connectionService) {
110 if (this.connectionService == connectionService) {
111 this.connectionService = null;
115 public void setInventoryServiceInternal(InventoryServiceInternal inventoryServiceInternal) {
116 this.inventoryServiceInternal = inventoryServiceInternal;
119 public void unsetInventoryServiceInternal(InventoryServiceInternal inventoryServiceInternal) {
120 if (this.inventoryServiceInternal == inventoryServiceInternal) {
121 this.inventoryServiceInternal = null;
125 private Connection getConnection (Node node) {
126 Connection connection = connectionService.getConnection(node);
127 if (connection == null || !connection.getChannel().isActive()) {
136 * @param node Node serving this configuration service
137 * @param bridgeConnectorIdentifier String representation of a Bridge Connector
138 * @return Bridge Connector configurations
141 public Status createBridgeDomain(Node node, String bridgeIdentifier,
142 Map<ConfigConstants, Object> configs) throws Throwable {
144 if (connectionService == null) {
145 logger.error("Couldn't refer to the ConnectionService");
146 return new Status(StatusCode.NOSERVICE);
149 Connection connection = this.getConnection(node);
150 if (connection == null) {
151 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
154 Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
155 String newBridge = "new_bridge";
156 String newInterface = "new_interface";
157 String newPort = "new_port";
158 String newSwitch = "new_switch";
160 Operation addSwitchRequest = null;
162 if(ovsTable != null){
163 String ovsTableUUID = (String) ovsTable.keySet().toArray()[0];
164 UUID bridgeUuidPair = new UUID(newBridge);
165 Mutation bm = new Mutation("bridges", Mutator.INSERT, bridgeUuidPair);
166 List<Mutation> mutations = new ArrayList<Mutation>();
169 UUID uuid = new UUID(ovsTableUUID);
170 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
171 List<Condition> where = new ArrayList<Condition>();
172 where.add(condition);
173 addSwitchRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations);
176 Open_vSwitch ovsTableRow = new Open_vSwitch();
177 OvsDBSet<UUID> bridges = new OvsDBSet<UUID>();
178 UUID bridgeUuidPair = new UUID(newBridge);
179 bridges.add(bridgeUuidPair);
180 ovsTableRow.setBridges(bridges);
181 addSwitchRequest = new InsertOperation(Open_vSwitch.NAME.getName(), newSwitch, ovsTableRow);
184 Bridge bridgeRow = new Bridge();
185 bridgeRow.setName(bridgeIdentifier);
186 OvsDBSet<UUID> ports = new OvsDBSet<UUID>();
187 UUID port = new UUID(newPort);
189 bridgeRow.setPorts(ports);
190 InsertOperation addBridgeRequest = new InsertOperation(Bridge.NAME.getName(), newBridge, bridgeRow);
192 Port portRow = new Port();
193 portRow.setName(bridgeIdentifier);
194 OvsDBSet<UUID> interfaces = new OvsDBSet<UUID>();
195 UUID interfaceid = new UUID(newInterface);
196 interfaces.add(interfaceid);
197 portRow.setInterfaces(interfaces);
198 InsertOperation addPortRequest = new InsertOperation(Port.NAME.getName(), newPort, portRow);
200 Interface interfaceRow = new Interface();
201 interfaceRow.setName(bridgeIdentifier);
202 interfaceRow.setType("internal");
203 InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(), newInterface, interfaceRow);
205 /* Update config version */
206 String ovsTableUUID = (String) ovsTable.keySet().toArray()[0];
207 Mutation bm = new Mutation("next_cfg", Mutator.SUM, 1);
208 List<Mutation> mutations = new ArrayList<Mutation>();
211 UUID uuid = new UUID(ovsTableUUID);
212 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
213 List<Condition> where = new ArrayList<Condition>();
214 where.add(condition);
215 MutateOperation updateCfgVerRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations);
217 TransactBuilder transaction = new TransactBuilder();
218 transaction.addOperations(new ArrayList<Operation>(
219 Arrays.asList(addSwitchRequest,
223 updateCfgVerRequest)));
225 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
226 List<OperationResult> tr = transResponse.get();
227 List<Operation> requests = transaction.getRequests();
228 Status status = new Status(StatusCode.SUCCESS);
229 for (int i = 0; i < tr.size() ; i++) {
230 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
231 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
232 OperationResult result = tr.get(i);
233 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
237 if (tr.size() > requests.size()) {
238 OperationResult result = tr.get(tr.size()-1);
239 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier,
241 result.getDetails());
242 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
244 if (status.isSuccess()) {
245 setBridgeOFController(node, bridgeIdentifier);
248 } catch(Exception e){
251 return new Status(StatusCode.INTERNALERROR);
255 * Create a Port Attached to a Bridge
256 * Ex. ovs-vsctl add-port br0 vif0
257 * @param node Node serving this configuration service
258 * @param bridgeDomainIdentifier String representation of a Bridge Domain
259 * @param portIdentifier String representation of a user defined Port Name
262 public Status addPort(Node node, String bridgeIdentifier, String portIdentifier,
263 Map<ConfigConstants, Object> configs) {
265 if (connectionService == null) {
266 logger.error("Couldn't refer to the ConnectionService");
267 return new Status(StatusCode.NOSERVICE);
269 Connection connection = this.getConnection(node);
270 if (connection == null) {
271 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
273 if (connection != null) {
274 Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
275 String newBridge = "new_bridge";
276 String newInterface = "new_interface";
277 String newPort = "new_port";
280 Operation addBrMutRequest = null;
281 String brUuid = null;
282 for (String uuid : brTable.keySet()) {
283 Bridge bridge = (Bridge) brTable.get(uuid);
284 if (bridge.getName().contains(bridgeIdentifier)) {
289 UUID brUuidPair = new UUID(newPort);
290 Mutation bm = new Mutation("ports", Mutator.INSERT, brUuidPair);
291 List<Mutation> mutations = new ArrayList<Mutation>();
294 UUID uuid = new UUID(brUuid);
295 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
296 List<Condition> where = new ArrayList<Condition>();
297 where.add(condition);
298 addBrMutRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
300 OvsDBMap<String, String> options = null;
302 OvsDBSet<BigInteger> tags = null;
303 if (configs != null) {
304 type = (String) configs.get(ConfigConstants.TYPE);
305 Map<String, String> customConfigs = (Map<String, String>) configs.get(ConfigConstants.CUSTOM);
306 if (customConfigs != null) {
307 options = new OvsDBMap<String, String>();
308 for (String customConfig : customConfigs.keySet()) {
309 options.put(customConfig, customConfigs.get(customConfig));
314 Interface interfaceRow = new Interface();
315 interfaceRow.setName(portIdentifier);
318 if (type.equalsIgnoreCase(OvsdbType.PortType.TUNNEL.name())) {
319 interfaceRow.setType((String)configs.get(ConfigConstants.TUNNEL_TYPE));
320 if (options == null) options = new OvsDBMap<String, String>();
321 options.put("remote_ip", (String)configs.get(ConfigConstants.DEST_IP));
322 } else if (type.equalsIgnoreCase(OvsdbType.PortType.VLAN.name())) {
323 tags = new OvsDBSet<BigInteger>();
324 tags.add(BigInteger.valueOf(Integer.parseInt((String)configs.get(ConfigConstants.VLAN))));
325 } else if (type.equalsIgnoreCase(OvsdbType.PortType.PATCH.name())) {
326 interfaceRow.setType(type.toLowerCase());
329 if (options != null) {
330 interfaceRow.setOptions(options);
333 InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(),
334 newInterface, interfaceRow);
336 Port portRow = new Port();
337 portRow.setName(portIdentifier);
338 if (tags != null) portRow.setTag(tags);
339 OvsDBSet<UUID> interfaces = new OvsDBSet<UUID>();
340 UUID interfaceid = new UUID(newInterface);
341 interfaces.add(interfaceid);
342 portRow.setInterfaces(interfaces);
343 InsertOperation addPortRequest = new InsertOperation(Port.NAME.getName(), newPort, portRow);
345 TransactBuilder transaction = new TransactBuilder();
346 transaction.addOperations(new ArrayList<Operation>
347 (Arrays.asList(addBrMutRequest, addPortRequest, addIntfRequest)));
349 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
350 List<OperationResult> tr = transResponse.get();
351 List<Operation> requests = transaction.getRequests();
352 Status status = new Status(StatusCode.SUCCESS);
353 for (int i = 0; i < tr.size() ; i++) {
354 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
355 if (tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
356 OperationResult result = tr.get(i);
357 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
361 if (tr.size() > requests.size()) {
362 OperationResult result = tr.get(tr.size()-1);
363 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier,
365 result.getDetails());
366 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
370 return new Status(StatusCode.INTERNALERROR);
372 } catch(Exception e){
375 return new Status(StatusCode.INTERNALERROR);
379 * Implements the OVS Connection for Managers
381 * @param node Node serving this configuration service
382 * @param String with IP and connection types
384 @SuppressWarnings("unchecked")
385 public boolean setManager(Node node, String managerip) throws Throwable{
387 if (connectionService == null) {
388 logger.error("Couldn't refer to the ConnectionService");
391 Connection connection = this.getConnection(node);
392 if (connection == null) {
396 if (connection != null) {
397 String newmanager = "new_manager";
399 OVSInstance instance = OVSInstance.monitorOVS(connection);
401 Map ovsoutter = new LinkedHashMap();
402 Map ovsinner = new LinkedHashMap();
403 ArrayList ovsalist1 = new ArrayList();
404 ArrayList ovsalist2 = new ArrayList();
405 ArrayList ovsalist3 = new ArrayList();
406 ArrayList ovsalist4 = new ArrayList();
409 ovsoutter.put("where", ovsalist1);
410 ovsalist1.add(ovsalist2);
411 ovsalist2.add("_uuid");
413 ovsalist2.add(ovsalist3);
414 ovsalist3.add("uuid");
415 ovsalist3.add(instance.getUuid());
416 ovsoutter.put("op", "update");
417 ovsoutter.put("table", "Open_vSwitch");
418 ovsoutter.put("row", ovsinner);
419 ovsinner.put("manager_options", ovsalist4);
420 ovsalist4.add("named-uuid");
421 ovsalist4.add(newmanager);
423 Map mgroutside = new LinkedHashMap();
424 Map mgrinside = new LinkedHashMap();
426 //Manager Table Insert
427 mgroutside.put("uuid-name", newmanager);
428 mgroutside.put("op", "insert");
429 mgroutside.put("table","Manager");
430 mgroutside.put("row", mgrinside);
431 mgrinside.put("target", managerip);
433 Object[] params = {"Open_vSwitch", ovsoutter, mgroutside};
434 OvsdbMessage msg = new OvsdbMessage("transact", params);
436 //connection.sendMessage(msg);
446 public Status addBridgeDomainConfig(Node node, String bridgeIdentfier,
447 Map<ConfigConstants, Object> configs) {
448 String mgmt = (String)configs.get(ConfigConstants.MGMT);
451 if (setManager(node, mgmt)) return new Status(StatusCode.SUCCESS);
452 } catch (Throwable e) {
453 // TODO Auto-generated catch block
455 return new Status(StatusCode.INTERNALERROR);
458 return new Status(StatusCode.BADREQUEST);
462 public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier,
463 Map<ConfigConstants, Object> configs) {
464 // TODO Auto-generated method stub
469 public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier) {
472 if (connectionService == null) {
473 logger.error("Couldn't refer to the ConnectionService");
474 return new Status(StatusCode.NOSERVICE);
477 Connection connection = this.getConnection(node);
478 if (connection == null) {
479 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
482 Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
483 Map<String, Table<?>> portTable = inventoryServiceInternal.getTableCache(node, Port.NAME.getName());
484 Operation delPortRequest = null;
485 String brUuid = null;
486 String portUuid = null;
488 for (String uuid : brTable.keySet()) {
489 Bridge bridge = (Bridge) brTable.get(uuid);
490 if (bridge.getName().contains(bridgeIdentifier)) {
495 if(portTable != null){
496 for (String uuid : portTable.keySet()) {
497 Port port = (Port) portTable.get(uuid);
498 if (port.getName().contains(portIdentifier)) {
504 UUID portUuidPair = new UUID(portUuid);
505 Mutation bm = new Mutation("ports", Mutator.DELETE, portUuidPair);
506 List<Mutation> mutations = new ArrayList<Mutation>();
509 UUID uuid = new UUID(brUuid);
510 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
511 List<Condition> where = new ArrayList<Condition>();
512 where.add(condition);
513 delPortRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
515 TransactBuilder transaction = new TransactBuilder();
516 transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delPortRequest)));
518 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
519 List<OperationResult> tr = transResponse.get();
520 List<Operation> requests = transaction.getRequests();
521 Status status = new Status(StatusCode.SUCCESS);
522 for (int i = 0; i < tr.size() ; i++) {
523 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
524 if (tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
525 OperationResult result = tr.get(i);
526 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
530 if (tr.size() > requests.size()) {
531 OperationResult result = tr.get(tr.size()-1);
532 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier,
534 result.getDetails());
535 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
538 } catch(Exception e){
541 return new Status(StatusCode.INTERNALERROR);
545 public Node getBridgeDomainNode(Node node, String bridgeIdentifier) {
546 // TODO Auto-generated method stub
551 public Map<ConfigConstants, Object> getPortConfigs(Node node, String bridgeIdentifier,
552 String portIdentifier) {
553 // TODO Auto-generated method stub
558 public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier,
559 Map<ConfigConstants, Object> configs) {
560 // TODO Auto-generated method stub
565 public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier,
566 Map<ConfigConstants, Object> configs) {
567 // TODO Auto-generated method stub
572 public Status deleteBridgeDomain(Node node, String bridgeIdentifier) {
575 if (connectionService == null) {
576 logger.error("Couldn't refer to the ConnectionService");
577 return new Status(StatusCode.NOSERVICE);
579 Connection connection = this.getConnection(node);
580 if (connection == null) {
581 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
583 Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
584 Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
585 Operation delBrRequest = null;
586 String ovsUuid = null;
587 String brUuid = null;
589 if (brTable != null) {
590 for (String uuid : brTable.keySet()) {
591 Bridge bridge = (Bridge) brTable.get(uuid);
592 if (bridge.getName().contains(bridgeIdentifier)) {
597 if (ovsTable != null) {
598 ovsUuid = (String) ovsTable.keySet().toArray()[0];
600 UUID bridgeUuidPair = new UUID(brUuid);
601 Mutation bm = new Mutation("bridges", Mutator.DELETE, bridgeUuidPair);
602 List<Mutation> mutations = new ArrayList<Mutation>();
605 UUID uuid = new UUID(ovsUuid);
606 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
607 List<Condition> where = new ArrayList<Condition>();
608 where.add(condition);
609 delBrRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations);
611 TransactBuilder transaction = new TransactBuilder();
612 transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delBrRequest)));
614 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
615 List<OperationResult> tr = transResponse.get();
616 List<Operation> requests = transaction.getRequests();
617 Status status = new Status(StatusCode.SUCCESS);
618 for (int i = 0; i < tr.size(); i++) {
619 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
620 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
621 OperationResult result = tr.get(i);
622 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
626 if (tr.size() > requests.size()) {
627 OperationResult result = tr.get(tr.size() - 1);
628 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}",
629 bridgeIdentifier, result.getError(), result.getDetails());
630 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
633 } catch (Exception e) {
636 return new Status(StatusCode.INTERNALERROR);
640 public Map<ConfigConstants, Object> getBridgeDomainConfigs(Node node, String bridgeIdentifier) {
641 // TODO Auto-generated method stub
646 public List<String> getBridgeDomains(Node node) {
647 List<String> brlist = new ArrayList<String>();
648 Map<String, Table<?>> brTableCache = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
649 if(brTableCache != null){
650 for (String uuid : brTableCache.keySet()) {
651 Bridge bridge = (Bridge) brTableCache.get(uuid);
652 brlist.add(bridge.getName());
659 public NodeConnector getNodeConnector(Node arg0, String arg1, String arg2) {
663 Boolean setBridgeOFController(Node node, String bridgeIdentifier) {
664 if (connectionService == null) {
665 logger.error("Couldn't refer to the ConnectionService");
670 Map<String, Table<?>> brTableCache = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
671 for (String uuid : brTableCache.keySet()) {
672 Bridge bridge = (Bridge)brTableCache.get(uuid);
673 if (bridge.getName().contains(bridgeIdentifier)) {
674 return connectionService.setOFController(node, uuid);
677 } catch(Exception e) {
684 public Status insertRow(Node node, String tableName, String parent_uuid, Table<?> row) {
685 logger.info("tableName : {}, parent_uuid : {} Row : {}", tableName, parent_uuid, row.toString());
686 Status statusWithUUID = null;
688 // Schema based Table handling will help fix this static Table handling.
690 if (row.getTableName().getName().equalsIgnoreCase("Bridge")) {
691 statusWithUUID = insertBridgeRow(node, parent_uuid, (Bridge)row);
693 else if (row.getTableName().getName().equalsIgnoreCase("Capbility")) {
694 statusWithUUID = insertCapabilityRow(node, parent_uuid, (Capability)row);
696 else if (row.getTableName().getName().equalsIgnoreCase("Controller")) {
697 statusWithUUID = insertControllerRow(node, parent_uuid, (Controller)row);
699 else if (row.getTableName().getName().equalsIgnoreCase("Interface")) {
700 statusWithUUID = insertInterfaceRow(node, parent_uuid, (Interface)row);
702 else if (row.getTableName().getName().equalsIgnoreCase("Manager")) {
703 statusWithUUID = insertManagerRow(node, parent_uuid, (Manager)row);
705 else if (row.getTableName().getName().equalsIgnoreCase("Mirror")) {
706 statusWithUUID = insertMirrorRow(node, parent_uuid, (Mirror)row);
708 else if (row.getTableName().getName().equalsIgnoreCase("NetFlow")) {
709 statusWithUUID = insertNetFlowRow(node, parent_uuid, (NetFlow)row);
711 else if (row.getTableName().getName().equalsIgnoreCase("Open_vSwitch")) {
712 statusWithUUID = insertOpen_vSwitchRow(node, (Open_vSwitch)row);
714 else if (row.getTableName().getName().equalsIgnoreCase("Port")) {
715 statusWithUUID = insertPortRow(node, parent_uuid, (Port)row);
717 else if (row.getTableName().getName().equalsIgnoreCase("QoS")) {
718 statusWithUUID = insertQosRow(node, parent_uuid, (Qos)row);
720 else if (row.getTableName().getName().equalsIgnoreCase("Queue")) {
721 statusWithUUID = insertQueueRow(node, parent_uuid, (Queue)row);
723 else if (row.getTableName().getName().equalsIgnoreCase("sFlow")) {
724 statusWithUUID = insertSflowRow(node, parent_uuid, (SFlow)row);
726 else if (row.getTableName().getName().equalsIgnoreCase("SSL")) {
727 statusWithUUID = insertSSLRow(node, parent_uuid, (SSL)row);
729 return statusWithUUID;
734 public Status updateRow (Node node, String tableName, String parentUUID, String rowUUID, Table<?> row) {
736 if (connectionService == null) {
737 logger.error("Couldn't refer to the ConnectionService");
738 return new Status(StatusCode.NOSERVICE);
741 Connection connection = this.getConnection(node);
742 if (connection == null) {
743 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
746 Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
748 if (ovsTable == null) {
749 return new Status(StatusCode.NOTFOUND, "There are no Open_vSwitch instance in the Open_vSwitch table");
752 UUID uuid = new UUID(rowUUID);
753 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
754 List<Condition> where = new ArrayList<Condition>();
755 where.add(condition);
756 Operation updateRequest = new UpdateOperation(tableName, where, row);
758 TransactBuilder transaction = new TransactBuilder();
759 transaction.addOperations(new ArrayList<Operation>(
760 Arrays.asList(updateRequest)));
762 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
763 List<OperationResult> tr = transResponse.get();
764 List<Operation> requests = transaction.getRequests();
765 Status status = new Status(StatusCode.SUCCESS);
766 for (int i = 0; i < tr.size() ; i++) {
767 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
768 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
769 OperationResult result = tr.get(i);
770 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
774 if (tr.size() > requests.size()) {
775 OperationResult result = tr.get(tr.size()-1);
776 logger.error("Error Updating Row : {}/{}\n Error : {}\n Details : {}", tableName, row,
778 result.getDetails());
779 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
781 if (status.isSuccess()) {
782 status = new Status(StatusCode.SUCCESS);
785 } catch(Exception e){
788 return new Status(StatusCode.INTERNALERROR);
792 public Status deleteRow(Node node, String tableName, String uuid) {
793 if (tableName.equalsIgnoreCase("Bridge")) {
794 return deleteBridgeRow(node, uuid);
796 else if (tableName.equalsIgnoreCase("Capbility")) {
797 return deleteCapabilityRow(node, uuid);
799 else if (tableName.equalsIgnoreCase("Controller")) {
800 return deleteControllerRow(node, uuid);
802 else if (tableName.equalsIgnoreCase("Interface")) {
803 return deleteInterfaceRow(node, uuid);
805 else if (tableName.equalsIgnoreCase("Manager")) {
806 return deleteManagerRow(node, uuid);
808 else if (tableName.equalsIgnoreCase("Mirror")) {
809 return deleteMirrorRow(node, uuid);
811 else if (tableName.equalsIgnoreCase("NetFlow")) {
812 return deleteNetFlowRow(node, uuid);
814 else if (tableName.equalsIgnoreCase("Open_vSwitch")) {
815 return deleteOpen_vSwitchRow(node, uuid);
817 else if (tableName.equalsIgnoreCase("Port")) {
818 return deletePortRow(node, uuid);
820 else if (tableName.equalsIgnoreCase("QoS")) {
821 return deleteQosRow(node, uuid);
823 else if (tableName.equalsIgnoreCase("Queue")) {
824 return deleteQueueRow(node, uuid);
826 else if (tableName.equalsIgnoreCase("sFlow")) {
827 return deleteSflowRow(node, uuid);
829 else if (tableName.equalsIgnoreCase("SSL")) {
830 return deleteSSLRow(node, uuid);
832 return new Status(StatusCode.NOTFOUND, "Table "+tableName+" not supported");
836 public Map<String, Table<?>> getRows(Node node, String tableName) throws Exception{
838 if (inventoryServiceInternal == null) {
839 throw new Exception("Inventory Service is Unavailable.");
841 Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, tableName);
843 } catch(Exception e){
844 throw new Exception("Unable to read table due to "+e.getMessage());
849 public Table<?> getRow(Node node, String tableName, String uuid) throws Exception {
851 if (inventoryServiceInternal == null) {
852 throw new Exception("Inventory Service is Unavailable.");
854 Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, tableName);
855 if (ovsTable == null) return null;
856 return ovsTable.get(uuid);
857 } catch(Exception e){
858 throw new Exception("Unable to read table due to "+e.getMessage());
863 public String getSerializedRows(Node node, String tableName) throws Exception{
865 Map<String, Table<?>> ovsTable = this.getRows(node, tableName);
866 if (ovsTable == null) return null;
867 ObjectMapper mapper = new ObjectMapper();
868 return mapper.writeValueAsString(ovsTable);
869 } catch(Exception e){
870 throw new Exception("Unable to read table due to "+e.getMessage());
875 public String getSerializedRow(Node node, String tableName, String uuid) throws Exception {
877 Table<?> row = this.getRow(node, tableName, uuid);
878 if (row == null) return null;
879 ObjectMapper mapper = new ObjectMapper();
880 return mapper.writeValueAsString(row);
881 } catch(Exception e){
882 throw new Exception("Unable to read table due to "+e.getMessage());
887 public List<String> getTables(Node node) {
888 // TODO Auto-generated method stub
892 private Status insertBridgeRow(Node node, String open_VSwitch_uuid, Bridge bridgeRow) {
894 if (connectionService == null) {
895 logger.error("Couldn't refer to the ConnectionService");
896 return new Status(StatusCode.NOSERVICE);
899 Connection connection = this.getConnection(node);
900 if (connection == null) {
901 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
904 Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
906 if (ovsTable == null) {
907 return new Status(StatusCode.NOTFOUND, "There are no Open_vSwitch instance in the Open_vSwitch table");
910 String newBridge = "new_bridge";
912 Operation addSwitchRequest = null;
914 String ovsTableUUID = open_VSwitch_uuid;
915 if (ovsTableUUID == null) ovsTableUUID = (String) ovsTable.keySet().toArray()[0];
916 UUID bridgeUuidPair = new UUID(newBridge);
917 Mutation bm = new Mutation("bridges", Mutator.INSERT, bridgeUuidPair);
918 List<Mutation> mutations = new ArrayList<Mutation>();
921 UUID uuid = new UUID(ovsTableUUID);
922 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
923 List<Condition> where = new ArrayList<Condition>();
924 where.add(condition);
925 addSwitchRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations);
927 InsertOperation addBridgeRequest = new InsertOperation(Bridge.NAME.getName(), newBridge, bridgeRow);
929 TransactBuilder transaction = new TransactBuilder();
930 transaction.addOperations(new ArrayList<Operation>(
931 Arrays.asList(addSwitchRequest,
934 int bridgeInsertIndex = transaction.getRequests().indexOf(addBridgeRequest);
936 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
937 List<OperationResult> tr = transResponse.get();
938 List<Operation> requests = transaction.getRequests();
939 Status status = new Status(StatusCode.SUCCESS);
940 for (int i = 0; i < tr.size() ; i++) {
941 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
942 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
943 OperationResult result = tr.get(i);
944 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
948 if (tr.size() > requests.size()) {
949 OperationResult result = tr.get(tr.size()-1);
950 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeRow.getName(),
952 result.getDetails());
953 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
955 if (status.isSuccess()) {
956 UUID bridgeUUID = tr.get(bridgeInsertIndex).getUuid();
957 status = new Status(StatusCode.SUCCESS, bridgeUUID.toString());
960 } catch(Exception e){
963 return new Status(StatusCode.INTERNALERROR);
966 private Status insertPortRow(Node node, String bridge_uuid, Port portRow) {
968 if (connectionService == null) {
969 logger.error("Couldn't refer to the ConnectionService");
970 return new Status(StatusCode.NOSERVICE);
972 Connection connection = this.getConnection(node);
973 if (connection == null) {
974 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
977 Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
978 if (brTable == null || brTable.get(bridge_uuid) == null) {
979 return new Status(StatusCode.NOTFOUND, "Bridge with UUID "+bridge_uuid+" Not found");
981 String newPort = "new_port";
982 UUID portUUID = new UUID(newPort);
983 Mutation bm = new Mutation("ports", Mutator.INSERT, portUUID);
984 List<Mutation> mutations = new ArrayList<Mutation>();
987 UUID uuid = new UUID(bridge_uuid);
988 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
989 List<Condition> where = new ArrayList<Condition>();
990 where.add(condition);
991 Operation addBrMutRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
993 // Default OVS schema is to have 1 or more interface part of Bridge. Hence it is mandatory to
994 // Insert an Interface in a Port add case :-(.
996 String newInterface = "new_interface";
997 Interface interfaceRow = new Interface();
998 interfaceRow.setName(portRow.getName());
999 InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(),
1000 newInterface, interfaceRow);
1002 OvsDBSet<UUID> interfaces = new OvsDBSet<UUID>();
1003 UUID interfaceid = new UUID(newInterface);
1004 interfaces.add(interfaceid);
1005 portRow.setInterfaces(interfaces);
1007 InsertOperation addPortRequest = new InsertOperation(Port.NAME.getName(), newPort, portRow);
1009 TransactBuilder transaction = new TransactBuilder();
1010 transaction.addOperations(new ArrayList<Operation>
1011 (Arrays.asList(addBrMutRequest, addPortRequest, addIntfRequest)));
1012 int portInsertIndex = transaction.getRequests().indexOf(addPortRequest);
1013 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1014 List<OperationResult> tr = transResponse.get();
1015 List<Operation> requests = transaction.getRequests();
1016 Status status = new Status(StatusCode.SUCCESS);
1017 for (int i = 0; i < tr.size() ; i++) {
1018 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
1019 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
1020 OperationResult result = tr.get(i);
1021 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1025 if (tr.size() > requests.size()) {
1026 OperationResult result = tr.get(tr.size()-1);
1027 logger.error("Error creating port : {}\n Error : {}\n Details : {}", portRow.getName(),
1029 result.getDetails());
1030 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1032 if (status.isSuccess()) {
1033 uuid = tr.get(portInsertIndex).getUuid();
1034 status = new Status(StatusCode.SUCCESS, uuid.toString());
1038 } catch (Exception e) {
1039 e.printStackTrace();
1041 return new Status(StatusCode.INTERNALERROR);
1044 private Status insertInterfaceRow(Node node, String port_uuid, Interface interfaceRow) {
1046 if (connectionService == null) {
1047 logger.error("Couldn't refer to the ConnectionService");
1048 return new Status(StatusCode.NOSERVICE);
1050 Connection connection = this.getConnection(node);
1051 if (connection == null) {
1052 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1055 // Interface table must have entry in Port table, checking port table for port
1056 Map<String, Table<?>> portTable = inventoryServiceInternal.getTableCache(node, Port.NAME.getName());
1057 if (portTable == null || portTable.get(port_uuid) == null) {
1058 return new Status(StatusCode.NOTFOUND, "Port with UUID "+port_uuid+" Not found");
1060 // MUTATOR, need to insert the interface UUID to LIST of interfaces in PORT TABLE for port_uuid
1061 String newInterface = "new_interface";
1062 UUID interfaceUUID = new UUID(newInterface);
1063 Mutation portTableMutation = new Mutation("interfaces", Mutator.INSERT, interfaceUUID); // field name to append is "interfaces"
1064 List<Mutation> mutations = new ArrayList<Mutation>();
1065 mutations.add(portTableMutation);
1067 // Create the Operation which will be used in Transact to perform the PORT TABLE mutation
1068 UUID uuid = new UUID(port_uuid);
1069 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
1070 List<Condition> where = new ArrayList<Condition>();
1071 where.add(condition);
1072 Operation addPortMutationRequest = new MutateOperation(Port.NAME.getName(), where, mutations);
1074 // Create the interface row request
1075 InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(),newInterface, interfaceRow);
1077 // Transaction to insert/modify tables - validate using "sudo ovsdb-client dump" on host running OVSDB process
1078 TransactBuilder transaction = new TransactBuilder();
1079 transaction.addOperations(new ArrayList<Operation>(Arrays.asList(addIntfRequest,addPortMutationRequest)));
1081 // Check the results. Iterates over the results of the Array of transaction Operations, and reports STATUS
1082 int intInsertIndex = transaction.getRequests().indexOf(addIntfRequest);
1083 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1084 List<OperationResult> tr = transResponse.get();
1085 List<Operation> requests = transaction.getRequests();
1086 Status status = new Status(StatusCode.SUCCESS);
1087 for (int i = 0; i < tr.size() ; i++) {
1088 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
1089 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
1090 OperationResult result = tr.get(i);
1091 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1094 if (tr.size() > requests.size()) {
1095 OperationResult result = tr.get(tr.size()-1);
1096 logger.error("Error creating interface : {}\n Error : {}\n Details : {}", interfaceRow.getName(),
1098 result.getDetails());
1099 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1101 if (status.isSuccess()) {
1102 uuid = tr.get(intInsertIndex).getUuid();
1103 status = new Status(StatusCode.SUCCESS, uuid.toString());
1107 } catch (Exception e) {
1108 e.printStackTrace();
1110 return new Status(StatusCode.INTERNALERROR);
1113 private Status insertOpen_vSwitchRow(Node node, Open_vSwitch row) {
1114 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1117 private Status insertControllerRow(Node node, String bridge_uuid, Controller row) {
1119 if (connectionService == null) {
1120 logger.error("Couldn't refer to the ConnectionService");
1121 return new Status(StatusCode.NOSERVICE);
1123 Connection connection = this.getConnection(node);
1124 if (connection == null) {
1125 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1128 Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
1129 if (brTable == null || brTable.get(bridge_uuid) == null) {
1130 return new Status(StatusCode.NOTFOUND, "Bridge with UUID "+bridge_uuid+" Not found");
1133 Map<String, Table<?>> controllerCache = inventoryServiceInternal.getTableCache(node, Controller.NAME.getName());
1135 String uuid_name = "new_controller";
1136 boolean controllerExists = false;
1137 if (controllerCache != null) {
1138 for (String uuid : controllerCache.keySet()) {
1139 Controller controller = (Controller)controllerCache.get(uuid);
1140 if (controller.getTarget().equals(row.getTarget())) {
1142 controllerExists = true;
1148 UUID controllerUUID = new UUID(uuid_name);
1149 Mutation bm = new Mutation("controller", Mutator.INSERT, controllerUUID);
1150 List<Mutation> mutations = new ArrayList<Mutation>();
1153 UUID uuid = new UUID(bridge_uuid);
1154 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
1155 List<Condition> where = new ArrayList<Condition>();
1156 where.add(condition);
1157 Operation addBrMutRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
1158 InsertOperation addControllerRequest = null;
1160 TransactBuilder transaction = new TransactBuilder();
1161 transaction.addOperation(addBrMutRequest);
1162 int portInsertIndex = -1;
1163 if (!controllerExists) {
1164 addControllerRequest = new InsertOperation(Controller.NAME.getName(), uuid_name, row);
1165 transaction.addOperation(addControllerRequest);
1166 portInsertIndex = transaction.getRequests().indexOf(addControllerRequest);
1169 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1170 List<OperationResult> tr = transResponse.get();
1171 List<Operation> requests = transaction.getRequests();
1172 Status status = new Status(StatusCode.SUCCESS);
1173 for (int i = 0; i < tr.size() ; i++) {
1174 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
1175 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
1176 OperationResult result = tr.get(i);
1177 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1181 if (tr.size() > requests.size()) {
1182 OperationResult result = tr.get(tr.size()-1);
1183 logger.error("Error creating port : {}\n Error : {}\n Details : {}", row.getTarget(),
1185 result.getDetails());
1186 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1188 if (status.isSuccess()) {
1189 if (controllerExists) {
1190 status = new Status(StatusCode.SUCCESS, uuid_name);
1192 uuid = tr.get(portInsertIndex).getUuid();
1193 status = new Status(StatusCode.SUCCESS, uuid.toString());
1197 } catch (Exception e) {
1198 e.printStackTrace();
1200 return new Status(StatusCode.INTERNALERROR);
1203 private Status insertSSLRow(Node node, String parent_uuid, SSL row) {
1204 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1207 private Status insertSflowRow(Node node, String parent_uuid, SFlow row) {
1208 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1211 private Status insertQueueRow(Node node, String parent_uuid, Queue row) {
1212 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1215 private Status insertQosRow(Node node, String parent_uuid, Qos row) {
1216 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1219 private Status insertNetFlowRow(Node node, String parent_uuid, NetFlow row) {
1220 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1223 private Status insertMirrorRow(Node node, String parent_uuid, Mirror row) {
1224 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1227 private Status insertManagerRow(Node node, String parent_uuid, Manager row) {
1228 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1231 private Status insertCapabilityRow(Node node, String parent_uuid, Capability row) {
1232 return new Status(StatusCode.NOTIMPLEMENTED, "Insert operation for this Table is not implemented yet.");
1235 private Status deleteBridgeRow(Node node, String uuid) {
1238 if (connectionService == null) {
1239 logger.error("Couldn't refer to the ConnectionService");
1240 return new Status(StatusCode.NOSERVICE);
1242 Connection connection = this.getConnection(node);
1243 if (connection == null) {
1244 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1246 Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
1247 Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
1248 Operation delBrRequest = null;
1250 if (ovsTable == null || brTable == null || uuid == null || brTable.get(uuid) == null) {
1251 return new Status(StatusCode.NOTFOUND, "");
1254 UUID bridgeUuidPair = new UUID(uuid);
1255 Mutation bm = new Mutation("bridges", Mutator.DELETE, bridgeUuidPair);
1256 List<Mutation> mutations = new ArrayList<Mutation>();
1259 UUID ovsUuid = new UUID((String) ovsTable.keySet().toArray()[0]);
1260 Condition condition = new Condition("_uuid", Function.EQUALS, ovsUuid);
1261 List<Condition> where = new ArrayList<Condition>();
1262 where.add(condition);
1263 delBrRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations);
1265 TransactBuilder transaction = new TransactBuilder();
1266 transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delBrRequest)));
1268 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1269 List<OperationResult> tr = transResponse.get();
1270 List<Operation> requests = transaction.getRequests();
1271 Status status = new Status(StatusCode.SUCCESS);
1272 for (int i = 0; i < tr.size(); i++) {
1273 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
1274 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
1275 OperationResult result = tr.get(i);
1276 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1280 if (tr.size() > requests.size()) {
1281 OperationResult result = tr.get(tr.size() - 1);
1282 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}",
1283 uuid, result.getError(), result.getDetails());
1284 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1287 } catch (Exception e) {
1288 e.printStackTrace();
1290 return new Status(StatusCode.INTERNALERROR);
1293 private Status deletePortRow(Node node, String uuid) {
1295 // Check there is a connectionService
1296 if (connectionService == null) {
1297 logger.error("Couldn't refer to the ConnectionService");
1298 return new Status(StatusCode.NOSERVICE);
1301 // Establish the connection
1302 Connection connection = this.getConnection(node);
1303 if (connection == null) {
1304 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1307 // Ports have a 0:n relationship with Bridges, so need to MUTATE BRIDGE row and DELETE PORT row
1308 Map<String, Table<?>> bridgeTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
1309 Map<String, Table<?>> portTable = inventoryServiceInternal.getTableCache(node, Port.NAME.getName());
1311 // Initialise the actual request var
1312 Operation delPortRequest = null;
1314 // Check that the UUID exists
1315 if (bridgeTable == null || portTable == null || uuid == null || portTable.get(uuid) == null) {
1316 return new Status(StatusCode.NOTFOUND, "");
1319 // Prepare the mutator to remove the port UUID from the "ports" list in the BRIDGE TABLE
1320 UUID portUuid = new UUID(uuid);
1321 Mutation portMutator = new Mutation("ports", Mutator.DELETE, portUuid);
1322 List<Mutation> mutations = new ArrayList<Mutation>();
1323 mutations.add(portMutator);
1325 //Iterate over the list of bridgeUUIDs that contain the portUUID and add them to the mutator
1326 Status status = new Status(StatusCode.SUCCESS);
1328 Condition condition = new Condition("ports", Function.INCLUDES, portUuid);
1329 List<Condition> where = new ArrayList<Condition>();
1330 where.add(condition);
1331 delPortRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
1333 TransactBuilder transaction = new TransactBuilder();
1334 transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delPortRequest)));
1336 // This executes the transaction.
1337 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1339 // Pull the responses
1340 List<OperationResult> tr = transResponse.get();
1341 List<Operation> requests = transaction.getRequests();
1343 for (int i = 0; i < tr.size(); i++) {
1344 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
1345 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
1346 OperationResult result = tr.get(i);
1347 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1351 if (tr.size() > requests.size()) {
1352 OperationResult result = tr.get(tr.size() - 1);
1353 logger.error("Error deleting Port: {}\n Error : {}\n Details : {}",
1354 uuid, result.getError(), result.getDetails());
1355 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1358 } catch (Exception e) {
1359 e.printStackTrace();
1361 return new Status(StatusCode.INTERNALERROR);
1364 private Status deleteInterfaceRow(Node node, String uuid) {
1365 // INTERFACE is a leaf table with no sub-ordinates, it's upstream is PORT
1367 // Check there is a connectionService
1368 if (connectionService == null) {
1369 logger.error("Couldn't refer to the ConnectionService");
1370 return new Status(StatusCode.NOSERVICE);
1373 // Establish the connection
1374 Connection connection = this.getConnection(node);
1375 if (connection == null) {
1376 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1379 // Pull the entire Port and Interface TABLES, to get a ROW, they will need to be cast to their Table type
1380 Map<String, Table<?>> portTable = inventoryServiceInternal.getTableCache(node, Port.NAME.getName());
1381 Map<String, Table<?>> interfaceTable = inventoryServiceInternal.getTableCache(node, Interface.NAME.getName());
1383 // Initialise the actual request var
1384 Operation delInterfaceRequest = null;
1385 Operation findInterfaceRequest = null;
1387 // Check that the UUID exists
1388 if (portTable == null || interfaceTable == null || uuid == null || interfaceTable.get(uuid) == null) {
1389 return new Status(StatusCode.NOTFOUND, "");
1392 UUID interfaceUuid = new UUID(uuid);
1393 // Need to check if this is the last interface for that port. Cannot delete last interface.
1394 for (int i=0 ; i < portTable.values().size(); i++){
1395 Port port = (Port)portTable.values().toArray()[i];
1396 if ((port.getInterfaces().size() == 1) && (port.getInterfaces().toString().contains(uuid))){
1397 return new Status(StatusCode.BADREQUEST, "Cannot delete last interface from port");
1401 // Prepare the mutator to remove the INTERFACE UUID from the "interfaces" list in the PORT TABLE
1402 // This will be combined with a WHERE operator to narrow down rows to Mutate.
1403 // This mutator looks in column "interfaces" to DELETE occurences of "interfaceUuid"
1405 Mutation interfaceMutator = new Mutation("interfaces", Mutator.DELETE, interfaceUuid);
1406 List<Mutation> mutations = new ArrayList<Mutation>();
1407 mutations.add(interfaceMutator);
1409 //As per the OVSDB spec, a Mutate can be performed across a number of row, so look for instances
1410 // of the interfaceUuid that are in the Port table
1411 Condition condition = new Condition("interfaces", Function.INCLUDES, interfaceUuid);
1412 List<Condition>where = new ArrayList<Condition>();
1413 where.add(condition);
1414 delInterfaceRequest = new MutateOperation(Port.NAME.getName(), where, mutations);
1416 TransactBuilder transaction = new TransactBuilder();
1417 transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delInterfaceRequest)));
1419 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1420 List<OperationResult> tr = transResponse.get();
1421 List<Operation> requests = transaction.getRequests();
1422 Status status = new Status(StatusCode.SUCCESS);
1423 for (int i = 0; i < tr.size(); i++) {
1424 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
1425 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
1426 OperationResult result = tr.get(i);
1427 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1431 if (tr.size() > requests.size()) {
1432 OperationResult result = tr.get(tr.size() - 1);
1433 logger.error("Error deleting Port: {}\n Error : {}\n Details : {}",
1434 uuid, result.getError(), result.getDetails());
1435 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1438 } catch (Exception e) {
1439 e.printStackTrace();
1441 return new Status(StatusCode.INTERNALERROR);
1444 private Status deleteOpen_vSwitchRow(Node node, String uuid) {
1445 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1448 private Status deleteControllerRow(Node node, String uuid) {
1450 // Check there is a connectionService
1451 if (connectionService == null) {
1452 logger.error("Couldn't refer to the ConnectionService");
1453 return new Status(StatusCode.NOSERVICE);
1456 // Establish the connection
1457 Connection connection = this.getConnection(node);
1458 if (connection == null) {
1459 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1462 // Controllers have a 0:n relationship with Bridges, so need to MUTATE BRIDGE row and DELETE PORT row
1463 Map<String, Table<?>> bridgeTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
1464 Map<String, Table<?>> controllerTable = inventoryServiceInternal.getTableCache(node, Controller.NAME.getName());
1466 // Initialise the actual request var
1467 Operation delControllerRequest = null;
1469 // Check that the UUID exists
1470 if (bridgeTable == null || controllerTable == null || uuid == null || controllerTable.get(uuid) == null) {
1471 return new Status(StatusCode.NOTFOUND, "");
1474 // Prepare the mutator to remove the controller UUID from the "ports" list in the BRIDGE TABLE
1475 UUID controllerUuid = new UUID(uuid);
1476 Mutation controllerMutator = new Mutation("controller", Mutator.DELETE, controllerUuid);
1477 List<Mutation> mutations = new ArrayList<Mutation>();
1478 mutations.add(controllerMutator);
1480 //Iterate over the list of bridgeUUIDs that contain the portUUID and add them to the mutator
1481 Status status = new Status(StatusCode.SUCCESS);
1483 Condition condition = new Condition("controller", Function.INCLUDES, controllerUuid);
1484 List<Condition> where = new ArrayList<Condition>();
1485 where.add(condition);
1486 delControllerRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
1488 TransactBuilder transaction = new TransactBuilder();
1489 transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delControllerRequest)));
1491 // This executes the transaction.
1492 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1494 // Pull the responses
1495 List<OperationResult> tr = transResponse.get();
1496 List<Operation> requests = transaction.getRequests();
1498 for (int i = 0; i < tr.size(); i++) {
1499 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
1500 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
1501 OperationResult result = tr.get(i);
1502 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1506 if (tr.size() > requests.size()) {
1507 OperationResult result = tr.get(tr.size() - 1);
1508 logger.error("Error deleting Controller : {}\n Error : {}\n Details : {}",
1509 uuid, result.getError(), result.getDetails());
1510 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1513 } catch (Exception e) {
1514 e.printStackTrace();
1516 return new Status(StatusCode.INTERNALERROR);
1520 private Status deleteSSLRow(Node node, String uuid) {
1521 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1524 private Status deleteSflowRow(Node node, String uuid) {
1525 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1528 private Status deleteQueueRow(Node node, String uuid) {
1529 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1532 private Status deleteQosRow(Node node, String uuid) {
1533 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1536 private Status deleteNetFlowRow(Node node, String uuid) {
1537 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1540 private Status deleteMirrorRow(Node node, String uuid) {
1541 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1544 private Status deleteManagerRow(Node node, String uuid) {
1545 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1548 private Status deleteCapabilityRow(Node node, String uuid) {
1549 return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1552 public void _ovsconnect (CommandInterpreter ci) {
1553 String bridgeName = ci.nextArgument();
1554 if (bridgeName == null) {
1555 ci.println("Please enter Bridge Name");
1559 String ovsdbserver = ci.nextArgument();
1560 if (ovsdbserver == null) {
1561 ci.println("Please enter valid IP-Address");
1565 InetAddress.getByName(ovsdbserver);
1566 } catch (Exception e) {
1567 e.printStackTrace();
1568 ci.println("Please enter valid IP-Address");
1571 String port = ci.nextArgument();
1576 ci.println("connecting to ovsdb server : "+ovsdbserver+":"+port+" ... ");
1577 Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
1578 params.put(ConnectionConstants.ADDRESS, ovsdbserver);
1579 params.put(ConnectionConstants.PORT, port);
1580 Node node = connectionService.connect(bridgeName, params);
1581 if (node != null) ci.println("Node Name: "+node.toString());
1582 else ci.println("Could not connect to Node");
1585 public void _addBridge (CommandInterpreter ci) {
1586 String nodeName = ci.nextArgument();
1587 if (nodeName == null) {
1588 ci.println("Please enter Node Name");
1591 String bridgeName = ci.nextArgument();
1592 if (bridgeName == null) {
1593 ci.println("Please enter Bridge Name");
1599 Node node = Node.fromString(nodeName);
1601 ci.println("Invalid Node");
1604 status = this.createBridgeDomain(node, bridgeName, null);
1605 ci.println("Bridge creation status : "+status.toString());
1606 } catch (Throwable e) {
1607 // TODO Auto-generated catch block
1608 e.printStackTrace();
1609 ci.println("Failed to create Bridge "+bridgeName);
1613 public void _getBridgeDomains (CommandInterpreter ci) {
1614 String nodeName = ci.nextArgument();
1615 if (nodeName == null) {
1616 ci.println("Please enter Node Name");
1621 List<String> brlist = new ArrayList<String>();
1623 Node node = Node.fromString(nodeName);
1624 brlist = this.getBridgeDomains(node);
1626 ci.println("Invalid Node");
1629 ci.println("Existing Bridges: "+brlist.toString());
1630 } catch (Throwable e) {
1631 e.printStackTrace();
1632 ci.println("Failed to list Bridges");
1636 public void _deleteBridgeDomain (CommandInterpreter ci) {
1637 String nodeName = ci.nextArgument();
1638 if (nodeName == null) {
1639 ci.println("Please enter Node Name");
1642 String bridgeName = ci.nextArgument();
1643 if (bridgeName == null) {
1644 ci.println("Please enter Bridge Name");
1649 Node node = Node.fromString(nodeName);
1651 ci.println("Invalid Node");
1654 status = this.deleteBridgeDomain(node, bridgeName);
1655 ci.println("Bridge deletion status : "+status.toString());
1656 } catch (Throwable e) {
1657 e.printStackTrace();
1658 ci.println("Failed to delete Bridge "+bridgeName);
1662 public void _addPort (CommandInterpreter ci) {
1663 String nodeName = ci.nextArgument();
1664 if (nodeName == null) {
1665 ci.println("Please enter Node Name");
1669 String bridgeName = ci.nextArgument();
1670 if (bridgeName == null) {
1671 ci.println("Please enter Bridge Name");
1675 String portName = ci.nextArgument();
1676 if (portName == null) {
1677 ci.println("Please enter Port Name");
1681 String type = ci.nextArgument();
1683 Map<String, String> configs = new HashMap<String, String>();
1685 String configKey = ci.nextArgument();
1686 if (configKey == null) break;
1687 String configValue = ci.nextArgument();
1688 if (configValue == null) break;
1689 configs.put(configKey, configValue);
1692 Map<ConfigConstants, Object> customConfigs = null;
1694 customConfigs = new HashMap<ConfigConstants, Object>();
1695 customConfigs.put(ConfigConstants.TYPE, type);
1698 if (configs.size() > 0) {
1699 if (customConfigs == null) customConfigs = new HashMap<ConfigConstants, Object>();
1700 customConfigs.put(ConfigConstants.CUSTOM, configs);
1701 ci.println(customConfigs.toString());
1705 Node node = Node.fromString(nodeName);
1707 ci.println("Invalid Node");
1710 status = this.addPort(node, bridgeName, portName, customConfigs);
1711 ci.println("Port creation status : "+status.toString());
1712 } catch (Throwable e) {
1713 // TODO Auto-generated catch block
1714 e.printStackTrace();
1715 ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
1719 public void _deletePort (CommandInterpreter ci) {
1720 String nodeName = ci.nextArgument();
1721 if (nodeName == null) {
1722 ci.println("Please enter Node Name");
1726 String bridgeName = ci.nextArgument();
1727 if (bridgeName == null) {
1728 ci.println("Please enter Bridge Name");
1732 String portName = ci.nextArgument();
1733 if (portName == null) {
1734 ci.println("Please enter Port Name");
1740 Node node = Node.fromString(nodeName);
1742 ci.println("Invalid Node");
1745 status = this.deletePort(node, bridgeName, portName);
1746 ci.println("Port deletion status : "+status.toString());
1747 } catch (Throwable e) {
1748 // TODO Auto-generated catch block
1749 e.printStackTrace();
1750 ci.println("Failed to delete Port "+portName+" in Bridge "+bridgeName);
1754 public void _addPortVlan (CommandInterpreter ci) {
1755 String nodeName = ci.nextArgument();
1756 if (nodeName == null) {
1757 ci.println("Please enter Node Name");
1761 String bridgeName = ci.nextArgument();
1762 if (bridgeName == null) {
1763 ci.println("Please enter Bridge Name");
1767 String portName = ci.nextArgument();
1768 if (portName == null) {
1769 ci.println("Please enter Port Name");
1773 String vlan = ci.nextArgument();
1775 ci.println("Please enter Valid Vlan");
1779 Integer.parseInt(vlan);
1780 } catch (Exception e) {
1781 ci.println("Please enter Valid Vlan");
1786 Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
1787 configs.put(ConfigConstants.TYPE, "VLAN");
1788 configs.put(ConfigConstants.VLAN, vlan);
1792 Node node = Node.fromString(nodeName);
1794 ci.println("Invalid Node");
1797 status = this.addPort(node, bridgeName, portName, configs);
1798 ci.println("Port creation status : "+status.toString());
1799 } catch (Throwable e) {
1800 // TODO Auto-generated catch block
1801 e.printStackTrace();
1802 ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
1806 public void _addTunnel (CommandInterpreter ci) {
1807 String nodeName = ci.nextArgument();
1808 if (nodeName == null) {
1809 ci.println("Please enter Node Name");
1813 String bridgeName = ci.nextArgument();
1814 if (bridgeName == null) {
1815 ci.println("Please enter Bridge Name");
1819 String portName = ci.nextArgument();
1820 if (portName == null) {
1821 ci.println("Please enter Port Name");
1825 String tunnelType = ci.nextArgument();
1826 if (tunnelType == null) {
1827 ci.println("Please enter Tunnel Type");
1831 String remoteIp = ci.nextArgument();
1832 if (remoteIp == null) {
1833 ci.println("Please enter valid Remote IP Address");
1838 InetAddress.getByName(remoteIp);
1839 } catch (Exception e) {
1840 e.printStackTrace();
1841 ci.println("Please enter valid Remote IP Address");
1845 Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
1846 configs.put(ConfigConstants.TYPE, "TUNNEL");
1847 configs.put(ConfigConstants.TUNNEL_TYPE, tunnelType);
1848 configs.put(ConfigConstants.DEST_IP, remoteIp);
1852 Node node = Node.fromString(nodeName);
1854 ci.println("Invalid Node");
1857 status = this.addPort(node, bridgeName, portName, configs);
1858 ci.println("Port creation status : "+status.toString());
1859 } catch (Throwable e) {
1860 // TODO Auto-generated catch block
1861 e.printStackTrace();
1862 ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
1866 public void _printCache (CommandInterpreter ci) {
1867 String nodeName = ci.nextArgument();
1868 if (nodeName == null) {
1869 ci.println("Please enter Node Name");
1872 Node node = Node.fromString(nodeName);
1874 ci.println("Invalid Node");
1877 inventoryServiceInternal.printCache(node);
1880 public void _forceConnect (CommandInterpreter ci) {
1881 String force = ci.nextArgument();
1882 if (force.equalsIgnoreCase("YES")) forceConnect = true;
1883 else if (force.equalsIgnoreCase("NO")) forceConnect = false;
1884 else ci.println("Please enter YES or NO.");
1885 ci.println("Current ForceConnect State : "+forceConnect);
1890 public String getHelp() {
1891 StringBuffer help = new StringBuffer();
1892 help.append("---OVSDB CLI---\n");
1893 help.append("\t ovsconnect <ConnectionName> <ip-address> - Connect to OVSDB\n");
1894 help.append("\t addBridge <Node> <BridgeName> - Add Bridge\n");
1895 help.append("\t getBridgeDomains <Node> - Get Bridges\n");
1896 help.append("\t deleteBridgeDomain <Node> <BridgeName> - Delete a Bridge\n");
1897 help.append("\t addPort <Node> <BridgeName> <PortName> <type> <options pairs> - Add Port\n");
1898 help.append("\t deletePort <Node> <BridgeName> <PortName> - Delete Port\n");
1899 help.append("\t addPortVlan <Node> <BridgeName> <PortName> <vlan> - Add Port, Vlan\n");
1900 help.append("\t addTunnel <Node> <Bridge> <Port> <tunnel-type> <remote-ip> - Add Tunnel\n");
1901 help.append("\t printCache <Node> - Prints Table Cache");
1902 return help.toString();