Added delete[Port|Interface|Controller]Row methods
[ovsdb.git] / ovsdb / src / main / java / org / opendaylight / ovsdb / plugin / ConfigurationService.java
1 package org.opendaylight.ovsdb.plugin;
2
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;
9 import java.util.List;
10 import java.util.Map;
11
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;
54
55 import com.fasterxml.jackson.databind.ObjectMapper;
56 import com.google.common.util.concurrent.ListenableFuture;
57
58 public class ConfigurationService implements IPluginInBridgeDomainConfigService, OVSDBConfigService,
59                                              CommandProvider
60 {
61     private static final Logger logger = LoggerFactory
62             .getLogger(ConfigurationService.class);
63
64     IConnectionServiceInternal connectionService;
65     InventoryServiceInternal inventoryServiceInternal;
66     boolean forceConnect = false;
67
68     void init() {
69     }
70
71     /**
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.
75      *
76      */
77     void destroy() {
78     }
79
80     /**
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
83      *
84      */
85     void start() {
86         registerWithOSGIConsole();
87     }
88
89     private void registerWithOSGIConsole() {
90         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
91                 .getBundleContext();
92         bundleContext.registerService(CommandProvider.class.getName(), this,
93                 null);
94     }
95
96     /**
97      * Function called by the dependency manager before the services exported by
98      * the component are unregistered, this will be followed by a "destroy ()"
99      * calls
100      *
101      */
102     void stop() {
103     }
104
105     public void setConnectionServiceInternal(IConnectionServiceInternal connectionService) {
106         this.connectionService = connectionService;
107     }
108
109     public void unsetConnectionServiceInternal(IConnectionServiceInternal connectionService) {
110         if (this.connectionService == connectionService) {
111             this.connectionService = null;
112         }
113     }
114
115     public void setInventoryServiceInternal(InventoryServiceInternal inventoryServiceInternal) {
116         this.inventoryServiceInternal = inventoryServiceInternal;
117     }
118
119     public void unsetInventoryServiceInternal(InventoryServiceInternal inventoryServiceInternal) {
120         if (this.inventoryServiceInternal == inventoryServiceInternal) {
121             this.inventoryServiceInternal = null;
122         }
123     }
124
125     private Connection getConnection (Node node) {
126         Connection connection = connectionService.getConnection(node);
127         if (connection == null || !connection.getChannel().isActive()) {
128             return null;
129         }
130
131         return connection;
132     }
133
134     /**
135      * Add a new bridge
136      * @param node Node serving this configuration service
137      * @param bridgeConnectorIdentifier String representation of a Bridge Connector
138      * @return Bridge Connector configurations
139      */
140     @Override
141     public Status createBridgeDomain(Node node, String bridgeIdentifier,
142             Map<ConfigConstants, Object> configs) throws Throwable {
143         try{
144             if (connectionService == null) {
145                 logger.error("Couldn't refer to the ConnectionService");
146                 return new Status(StatusCode.NOSERVICE);
147             }
148
149             Connection connection = this.getConnection(node);
150             if (connection == null) {
151                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
152             }
153
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";
159
160             Operation addSwitchRequest = null;
161
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>();
167                 mutations.add(bm);
168
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);
174             }
175             else{
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);
182             }
183
184             Bridge bridgeRow = new Bridge();
185             bridgeRow.setName(bridgeIdentifier);
186             OvsDBSet<UUID> ports = new OvsDBSet<UUID>();
187             UUID port = new UUID(newPort);
188             ports.add(port);
189             bridgeRow.setPorts(ports);
190             InsertOperation addBridgeRequest = new InsertOperation(Bridge.NAME.getName(), newBridge, bridgeRow);
191
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);
199
200             Interface interfaceRow = new Interface();
201             interfaceRow.setName(bridgeIdentifier);
202             interfaceRow.setType("internal");
203             InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(), newInterface, interfaceRow);
204
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>();
209             mutations.add(bm);
210
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);
216
217             TransactBuilder transaction = new TransactBuilder();
218             transaction.addOperations(new ArrayList<Operation>(
219                                       Arrays.asList(addSwitchRequest,
220                                                     addIntfRequest,
221                                                     addPortRequest,
222                                                     addBridgeRequest,
223                                                     updateCfgVerRequest)));
224
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());
234                 }
235             }
236
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,
240                                                                                        result.getError(),
241                                                                                        result.getDetails());
242                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
243             }
244             if (status.isSuccess()) {
245                 setBridgeOFController(node, bridgeIdentifier);
246             }
247             return status;
248         } catch(Exception e){
249             e.printStackTrace();
250         }
251         return new Status(StatusCode.INTERNALERROR);
252     }
253
254     /**
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
260      */
261     @Override
262     public Status addPort(Node node, String bridgeIdentifier, String portIdentifier,
263                           Map<ConfigConstants, Object> configs) {
264         try{
265             if (connectionService == null) {
266                 logger.error("Couldn't refer to the ConnectionService");
267                 return new Status(StatusCode.NOSERVICE);
268             }
269             Connection connection = this.getConnection(node);
270             if (connection == null) {
271                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
272             }
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";
278
279                 if(brTable != null){
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)) {
285                             brUuid = uuid;
286                         }
287                     }
288
289                     UUID brUuidPair = new UUID(newPort);
290                     Mutation bm = new Mutation("ports", Mutator.INSERT, brUuidPair);
291                     List<Mutation> mutations = new ArrayList<Mutation>();
292                     mutations.add(bm);
293
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);
299
300                     OvsDBMap<String, String> options = null;
301                     String type = 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));
310                             }
311                         }
312                     }
313
314                     Interface interfaceRow = new Interface();
315                     interfaceRow.setName(portIdentifier);
316
317                     if (type != null) {
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());
327                         }
328                     }
329                     if (options != null) {
330                         interfaceRow.setOptions(options);
331                     }
332
333                     InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(),
334                             newInterface, interfaceRow);
335
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);
344
345                     TransactBuilder transaction = new TransactBuilder();
346                     transaction.addOperations(new ArrayList<Operation>
347                             (Arrays.asList(addBrMutRequest, addPortRequest, addIntfRequest)));
348
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());
358                         }
359                     }
360
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,
364                                 result.getError(),
365                                 result.getDetails());
366                         status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
367                     }
368                     return status;
369                 }
370                 return new Status(StatusCode.INTERNALERROR);
371             }
372         } catch(Exception e){
373             e.printStackTrace();
374         }
375         return new Status(StatusCode.INTERNALERROR);
376     }
377
378     /**
379      * Implements the OVS Connection for Managers
380      *
381      * @param node Node serving this configuration service
382      * @param String with IP and connection types
383      */
384     @SuppressWarnings("unchecked")
385     public boolean setManager(Node node, String managerip) throws Throwable{
386         try{
387             if (connectionService == null) {
388                 logger.error("Couldn't refer to the ConnectionService");
389                 return false;
390             }
391             Connection connection = this.getConnection(node);
392             if (connection == null) {
393                 return false;
394             }
395
396             if (connection != null) {
397                 String newmanager = "new_manager";
398
399                 OVSInstance instance = OVSInstance.monitorOVS(connection);
400
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();
407
408                 //OVS Table Update
409                 ovsoutter.put("where", ovsalist1);
410                 ovsalist1.add(ovsalist2);
411                 ovsalist2.add("_uuid");
412                 ovsalist2.add("==");
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);
422
423                 Map mgroutside = new LinkedHashMap();
424                 Map mgrinside = new LinkedHashMap();
425
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);
432
433                 Object[] params = {"Open_vSwitch", ovsoutter, mgroutside};
434                 OvsdbMessage msg = new OvsdbMessage("transact", params);
435
436                 //connection.sendMessage(msg);
437
438             }
439         }catch(Exception e){
440             e.printStackTrace();
441         }
442         return true;
443     }
444
445     @Override
446     public Status addBridgeDomainConfig(Node node, String bridgeIdentfier,
447             Map<ConfigConstants, Object> configs) {
448         String mgmt = (String)configs.get(ConfigConstants.MGMT);
449         if (mgmt != null) {
450             try {
451                 if (setManager(node, mgmt)) return new Status(StatusCode.SUCCESS);
452             } catch (Throwable e) {
453                 // TODO Auto-generated catch block
454                 e.printStackTrace();
455                 return new Status(StatusCode.INTERNALERROR);
456             }
457         }
458         return new Status(StatusCode.BADREQUEST);
459     }
460
461     @Override
462     public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier,
463             Map<ConfigConstants, Object> configs) {
464         // TODO Auto-generated method stub
465         return null;
466     }
467
468     @Override
469     public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier) {
470
471             try{
472                 if (connectionService == null) {
473                     logger.error("Couldn't refer to the ConnectionService");
474                     return new Status(StatusCode.NOSERVICE);
475                 }
476
477                 Connection connection = this.getConnection(node);
478                 if (connection == null) {
479                     return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
480                 }
481
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;
487                 if(brTable != null){
488                     for (String uuid : brTable.keySet()) {
489                         Bridge bridge = (Bridge) brTable.get(uuid);
490                         if (bridge.getName().contains(bridgeIdentifier)) {
491                             brUuid = uuid;
492                         }
493                     }
494                 }
495             if(portTable != null){
496                 for (String uuid : portTable.keySet()) {
497                     Port port = (Port) portTable.get(uuid);
498                     if (port.getName().contains(portIdentifier)) {
499                         portUuid = uuid;
500                     }
501                 }
502             }
503
504             UUID portUuidPair = new UUID(portUuid);
505             Mutation bm = new Mutation("ports", Mutator.DELETE, portUuidPair);
506             List<Mutation> mutations = new ArrayList<Mutation>();
507             mutations.add(bm);
508
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);
514
515             TransactBuilder transaction = new TransactBuilder();
516             transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delPortRequest)));
517
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());
527                 }
528             }
529
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,
533                         result.getError(),
534                         result.getDetails());
535                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
536             }
537             return status;
538         } catch(Exception e){
539             e.printStackTrace();
540         }
541         return new Status(StatusCode.INTERNALERROR);
542     }
543
544     @Override
545     public Node getBridgeDomainNode(Node node, String bridgeIdentifier) {
546         // TODO Auto-generated method stub
547         return null;
548     }
549
550     @Override
551     public Map<ConfigConstants, Object> getPortConfigs(Node node, String bridgeIdentifier,
552             String portIdentifier) {
553         // TODO Auto-generated method stub
554         return null;
555     }
556
557     @Override
558     public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier,
559             Map<ConfigConstants, Object> configs) {
560         // TODO Auto-generated method stub
561         return null;
562     }
563
564     @Override
565     public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier,
566             Map<ConfigConstants, Object> configs) {
567         // TODO Auto-generated method stub
568         return null;
569     }
570
571     @Override
572     public Status deleteBridgeDomain(Node node, String bridgeIdentifier) {
573
574         try {
575             if (connectionService == null) {
576                 logger.error("Couldn't refer to the ConnectionService");
577                 return new Status(StatusCode.NOSERVICE);
578             }
579             Connection connection = this.getConnection(node);
580             if (connection == null) {
581                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
582             }
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;
588
589             if (brTable != null) {
590                 for (String uuid : brTable.keySet()) {
591                     Bridge bridge = (Bridge) brTable.get(uuid);
592                     if (bridge.getName().contains(bridgeIdentifier)) {
593                         brUuid = uuid;
594                     }
595                 }
596             }
597             if (ovsTable != null) {
598                 ovsUuid = (String) ovsTable.keySet().toArray()[0];
599             }
600             UUID bridgeUuidPair = new UUID(brUuid);
601             Mutation bm = new Mutation("bridges", Mutator.DELETE, bridgeUuidPair);
602             List<Mutation> mutations = new ArrayList<Mutation>();
603             mutations.add(bm);
604
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);
610
611             TransactBuilder transaction = new TransactBuilder();
612             transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delBrRequest)));
613
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());
623                 }
624             }
625
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());
631             }
632             return status;
633         } catch (Exception e) {
634             e.printStackTrace();
635         }
636         return new Status(StatusCode.INTERNALERROR);
637     }
638
639     @Override
640     public Map<ConfigConstants, Object> getBridgeDomainConfigs(Node node, String bridgeIdentifier) {
641         // TODO Auto-generated method stub
642         return null;
643     }
644
645     @Override
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());
653             }
654         }
655         return brlist;
656     }
657
658     @Override
659     public NodeConnector getNodeConnector(Node arg0, String arg1, String arg2) {
660         return null;
661     }
662
663     Boolean setBridgeOFController(Node node, String bridgeIdentifier) {
664         if (connectionService == null) {
665             logger.error("Couldn't refer to the ConnectionService");
666             return false;
667         }
668
669         try{
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);
675                 }
676             }
677         } catch(Exception e) {
678             e.printStackTrace();
679         }
680         return false;
681     }
682
683     @Override
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;
687
688         // Schema based Table handling will help fix this static Table handling.
689
690         if (row.getTableName().getName().equalsIgnoreCase("Bridge")) {
691             statusWithUUID = insertBridgeRow(node, parent_uuid, (Bridge)row);
692         }
693         else if (row.getTableName().getName().equalsIgnoreCase("Capbility")) {
694             statusWithUUID = insertCapabilityRow(node, parent_uuid, (Capability)row);
695         }
696         else if (row.getTableName().getName().equalsIgnoreCase("Controller")) {
697             statusWithUUID = insertControllerRow(node, parent_uuid, (Controller)row);
698         }
699         else if (row.getTableName().getName().equalsIgnoreCase("Interface")) {
700             statusWithUUID = insertInterfaceRow(node, parent_uuid, (Interface)row);
701         }
702         else if (row.getTableName().getName().equalsIgnoreCase("Manager")) {
703             statusWithUUID = insertManagerRow(node, parent_uuid, (Manager)row);
704         }
705         else if (row.getTableName().getName().equalsIgnoreCase("Mirror")) {
706             statusWithUUID = insertMirrorRow(node, parent_uuid, (Mirror)row);
707         }
708         else if (row.getTableName().getName().equalsIgnoreCase("NetFlow")) {
709             statusWithUUID = insertNetFlowRow(node, parent_uuid, (NetFlow)row);
710         }
711         else if (row.getTableName().getName().equalsIgnoreCase("Open_vSwitch")) {
712             statusWithUUID = insertOpen_vSwitchRow(node, (Open_vSwitch)row);
713         }
714         else if (row.getTableName().getName().equalsIgnoreCase("Port")) {
715             statusWithUUID = insertPortRow(node, parent_uuid, (Port)row);
716         }
717         else if (row.getTableName().getName().equalsIgnoreCase("QoS")) {
718             statusWithUUID = insertQosRow(node, parent_uuid, (Qos)row);
719         }
720         else if (row.getTableName().getName().equalsIgnoreCase("Queue")) {
721             statusWithUUID = insertQueueRow(node, parent_uuid, (Queue)row);
722         }
723         else if (row.getTableName().getName().equalsIgnoreCase("sFlow")) {
724             statusWithUUID = insertSflowRow(node, parent_uuid, (SFlow)row);
725         }
726         else if (row.getTableName().getName().equalsIgnoreCase("SSL")) {
727             statusWithUUID = insertSSLRow(node, parent_uuid, (SSL)row);
728         }
729         return statusWithUUID;
730     }
731
732
733     @Override
734     public Status updateRow (Node node, String tableName, String parentUUID, String rowUUID, Table<?> row) {
735         try{
736             if (connectionService == null) {
737                 logger.error("Couldn't refer to the ConnectionService");
738                 return new Status(StatusCode.NOSERVICE);
739             }
740
741             Connection connection = this.getConnection(node);
742             if (connection == null) {
743                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
744             }
745
746             Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
747
748             if (ovsTable == null) {
749                 return new Status(StatusCode.NOTFOUND, "There are no Open_vSwitch instance in the Open_vSwitch table");
750             }
751
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);
757
758             TransactBuilder transaction = new TransactBuilder();
759             transaction.addOperations(new ArrayList<Operation>(
760                                       Arrays.asList(updateRequest)));
761
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());
771                 }
772             }
773
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,
777                                                                                        result.getError(),
778                                                                                        result.getDetails());
779                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
780             }
781             if (status.isSuccess()) {
782                 status = new Status(StatusCode.SUCCESS);
783             }
784             return status;
785         } catch(Exception e){
786             e.printStackTrace();
787         }
788         return new Status(StatusCode.INTERNALERROR);
789     }
790
791     @Override
792     public Status deleteRow(Node node, String tableName, String uuid) {
793         if (tableName.equalsIgnoreCase("Bridge")) {
794             return deleteBridgeRow(node, uuid);
795         }
796         else if (tableName.equalsIgnoreCase("Capbility")) {
797             return deleteCapabilityRow(node, uuid);
798         }
799         else if (tableName.equalsIgnoreCase("Controller")) {
800             return deleteControllerRow(node, uuid);
801         }
802         else if (tableName.equalsIgnoreCase("Interface")) {
803             return deleteInterfaceRow(node, uuid);
804         }
805         else if (tableName.equalsIgnoreCase("Manager")) {
806             return deleteManagerRow(node, uuid);
807         }
808         else if (tableName.equalsIgnoreCase("Mirror")) {
809             return deleteMirrorRow(node, uuid);
810         }
811         else if (tableName.equalsIgnoreCase("NetFlow")) {
812             return deleteNetFlowRow(node, uuid);
813         }
814         else if (tableName.equalsIgnoreCase("Open_vSwitch")) {
815             return deleteOpen_vSwitchRow(node, uuid);
816         }
817         else if (tableName.equalsIgnoreCase("Port")) {
818             return deletePortRow(node, uuid);
819         }
820         else if (tableName.equalsIgnoreCase("QoS")) {
821             return deleteQosRow(node, uuid);
822         }
823         else if (tableName.equalsIgnoreCase("Queue")) {
824             return deleteQueueRow(node, uuid);
825         }
826         else if (tableName.equalsIgnoreCase("sFlow")) {
827             return deleteSflowRow(node, uuid);
828         }
829         else if (tableName.equalsIgnoreCase("SSL")) {
830             return deleteSSLRow(node, uuid);
831         }
832         return new Status(StatusCode.NOTFOUND, "Table "+tableName+" not supported");
833     }
834
835     @Override
836     public Map<String, Table<?>> getRows(Node node, String tableName) throws Exception{
837         try{
838             if (inventoryServiceInternal == null) {
839                 throw new Exception("Inventory Service is Unavailable.");
840             }
841             Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, tableName);
842             return ovsTable;
843         } catch(Exception e){
844             throw new Exception("Unable to read table due to "+e.getMessage());
845         }
846     }
847
848     @Override
849     public Table<?> getRow(Node node, String tableName, String uuid) throws Exception {
850         try{
851             if (inventoryServiceInternal == null) {
852                 throw new Exception("Inventory Service is Unavailable.");
853             }
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());
859         }
860     }
861
862     @Override
863     public String getSerializedRows(Node node, String tableName) throws Exception{
864         try{
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());
871         }
872     }
873
874     @Override
875     public String getSerializedRow(Node node, String tableName, String uuid) throws Exception {
876         try{
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());
883         }
884     }
885
886     @Override
887     public List<String> getTables(Node node) {
888         // TODO Auto-generated method stub
889         return null;
890     }
891
892     private Status insertBridgeRow(Node node, String open_VSwitch_uuid, Bridge bridgeRow) {
893         try{
894             if (connectionService == null) {
895                 logger.error("Couldn't refer to the ConnectionService");
896                 return new Status(StatusCode.NOSERVICE);
897             }
898
899             Connection connection = this.getConnection(node);
900             if (connection == null) {
901                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
902             }
903
904             Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
905
906             if (ovsTable == null) {
907                 return new Status(StatusCode.NOTFOUND, "There are no Open_vSwitch instance in the Open_vSwitch table");
908             }
909
910             String newBridge = "new_bridge";
911
912             Operation addSwitchRequest = null;
913
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>();
919             mutations.add(bm);
920
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);
926
927             InsertOperation addBridgeRequest = new InsertOperation(Bridge.NAME.getName(), newBridge, bridgeRow);
928
929             TransactBuilder transaction = new TransactBuilder();
930             transaction.addOperations(new ArrayList<Operation>(
931                                       Arrays.asList(addSwitchRequest,
932                                                     addBridgeRequest)));
933
934             int bridgeInsertIndex = transaction.getRequests().indexOf(addBridgeRequest);
935
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());
945                 }
946             }
947
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(),
951                                                                                        result.getError(),
952                                                                                        result.getDetails());
953                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
954             }
955             if (status.isSuccess()) {
956                 UUID bridgeUUID = tr.get(bridgeInsertIndex).getUuid();
957                 status = new Status(StatusCode.SUCCESS, bridgeUUID.toString());
958             }
959             return status;
960         } catch(Exception e){
961             e.printStackTrace();
962         }
963         return new Status(StatusCode.INTERNALERROR);
964     }
965
966     private Status insertPortRow(Node node, String bridge_uuid, Port portRow) {
967         try{
968             if (connectionService == null) {
969                 logger.error("Couldn't refer to the ConnectionService");
970                 return new Status(StatusCode.NOSERVICE);
971             }
972             Connection connection = this.getConnection(node);
973             if (connection == null) {
974                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
975             }
976
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");
980             }
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>();
985             mutations.add(bm);
986
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);
992
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 :-(.
995
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);
1001
1002             OvsDBSet<UUID> interfaces = new OvsDBSet<UUID>();
1003             UUID interfaceid = new UUID(newInterface);
1004             interfaces.add(interfaceid);
1005             portRow.setInterfaces(interfaces);
1006
1007             InsertOperation addPortRequest = new InsertOperation(Port.NAME.getName(), newPort, portRow);
1008
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());
1022                 }
1023             }
1024
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(),
1028                         result.getError(),
1029                         result.getDetails());
1030                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1031             }
1032             if (status.isSuccess()) {
1033                 uuid = tr.get(portInsertIndex).getUuid();
1034                 status = new Status(StatusCode.SUCCESS, uuid.toString());
1035             }
1036
1037             return status;
1038         } catch (Exception e) {
1039             e.printStackTrace();
1040         }
1041         return new Status(StatusCode.INTERNALERROR);
1042     }
1043
1044     private Status insertInterfaceRow(Node node, String port_uuid, Interface interfaceRow) {
1045         try{
1046             if (connectionService == null) {
1047                 logger.error("Couldn't refer to the ConnectionService");
1048                 return new Status(StatusCode.NOSERVICE);
1049             }
1050             Connection connection = this.getConnection(node);
1051             if (connection == null) {
1052                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1053             }
1054
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");
1059             }
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);
1066
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);
1073
1074             // Create the interface row request
1075             InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(),newInterface, interfaceRow);
1076
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)));
1080
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());
1092                 }
1093             }
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(),
1097                         result.getError(),
1098                         result.getDetails());
1099                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1100             }
1101             if (status.isSuccess()) {
1102                 uuid = tr.get(intInsertIndex).getUuid();
1103                 status = new Status(StatusCode.SUCCESS, uuid.toString());
1104             }
1105             return status;
1106
1107         } catch (Exception e) {
1108             e.printStackTrace();
1109         }
1110         return new Status(StatusCode.INTERNALERROR);
1111     }
1112
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.");
1115     }
1116
1117     private Status insertControllerRow(Node node, String bridge_uuid, Controller row) {
1118         try{
1119             if (connectionService == null) {
1120                 logger.error("Couldn't refer to the ConnectionService");
1121                 return new Status(StatusCode.NOSERVICE);
1122             }
1123             Connection connection = this.getConnection(node);
1124             if (connection == null) {
1125                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1126             }
1127
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");
1131             }
1132
1133             Map<String, Table<?>> controllerCache = inventoryServiceInternal.getTableCache(node, Controller.NAME.getName());
1134
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())) {
1141                         uuid_name = uuid;
1142                         controllerExists = true;
1143                         break;
1144                     }
1145                 }
1146             }
1147
1148             UUID controllerUUID = new UUID(uuid_name);
1149             Mutation bm = new Mutation("controller", Mutator.INSERT, controllerUUID);
1150             List<Mutation> mutations = new ArrayList<Mutation>();
1151             mutations.add(bm);
1152
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;
1159
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);
1167             }
1168
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());
1178                 }
1179             }
1180
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(),
1184                         result.getError(),
1185                         result.getDetails());
1186                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
1187             }
1188             if (status.isSuccess()) {
1189                 if (controllerExists) {
1190                     status = new Status(StatusCode.SUCCESS, uuid_name);
1191                 } else {
1192                     uuid = tr.get(portInsertIndex).getUuid();
1193                     status = new Status(StatusCode.SUCCESS, uuid.toString());
1194                 }
1195             }
1196             return status;
1197         } catch (Exception e) {
1198             e.printStackTrace();
1199         }
1200         return new Status(StatusCode.INTERNALERROR);
1201     }
1202
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.");
1205     }
1206
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.");
1209     }
1210
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.");
1213     }
1214
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.");
1217     }
1218
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.");
1221     }
1222
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.");
1225     }
1226
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.");
1229     }
1230
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.");
1233     }
1234
1235     private Status deleteBridgeRow(Node node, String uuid) {
1236
1237         try {
1238             if (connectionService == null) {
1239                 logger.error("Couldn't refer to the ConnectionService");
1240                 return new Status(StatusCode.NOSERVICE);
1241             }
1242             Connection connection = this.getConnection(node);
1243             if (connection == null) {
1244                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
1245             }
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;
1249
1250             if (ovsTable == null || brTable == null || uuid == null || brTable.get(uuid) == null) {
1251                 return new Status(StatusCode.NOTFOUND, "");
1252             }
1253
1254             UUID bridgeUuidPair = new UUID(uuid);
1255             Mutation bm = new Mutation("bridges", Mutator.DELETE, bridgeUuidPair);
1256             List<Mutation> mutations = new ArrayList<Mutation>();
1257             mutations.add(bm);
1258
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);
1264
1265             TransactBuilder transaction = new TransactBuilder();
1266             transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delBrRequest)));
1267
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());
1277                 }
1278             }
1279
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());
1285             }
1286             return status;
1287         } catch (Exception e) {
1288             e.printStackTrace();
1289         }
1290         return new Status(StatusCode.INTERNALERROR);
1291     }
1292
1293     private Status deletePortRow(Node node, String uuid) {
1294         try {
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);
1299             }
1300
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");
1305             }
1306
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());
1310
1311             // Initialise the actual request var
1312             Operation delPortRequest = null;
1313
1314             // Check that the UUID exists
1315             if (bridgeTable == null || portTable == null || uuid == null || portTable.get(uuid) == null) {
1316                 return new Status(StatusCode.NOTFOUND, "");
1317             }
1318
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);
1324
1325             //Iterate over the list of bridgeUUIDs that contain the portUUID and add them to the mutator
1326             Status status = new Status(StatusCode.SUCCESS);
1327
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);
1332
1333             TransactBuilder transaction = new TransactBuilder();
1334             transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delPortRequest)));
1335
1336             // This executes the transaction.
1337             ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1338
1339             // Pull the responses
1340             List<OperationResult> tr = transResponse.get();
1341             List<Operation> requests = transaction.getRequests();
1342
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());
1348                 }
1349             }
1350
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());
1356             }
1357             return status;
1358         } catch (Exception e) {
1359             e.printStackTrace();
1360         }
1361         return new Status(StatusCode.INTERNALERROR);
1362     }
1363
1364     private Status deleteInterfaceRow(Node node, String uuid) {
1365         // INTERFACE is a leaf table with no sub-ordinates, it's upstream is PORT
1366         try {
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);
1371             }
1372
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");
1377             }
1378
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());
1382
1383             // Initialise the actual request var
1384             Operation delInterfaceRequest = null;
1385             Operation findInterfaceRequest = null;
1386
1387             // Check that the UUID exists
1388             if (portTable == null || interfaceTable == null || uuid == null || interfaceTable.get(uuid) == null) {
1389                 return new Status(StatusCode.NOTFOUND, "");
1390             }
1391
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");
1398                 }
1399             }
1400             // End Select
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"
1404
1405             Mutation interfaceMutator = new Mutation("interfaces", Mutator.DELETE, interfaceUuid);
1406             List<Mutation> mutations = new ArrayList<Mutation>();
1407             mutations.add(interfaceMutator);
1408
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);
1415
1416             TransactBuilder transaction = new TransactBuilder();
1417             transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delInterfaceRequest)));
1418
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());
1428                 }
1429             }
1430
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());
1436             }
1437             return status;
1438         } catch (Exception e) {
1439             e.printStackTrace();
1440         }
1441         return new Status(StatusCode.INTERNALERROR);
1442     }
1443
1444     private Status deleteOpen_vSwitchRow(Node node, String uuid) {
1445         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1446     }
1447
1448     private Status deleteControllerRow(Node node, String uuid) {
1449         try {
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);
1454             }
1455
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");
1460             }
1461
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());
1465
1466             // Initialise the actual request var
1467             Operation delControllerRequest = null;
1468
1469             // Check that the UUID exists
1470             if (bridgeTable == null || controllerTable == null || uuid == null || controllerTable.get(uuid) == null) {
1471                 return new Status(StatusCode.NOTFOUND, "");
1472             }
1473
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);
1479
1480             //Iterate over the list of bridgeUUIDs that contain the portUUID and add them to the mutator
1481             Status status = new Status(StatusCode.SUCCESS);
1482
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);
1487
1488             TransactBuilder transaction = new TransactBuilder();
1489             transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delControllerRequest)));
1490
1491             // This executes the transaction.
1492             ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
1493
1494             // Pull the responses
1495             List<OperationResult> tr = transResponse.get();
1496             List<Operation> requests = transaction.getRequests();
1497
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());
1503                 }
1504             }
1505
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());
1511             }
1512             return status;
1513         } catch (Exception e) {
1514             e.printStackTrace();
1515         }
1516         return new Status(StatusCode.INTERNALERROR);
1517
1518     }
1519
1520     private Status deleteSSLRow(Node node, String uuid) {
1521         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1522     }
1523
1524     private Status deleteSflowRow(Node node, String uuid) {
1525         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1526     }
1527
1528     private Status deleteQueueRow(Node node, String uuid) {
1529         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1530     }
1531
1532     private Status deleteQosRow(Node node, String uuid) {
1533         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1534     }
1535
1536     private Status deleteNetFlowRow(Node node, String uuid) {
1537         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1538     }
1539
1540     private Status deleteMirrorRow(Node node, String uuid) {
1541         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1542     }
1543
1544     private Status deleteManagerRow(Node node, String uuid) {
1545         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1546     }
1547
1548     private Status deleteCapabilityRow(Node node, String uuid) {
1549         return new Status(StatusCode.NOTIMPLEMENTED, "delete operation for this Table is not implemented yet.");
1550     }
1551
1552     public void _ovsconnect (CommandInterpreter ci) {
1553         String bridgeName = ci.nextArgument();
1554         if (bridgeName == null) {
1555             ci.println("Please enter Bridge Name");
1556             return;
1557         }
1558
1559         String ovsdbserver = ci.nextArgument();
1560         if (ovsdbserver == null) {
1561             ci.println("Please enter valid IP-Address");
1562             return;
1563         }
1564         try {
1565             InetAddress.getByName(ovsdbserver);
1566         }  catch (Exception e) {
1567             e.printStackTrace();
1568             ci.println("Please enter valid IP-Address");
1569             return;
1570         }
1571         String port = ci.nextArgument();
1572         if (port == null) {
1573             port = "6634";
1574         }
1575
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");
1583     }
1584
1585     public void _addBridge (CommandInterpreter ci) {
1586         String nodeName = ci.nextArgument();
1587         if (nodeName == null) {
1588             ci.println("Please enter Node Name");
1589             return;
1590         }
1591         String bridgeName = ci.nextArgument();
1592         if (bridgeName == null) {
1593             ci.println("Please enter Bridge Name");
1594             return;
1595         }
1596         Status status;
1597
1598         try {
1599             Node node = Node.fromString(nodeName);
1600             if (node == null) {
1601                 ci.println("Invalid Node");
1602                 return;
1603             }
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);
1610         }
1611     }
1612
1613     public void _getBridgeDomains (CommandInterpreter ci) {
1614         String nodeName = ci.nextArgument();
1615         if (nodeName == null) {
1616             ci.println("Please enter Node Name");
1617             return;
1618         }
1619         Status status;
1620
1621         List<String> brlist = new ArrayList<String>();
1622         try {
1623             Node node = Node.fromString(nodeName);
1624             brlist = this.getBridgeDomains(node);
1625             if (node == null) {
1626                 ci.println("Invalid Node");
1627                 return;
1628             }
1629             ci.println("Existing Bridges: "+brlist.toString());
1630         } catch (Throwable e) {
1631             e.printStackTrace();
1632             ci.println("Failed to list Bridges");
1633         }
1634     }
1635
1636     public void _deleteBridgeDomain (CommandInterpreter ci) {
1637         String nodeName = ci.nextArgument();
1638         if (nodeName == null) {
1639             ci.println("Please enter Node Name");
1640             return;
1641         }
1642         String bridgeName = ci.nextArgument();
1643         if (bridgeName == null) {
1644             ci.println("Please enter Bridge Name");
1645             return;
1646         }
1647         Status status;
1648         try {
1649             Node node = Node.fromString(nodeName);
1650             if (node == null) {
1651                 ci.println("Invalid Node");
1652                 return;
1653             }
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);
1659         }
1660     }
1661
1662     public void _addPort (CommandInterpreter ci) {
1663         String nodeName = ci.nextArgument();
1664         if (nodeName == null) {
1665             ci.println("Please enter Node Name");
1666             return;
1667         }
1668
1669         String bridgeName = ci.nextArgument();
1670         if (bridgeName == null) {
1671             ci.println("Please enter Bridge Name");
1672             return;
1673         }
1674
1675         String portName = ci.nextArgument();
1676         if (portName == null) {
1677             ci.println("Please enter Port Name");
1678             return;
1679         }
1680
1681         String type = ci.nextArgument();
1682
1683         Map<String, String> configs = new HashMap<String, String>();
1684         while(true) {
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);
1690         }
1691
1692         Map<ConfigConstants, Object> customConfigs = null;
1693         if (type != null) {
1694             customConfigs = new HashMap<ConfigConstants, Object>();
1695             customConfigs.put(ConfigConstants.TYPE, type);
1696         }
1697
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());
1702         }
1703         Status status;
1704         try {
1705             Node node = Node.fromString(nodeName);
1706             if (node == null) {
1707                 ci.println("Invalid Node");
1708                 return;
1709             }
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);
1716         }
1717     }
1718
1719     public void _deletePort (CommandInterpreter ci) {
1720         String nodeName = ci.nextArgument();
1721         if (nodeName == null) {
1722             ci.println("Please enter Node Name");
1723             return;
1724         }
1725
1726         String bridgeName = ci.nextArgument();
1727         if (bridgeName == null) {
1728             ci.println("Please enter Bridge Name");
1729             return;
1730         }
1731
1732         String portName = ci.nextArgument();
1733         if (portName == null) {
1734             ci.println("Please enter Port Name");
1735             return;
1736         }
1737
1738         Status status;
1739         try {
1740             Node node = Node.fromString(nodeName);
1741             if (node == null) {
1742                 ci.println("Invalid Node");
1743                 return;
1744             }
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);
1751         }
1752     }
1753
1754     public void _addPortVlan (CommandInterpreter ci) {
1755         String nodeName = ci.nextArgument();
1756         if (nodeName == null) {
1757             ci.println("Please enter Node Name");
1758             return;
1759         }
1760
1761         String bridgeName = ci.nextArgument();
1762         if (bridgeName == null) {
1763             ci.println("Please enter Bridge Name");
1764             return;
1765         }
1766
1767         String portName = ci.nextArgument();
1768         if (portName == null) {
1769             ci.println("Please enter Port Name");
1770             return;
1771         }
1772
1773         String vlan = ci.nextArgument();
1774         if (vlan == null) {
1775             ci.println("Please enter Valid Vlan");
1776             return;
1777         } else {
1778             try {
1779             Integer.parseInt(vlan);
1780             } catch (Exception e) {
1781                 ci.println("Please enter Valid Vlan");
1782                 return;
1783             }
1784         }
1785
1786         Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
1787         configs.put(ConfigConstants.TYPE, "VLAN");
1788         configs.put(ConfigConstants.VLAN, vlan);
1789
1790         Status status;
1791         try {
1792             Node node = Node.fromString(nodeName);
1793             if (node == null) {
1794                 ci.println("Invalid Node");
1795                 return;
1796             }
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);
1803         }
1804     }
1805
1806     public void _addTunnel (CommandInterpreter ci) {
1807         String nodeName = ci.nextArgument();
1808         if (nodeName == null) {
1809             ci.println("Please enter Node Name");
1810             return;
1811         }
1812
1813         String bridgeName = ci.nextArgument();
1814         if (bridgeName == null) {
1815             ci.println("Please enter Bridge Name");
1816             return;
1817         }
1818
1819         String portName = ci.nextArgument();
1820         if (portName == null) {
1821             ci.println("Please enter Port Name");
1822             return;
1823         }
1824
1825         String tunnelType = ci.nextArgument();
1826         if (tunnelType == null) {
1827             ci.println("Please enter Tunnel Type");
1828             return;
1829         }
1830
1831         String remoteIp = ci.nextArgument();
1832         if (remoteIp == null) {
1833             ci.println("Please enter valid Remote IP Address");
1834             return;
1835         }
1836
1837         try {
1838             InetAddress.getByName(remoteIp);
1839         }  catch (Exception e) {
1840             e.printStackTrace();
1841             ci.println("Please enter valid Remote IP Address");
1842             return;
1843         }
1844
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);
1849
1850         Status status;
1851         try {
1852             Node node = Node.fromString(nodeName);
1853             if (node == null) {
1854                 ci.println("Invalid Node");
1855                 return;
1856             }
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);
1863         }
1864     }
1865
1866     public void _printCache (CommandInterpreter ci) {
1867         String nodeName = ci.nextArgument();
1868         if (nodeName == null) {
1869             ci.println("Please enter Node Name");
1870             return;
1871         }
1872         Node node = Node.fromString(nodeName);
1873         if (node == null) {
1874             ci.println("Invalid Node");
1875             return;
1876         }
1877         inventoryServiceInternal.printCache(node);
1878     }
1879
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);
1886         return;
1887     }
1888
1889     @Override
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();
1903     }
1904 }
1905