Merge "Allow to change the controller ip and port for the integration test from the...
[netvirt.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.net.NetworkInterface;
6 import java.net.SocketException;
7 import java.util.*;
8
9 import org.eclipse.osgi.framework.console.CommandInterpreter;
10 import org.eclipse.osgi.framework.console.CommandProvider;
11 import org.opendaylight.ovsdb.lib.database.OVSInstance;
12 import org.opendaylight.ovsdb.lib.database.OvsdbType;
13 import org.opendaylight.ovsdb.lib.message.TransactBuilder;
14 import org.opendaylight.ovsdb.lib.message.operations.InsertOperation;
15 import org.opendaylight.ovsdb.lib.message.operations.MutateOperation;
16 import org.opendaylight.ovsdb.lib.message.operations.Operation;
17 import org.opendaylight.ovsdb.lib.message.operations.OperationResult;
18 import org.opendaylight.ovsdb.lib.notation.Condition;
19 import org.opendaylight.ovsdb.lib.notation.Function;
20 import org.opendaylight.ovsdb.lib.notation.Mutation;
21 import org.opendaylight.ovsdb.lib.notation.Mutator;
22 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
23 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
24 import org.opendaylight.ovsdb.lib.notation.UUID;
25 import org.opendaylight.ovsdb.lib.table.Bridge;
26 import org.opendaylight.ovsdb.lib.table.Controller;
27 import org.opendaylight.ovsdb.lib.table.Interface;
28 import org.opendaylight.ovsdb.lib.table.Open_vSwitch;
29 import org.opendaylight.ovsdb.lib.table.Port;
30 import org.opendaylight.ovsdb.lib.table.internal.Table;
31 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
32 import org.opendaylight.controller.sal.connection.ConnectionConstants;
33 import org.opendaylight.controller.sal.core.Node;
34 import org.opendaylight.controller.sal.core.NodeConnector;
35 import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants;
36 import org.opendaylight.controller.sal.networkconfig.bridgedomain.IPluginInBridgeDomainConfigService;
37 import org.opendaylight.controller.sal.utils.NetUtils;
38 import org.opendaylight.controller.sal.utils.Status;
39 import org.opendaylight.controller.sal.utils.StatusCode;
40 import org.osgi.framework.BundleContext;
41 import org.osgi.framework.FrameworkUtil;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import com.google.common.util.concurrent.ListenableFuture;
46
47 public class ConfigurationService implements IPluginInBridgeDomainConfigService, CommandProvider
48 {
49     private static final Logger logger = LoggerFactory
50             .getLogger(ConfigurationService.class);
51
52     IConnectionServiceInternal connectionService;
53     InventoryServiceInternal inventoryServiceInternal;
54     private IClusterGlobalServices clusterServices;
55     boolean forceConnect = false;
56
57     void init() {
58     }
59
60     /**
61      * Function called by the dependency manager when at least one dependency
62      * become unsatisfied or when the component is shutting down because for
63      * example bundle is being stopped.
64      *
65      */
66     void destroy() {
67     }
68
69     /**
70      * Function called by dependency manager after "init ()" is called and after
71      * the services provided by the class are registered in the service registry
72      *
73      */
74     void start() {
75         registerWithOSGIConsole();
76     }
77
78     private void registerWithOSGIConsole() {
79         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
80                 .getBundleContext();
81         bundleContext.registerService(CommandProvider.class.getName(), this,
82                 null);
83     }
84
85     /**
86      * Function called by the dependency manager before the services exported by
87      * the component are unregistered, this will be followed by a "destroy ()"
88      * calls
89      *
90      */
91     void stop() {
92     }
93
94     public void setConnectionServiceInternal(IConnectionServiceInternal connectionService) {
95         this.connectionService = connectionService;
96     }
97
98     public void unsetConnectionServiceInternal(IConnectionServiceInternal connectionService) {
99         if (this.connectionService == connectionService) {
100             this.connectionService = null;
101         }
102     }
103
104     public void setInventoryServiceInternal(InventoryServiceInternal inventoryServiceInternal) {
105         this.inventoryServiceInternal = inventoryServiceInternal;
106     }
107
108     public void unsetInventoryServiceInternal(InventoryServiceInternal inventoryServiceInternal) {
109         if (this.inventoryServiceInternal == inventoryServiceInternal) {
110             this.inventoryServiceInternal = null;
111         }
112     }
113
114     public void setClusterServices(IClusterGlobalServices i) {
115         this.clusterServices = i;
116     }
117
118     public void unsetClusterServices(IClusterGlobalServices i) {
119         if (this.clusterServices == i) {
120             this.clusterServices = null;
121         }
122     }
123
124     private Connection getConnection (Node node) {
125         Connection connection = connectionService.getConnection(node);
126         if (connection == null || !connection.getChannel().isActive()) {
127             return null;
128         }
129
130         return connection;
131     }
132
133     /**
134      * Add a new bridge
135      * @param node Node serving this configuration service
136      * @param bridgeConnectorIdentifier String representation of a Bridge Connector
137      * @return Bridge Connector configurations
138      */
139     @Override
140     public Status createBridgeDomain(Node node, String bridgeIdentifier,
141             Map<ConfigConstants, Object> configs) throws Throwable {
142         try{
143             if (connectionService == null) {
144                 logger.error("Couldn't refer to the ConnectionService");
145                 return new Status(StatusCode.NOSERVICE);
146             }
147
148             Connection connection = this.getConnection(node);
149             if (connection == null) {
150                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
151             }
152
153             Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
154             String newBridge = "new_bridge";
155             String newInterface = "new_interface";
156             String newPort = "new_port";
157             String newSwitch = "new_switch";
158
159             Operation addSwitchRequest = null;
160
161             if(ovsTable != null){
162                 String ovsTableUUID = (String) ovsTable.keySet().toArray()[0];
163                 UUID bridgeUuidPair = new UUID(newBridge);
164                 Mutation bm = new Mutation("bridges", Mutator.INSERT, bridgeUuidPair);
165                 List<Mutation> mutations = new ArrayList<Mutation>();
166                 mutations.add(bm);
167
168                 UUID uuid = new UUID(ovsTableUUID);
169                 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
170                 List<Condition> where = new ArrayList<Condition>();
171                 where.add(condition);
172                 addSwitchRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations);
173             }
174             else{
175                 Open_vSwitch ovsTableRow = new Open_vSwitch();
176                 OvsDBSet<UUID> bridges = new OvsDBSet<UUID>();
177                 UUID bridgeUuidPair = new UUID(newBridge);
178                 bridges.add(bridgeUuidPair);
179                 ovsTableRow.setBridges(bridges);
180                 addSwitchRequest = new InsertOperation(Open_vSwitch.NAME.getName(), newSwitch, ovsTableRow);
181             }
182
183             Bridge bridgeRow = new Bridge();
184             bridgeRow.setName(bridgeIdentifier);
185             OvsDBSet<UUID> ports = new OvsDBSet<UUID>();
186             UUID port = new UUID(newPort);
187             ports.add(port);
188             bridgeRow.setPorts(ports);
189             InsertOperation addBridgeRequest = new InsertOperation(Bridge.NAME.getName(), newBridge, bridgeRow);
190
191             Port portRow = new Port();
192             portRow.setName(bridgeIdentifier);
193             OvsDBSet<UUID> interfaces = new OvsDBSet<UUID>();
194             UUID interfaceid = new UUID(newInterface);
195             interfaces.add(interfaceid);
196             portRow.setInterfaces(interfaces);
197             InsertOperation addPortRequest = new InsertOperation(Port.NAME.getName(), newPort, portRow);
198
199             Interface interfaceRow = new Interface();
200             interfaceRow.setName(bridgeIdentifier);
201             interfaceRow.setType("internal");
202             InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(), newInterface, interfaceRow);
203
204             /* Update config version */
205             String ovsTableUUID = (String) ovsTable.keySet().toArray()[0];
206             Mutation bm = new Mutation("next_cfg", Mutator.SUM, 1);
207             List<Mutation> mutations = new ArrayList<Mutation>();
208             mutations.add(bm);
209
210             UUID uuid = new UUID(ovsTableUUID);
211             Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
212             List<Condition> where = new ArrayList<Condition>();
213             where.add(condition);
214             MutateOperation updateCfgVerRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations);
215
216             TransactBuilder transaction = new TransactBuilder();
217             transaction.addOperations(new ArrayList<Operation>(
218                                       Arrays.asList(addSwitchRequest, addIntfRequest, addPortRequest, addBridgeRequest, updateCfgVerRequest)));
219
220             ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
221             List<OperationResult> tr = transResponse.get();
222             List<Operation> requests = transaction.getRequests();
223             Status status = new Status(StatusCode.SUCCESS);
224             for (int i = 0; i < tr.size() ; i++) {
225                 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
226                 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
227                     OperationResult result = tr.get(i);
228                     status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
229                 }
230             }
231
232             if (tr.size() > requests.size()) {
233                 OperationResult result = tr.get(tr.size()-1);
234                 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier,
235                                                                                        result.getError(),
236                                                                                        result.getDetails());
237                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
238             }
239             if (status.isSuccess()) {
240                 setBridgeOFController(node, bridgeIdentifier);
241             }
242             return status;
243         } catch(Exception e){
244             e.printStackTrace();
245         }
246         return new Status(StatusCode.INTERNALERROR);
247     }
248
249     /**
250      * Create a Port Attached to a Bridge
251      * Ex. ovs-vsctl add-port br0 vif0
252      * @param node Node serving this configuration service
253      * @param bridgeDomainIdentifier String representation of a Bridge Domain
254      * @param portIdentifier String representation of a user defined Port Name
255      */
256     @Override
257     public Status addPort(Node node, String bridgeIdentifier, String portIdentifier,
258                           Map<ConfigConstants, Object> configs) {
259         try{
260             if (connectionService == null) {
261                 logger.error("Couldn't refer to the ConnectionService");
262                 return new Status(StatusCode.NOSERVICE);
263             }
264             Connection connection = this.getConnection(node);
265             if (connection == null) {
266                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
267             }
268             if (connection != null) {
269                 Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
270                 String newBridge = "new_bridge";
271                 String newInterface = "new_interface";
272                 String newPort = "new_port";
273
274                 if(brTable != null){
275                     Operation addBrMutRequest = null;
276                     String brUuid = null;
277                     for (String uuid : brTable.keySet()) {
278                         Bridge bridge = (Bridge) brTable.get(uuid);
279                         if (bridge.getName().contains(bridgeIdentifier)) {
280                             brUuid = uuid;
281                         }
282                     }
283
284                     UUID brUuidPair = new UUID(newPort);
285                     Mutation bm = new Mutation("ports", Mutator.INSERT, brUuidPair);
286                     List<Mutation> mutations = new ArrayList<Mutation>();
287                     mutations.add(bm);
288
289                     UUID uuid = new UUID(brUuid);
290                     Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
291                     List<Condition> where = new ArrayList<Condition>();
292                     where.add(condition);
293                     addBrMutRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
294
295                     OvsDBMap<String, String> options = null;
296                     String type = null;
297                     OvsDBSet<BigInteger> tags = null;
298                     if (configs != null) {
299                         type = (String) configs.get(ConfigConstants.TYPE);
300                         Map<String, String> customConfigs = (Map<String, String>) configs.get(ConfigConstants.CUSTOM);
301                         if (customConfigs != null) {
302                             options = new OvsDBMap<String, String>();
303                             for (String customConfig : customConfigs.keySet()) {
304                                 options.put(customConfig, customConfigs.get(customConfig));
305                             }
306                         }
307                     }
308
309                     Interface interfaceRow = new Interface();
310                     interfaceRow.setName(portIdentifier);
311
312                     if (type != null) {
313                         if (type.equalsIgnoreCase(OvsdbType.PortType.TUNNEL.name())) {
314                             interfaceRow.setType((String)configs.get(ConfigConstants.TUNNEL_TYPE));
315                             if (options == null) options = new OvsDBMap<String, String>();
316                             options.put("remote_ip", (String)configs.get(ConfigConstants.DEST_IP));
317                         } else if (type.equalsIgnoreCase(OvsdbType.PortType.VLAN.name())) {
318                             tags = new OvsDBSet<BigInteger>();
319                             tags.add(BigInteger.valueOf(Integer.parseInt((String)configs.get(ConfigConstants.VLAN))));
320                         } else if (type.equalsIgnoreCase(OvsdbType.PortType.PATCH.name())) {
321                             interfaceRow.setType(type.toLowerCase());
322                         }
323                     }
324                     if (options != null) {
325                         interfaceRow.setOptions(options);
326                     }
327
328                     InsertOperation addIntfRequest = new InsertOperation(Interface.NAME.getName(),
329                             newInterface, interfaceRow);
330
331                     Port portRow = new Port();
332                     portRow.setName(portIdentifier);
333                     if (tags != null) portRow.setTag(tags);
334                     OvsDBSet<UUID> interfaces = new OvsDBSet<UUID>();
335                     UUID interfaceid = new UUID(newInterface);
336                     interfaces.add(interfaceid);
337                     portRow.setInterfaces(interfaces);
338                     InsertOperation addPortRequest = new InsertOperation(Port.NAME.getName(), newPort, portRow);
339
340                     TransactBuilder transaction = new TransactBuilder();
341                     transaction.addOperations(new ArrayList<Operation>
342                             (Arrays.asList(addBrMutRequest, addPortRequest, addIntfRequest)));
343
344                     ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
345                     List<OperationResult> tr = transResponse.get();
346                     List<Operation> requests = transaction.getRequests();
347                     Status status = new Status(StatusCode.SUCCESS);
348                     for (int i = 0; i < tr.size() ; i++) {
349                         if (i < requests.size()) requests.get(i).setResult(tr.get(i));
350                         if (tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
351                             OperationResult result = tr.get(i);
352                             status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
353                         }
354                     }
355
356                     if (tr.size() > requests.size()) {
357                         OperationResult result = tr.get(tr.size()-1);
358                         logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier,
359                                 result.getError(),
360                                 result.getDetails());
361                         status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
362                     }
363                     return status;
364                 }
365                 return new Status(StatusCode.INTERNALERROR);
366             }
367         } catch(Exception e){
368             e.printStackTrace();
369         }
370         return new Status(StatusCode.INTERNALERROR);
371     }
372
373     /**
374      * Implements the OVS Connection for Managers
375      *
376      * @param node Node serving this configuration service
377      * @param String with IP and connection types
378      */
379     @SuppressWarnings("unchecked")
380     public boolean setManager(Node node, String managerip) throws Throwable{
381         try{
382             if (connectionService == null) {
383                 logger.error("Couldn't refer to the ConnectionService");
384                 return false;
385             }
386             Connection connection = this.getConnection(node);
387             if (connection == null) {
388                 return false;
389             }
390
391             if (connection != null) {
392                 String newmanager = "new_manager";
393
394                 OVSInstance instance = OVSInstance.monitorOVS(connection);
395
396                 Map ovsoutter = new LinkedHashMap();
397                 Map ovsinner = new LinkedHashMap();
398                 ArrayList ovsalist1 = new ArrayList();
399                 ArrayList ovsalist2 = new ArrayList();
400                 ArrayList ovsalist3 = new ArrayList();
401                 ArrayList ovsalist4 = new ArrayList();
402
403                 //OVS Table Update
404                 ovsoutter.put("where", ovsalist1);
405                 ovsalist1.add(ovsalist2);
406                 ovsalist2.add("_uuid");
407                 ovsalist2.add("==");
408                 ovsalist2.add(ovsalist3);
409                 ovsalist3.add("uuid");
410                 ovsalist3.add(instance.getUuid());
411                 ovsoutter.put("op", "update");
412                 ovsoutter.put("table", "Open_vSwitch");
413                 ovsoutter.put("row", ovsinner);
414                 ovsinner.put("manager_options", ovsalist4);
415                 ovsalist4.add("named-uuid");
416                 ovsalist4.add(newmanager);
417
418                 Map mgroutside = new LinkedHashMap();
419                 Map mgrinside = new LinkedHashMap();
420
421                 //Manager Table Insert
422                 mgroutside.put("uuid-name", newmanager);
423                 mgroutside.put("op", "insert");
424                 mgroutside.put("table","Manager");
425                 mgroutside.put("row", mgrinside);
426                 mgrinside.put("target", managerip);
427
428                 Object[] params = {"Open_vSwitch", ovsoutter, mgroutside};
429                 OvsdbMessage msg = new OvsdbMessage("transact", params);
430
431                 //connection.sendMessage(msg);
432
433             }
434         }catch(Exception e){
435             e.printStackTrace();
436         }
437         return true;
438     }
439
440     @Override
441     public Status addBridgeDomainConfig(Node node, String bridgeIdentfier,
442             Map<ConfigConstants, Object> configs) {
443         String mgmt = (String)configs.get(ConfigConstants.MGMT);
444         if (mgmt != null) {
445             try {
446                 if (setManager(node, mgmt)) return new Status(StatusCode.SUCCESS);
447             } catch (Throwable e) {
448                 // TODO Auto-generated catch block
449                 e.printStackTrace();
450                 return new Status(StatusCode.INTERNALERROR);
451             }
452         }
453         return new Status(StatusCode.BADREQUEST);
454     }
455
456     @Override
457     public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier,
458             Map<ConfigConstants, Object> configs) {
459         // TODO Auto-generated method stub
460         return null;
461     }
462
463     @Override
464     public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier) {
465
466             try{
467                 if (connectionService == null) {
468                     logger.error("Couldn't refer to the ConnectionService");
469                     return new Status(StatusCode.NOSERVICE);
470                 }
471
472                 Connection connection = this.getConnection(node);
473                 if (connection == null) {
474                     return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
475                 }
476
477                 Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
478                 Map<String, Table<?>> portTable = inventoryServiceInternal.getTableCache(node, Port.NAME.getName());
479                 Operation delPortRequest = null;
480                 String brUuid = null;
481                 String portUuid = null;
482                 if(brTable != null){
483                     for (String uuid : brTable.keySet()) {
484                         Bridge bridge = (Bridge) brTable.get(uuid);
485                         if (bridge.getName().contains(bridgeIdentifier)) {
486                             brUuid = uuid;
487                         }
488                     }
489                 }
490             if(portTable != null){
491                 for (String uuid : portTable.keySet()) {
492                     Port port = (Port) portTable.get(uuid);
493                     if (port.getName().contains(portIdentifier)) {
494                         portUuid = uuid;
495                     }
496                 }
497             }
498
499             UUID portUuidPair = new UUID(portUuid);
500             Mutation bm = new Mutation("ports", Mutator.DELETE, portUuidPair);
501             List<Mutation> mutations = new ArrayList<Mutation>();
502             mutations.add(bm);
503
504             UUID uuid = new UUID(brUuid);
505             Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
506             List<Condition> where = new ArrayList<Condition>();
507             where.add(condition);
508             delPortRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
509
510             TransactBuilder transaction = new TransactBuilder();
511             transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delPortRequest)));
512
513             ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
514             List<OperationResult> tr = transResponse.get();
515             List<Operation> requests = transaction.getRequests();
516             Status status = new Status(StatusCode.SUCCESS);
517             for (int i = 0; i < tr.size() ; i++) {
518                 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
519                 if (tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
520                     OperationResult result = tr.get(i);
521                     status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
522                 }
523             }
524
525             if (tr.size() > requests.size()) {
526                 OperationResult result = tr.get(tr.size()-1);
527                 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier,
528                         result.getError(),
529                         result.getDetails());
530                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
531             }
532             return status;
533         } catch(Exception e){
534             e.printStackTrace();
535         }
536         return new Status(StatusCode.INTERNALERROR);
537     }
538
539     @Override
540     public Node getBridgeDomainNode(Node node, String bridgeIdentifier) {
541         // TODO Auto-generated method stub
542         return null;
543     }
544
545     @Override
546     public Map<ConfigConstants, Object> getPortConfigs(Node node, String bridgeIdentifier,
547             String portIdentifier) {
548         // TODO Auto-generated method stub
549         return null;
550     }
551
552     @Override
553     public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier,
554             Map<ConfigConstants, Object> configs) {
555         // TODO Auto-generated method stub
556         return null;
557     }
558
559     @Override
560     public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier,
561             Map<ConfigConstants, Object> configs) {
562         // TODO Auto-generated method stub
563         return null;
564     }
565
566     @Override
567     public Status deleteBridgeDomain(Node node, String bridgeIdentifier) {
568
569         try {
570             if (connectionService == null) {
571                 logger.error("Couldn't refer to the ConnectionService");
572                 return new Status(StatusCode.NOSERVICE);
573             }
574             Connection connection = this.getConnection(node);
575             if (connection == null) {
576                 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
577             }
578             Map<String, Table<?>> ovsTable = inventoryServiceInternal.getTableCache(node, Open_vSwitch.NAME.getName());
579             Map<String, Table<?>> brTable = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
580             Operation delBrRequest = null;
581             String ovsUuid = null;
582             String brUuid = null;
583
584             if (brTable != null) {
585                 for (String uuid : brTable.keySet()) {
586                     Bridge bridge = (Bridge) brTable.get(uuid);
587                     if (bridge.getName().contains(bridgeIdentifier)) {
588                         brUuid = uuid;
589                     }
590                 }
591             }
592             if (ovsTable != null) {
593                 ovsUuid = (String) ovsTable.keySet().toArray()[0];
594             }
595             UUID bridgeUuidPair = new UUID(brUuid);
596             Mutation bm = new Mutation("bridges", Mutator.DELETE, bridgeUuidPair);
597             List<Mutation> mutations = new ArrayList<Mutation>();
598             mutations.add(bm);
599
600             UUID uuid = new UUID(ovsUuid);
601             Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
602             List<Condition> where = new ArrayList<Condition>();
603             where.add(condition);
604             delBrRequest = new MutateOperation(Open_vSwitch.NAME.getName(), where, mutations);
605
606             TransactBuilder transaction = new TransactBuilder();
607             transaction.addOperations(new ArrayList<Operation>(Arrays.asList(delBrRequest)));
608
609             ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
610             List<OperationResult> tr = transResponse.get();
611             List<Operation> requests = transaction.getRequests();
612             Status status = new Status(StatusCode.SUCCESS);
613             for (int i = 0; i < tr.size(); i++) {
614                 if (i < requests.size()) requests.get(i).setResult(tr.get(i));
615                 if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
616                     OperationResult result = tr.get(i);
617                     status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
618                 }
619             }
620
621             if (tr.size() > requests.size()) {
622                 OperationResult result = tr.get(tr.size() - 1);
623                 logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}",
624                         bridgeIdentifier, result.getError(), result.getDetails());
625                 status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
626             }
627             return status;
628         } catch (Exception e) {
629             e.printStackTrace();
630         }
631         return new Status(StatusCode.INTERNALERROR);
632     }
633
634     @Override
635     public Map<ConfigConstants, Object> getBridgeDomainConfigs(Node node, String bridgeIdentifier) {
636         // TODO Auto-generated method stub
637         return null;
638     }
639
640     @Override
641     public List<String> getBridgeDomains(Node node) {
642         List<String> brlist = new ArrayList<String>();
643         Map<String, Table<?>> brTableCache = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
644         if(brTableCache != null){
645             for (String uuid : brTableCache.keySet()) {
646                 Bridge bridge = (Bridge) brTableCache.get(uuid);
647                 brlist.add(bridge.getName());
648             }
649         }
650         return brlist;
651     }
652
653     @Override
654     public NodeConnector getNodeConnector(Node arg0, String arg1, String arg2) {
655         return null;
656     }
657
658     private short getControllerOFPort() {
659         Short defaultOpenFlowPort = 6633;
660         Short openFlowPort = defaultOpenFlowPort;
661         String portString = System.getProperty("of.listenPort");
662         if (portString != null) {
663             try {
664                 openFlowPort = Short.decode(portString).shortValue();
665             } catch (NumberFormatException e) {
666                 logger.warn("Invalid port:{}, use default({})", portString,
667                         openFlowPort);
668             }
669         }
670         return openFlowPort;
671     }
672
673     private List<InetAddress> getControllerIPAddresses() {
674         List<InetAddress> controllers = null;
675         if (clusterServices != null) {
676             controllers = clusterServices.getClusteredControllers();
677             if (controllers != null && controllers.size() > 0) {
678                 if (controllers.size() == 1) {
679                     InetAddress controller = controllers.get(0);
680                     if (!controller.equals(InetAddress.getLoopbackAddress())) {
681                         return controllers;
682                     }
683                 } else {
684                     return controllers;
685                 }
686             }
687         }
688
689         controllers = new ArrayList<InetAddress>();
690         InetAddress controllerIP;
691         Enumeration<NetworkInterface> nets;
692         try {
693             nets = NetworkInterface.getNetworkInterfaces();
694             for (NetworkInterface netint : Collections.list(nets)) {
695                 Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
696                 for (InetAddress inetAddress : Collections.list(inetAddresses)) {
697                     if (!inetAddress.isLoopbackAddress() &&
698                             NetUtils.isIPv4AddressValid(inetAddress.getHostAddress())) {
699                         controllers.add(inetAddress);
700                     }
701                 }
702             }
703         } catch (SocketException e) {
704             controllers.add(InetAddress.getLoopbackAddress());
705         }
706         return controllers;
707     }
708
709     public Boolean setBridgeOFController(Node node, String bridgeIdentifier) {
710         try{
711             if (connectionService == null) {
712                 logger.error("Couldn't refer to the ConnectionService");
713                 return false;
714             }
715             Connection connection = this.getConnection(node);
716             if (connection == null) {
717                 return false;
718             }
719
720             if (connection != null) {
721                 List<InetAddress> ofControllerAddrs = getControllerIPAddresses();
722                 short ofControllerPort = getControllerOFPort();
723                 OvsDBSet<UUID> controllerUUIDs = new OvsDBSet<UUID>();
724                 List<Operation> controllerInsertOperations = new ArrayList<Operation>();
725                 Map<String, Table<?>> controllerCache = inventoryServiceInternal.getTableCache(node, Controller.NAME.getName());
726
727                 int count = 0;
728                 for (InetAddress ofControllerAddress : ofControllerAddrs) {
729                     String cntrlUuid = null;
730                     String newController = "tcp:"+ofControllerAddress.getHostAddress()+":"+ofControllerPort;
731                     if (controllerCache != null) {
732                         for (String uuid : controllerCache.keySet()) {
733                             Controller controller = (Controller)controllerCache.get(uuid);
734                             if (controller.getTarget().equals(newController)) {
735                                 cntrlUuid = uuid;
736                                 controllerUUIDs.add(new UUID(uuid));
737                                 break;
738                             }
739                         }
740                     }
741                     if (cntrlUuid == null) {
742                         count++;
743                         String uuid_name = "new_controller_"+count;
744                         controllerUUIDs.add(new UUID(uuid_name));
745                         Controller controllerRow = new Controller();
746                         controllerRow.setTarget(newController);
747                         InsertOperation addCtlRequest = new InsertOperation(Controller.NAME.getName(), uuid_name, controllerRow);
748                         controllerInsertOperations.add(addCtlRequest);
749                     }
750                 }
751                 String brCntrlUuid = null;
752                 Map<String, Table<?>> brTableCache = inventoryServiceInternal.getTableCache(node, Bridge.NAME.getName());
753                 for (String uuid : brTableCache.keySet()) {
754                     Bridge bridge = (Bridge)brTableCache.get(uuid);
755                     if (bridge.getName().contains(bridgeIdentifier)) {
756                         brCntrlUuid = uuid;
757                     }
758                 }
759                 Operation addControlRequest = null;
760                 Mutation bm = new Mutation("controller", Mutator.INSERT, controllerUUIDs);
761                 List<Mutation> mutations = new ArrayList<Mutation>();
762                 mutations.add(bm);
763
764                 UUID uuid = new UUID(brCntrlUuid);
765                 Condition condition = new Condition("_uuid", Function.EQUALS, uuid);
766                 List<Condition> where = new ArrayList<Condition>();
767                 where.add(condition);
768                 addControlRequest = new MutateOperation(Bridge.NAME.getName(), where, mutations);
769
770                 TransactBuilder transaction = new TransactBuilder();
771                 transaction.addOperations(controllerInsertOperations);
772                 transaction.addOperation(addControlRequest);
773
774                 ListenableFuture<List<OperationResult>> transResponse = connection.getRpc().transact(transaction);
775                 List<OperationResult> tr = transResponse.get();
776                 List<Operation> requests = transaction.getRequests();
777                 Status status = new Status(StatusCode.SUCCESS);
778                 for (int i = 0; i < tr.size() ; i++) {
779                     if (i < requests.size()) requests.get(i).setResult(tr.get(i));
780                     if (tr.get(i) != null && tr.get(i).getError() != null && tr.get(i).getError().trim().length() > 0) {
781                         OperationResult result = tr.get(i);
782                         status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
783                     }
784                 }
785
786                 if (tr.size() > requests.size()) {
787                     OperationResult result = tr.get(tr.size()-1);
788                     logger.error("Error creating Bridge : {}\n Error : {}\n Details : {}", bridgeIdentifier,
789                             result.getError(),
790                             result.getDetails());
791                     status = new Status(StatusCode.BADREQUEST, result.getError() + " : " + result.getDetails());
792
793                 }
794             }
795         }catch(Exception e){
796             e.printStackTrace();
797         }
798         return true;
799     }
800
801     public void _ovsconnect (CommandInterpreter ci) {
802         String bridgeName = ci.nextArgument();
803         if (bridgeName == null) {
804             ci.println("Please enter Bridge Name");
805             return;
806         }
807
808         String ovsdbserver = ci.nextArgument();
809         if (ovsdbserver == null) {
810             ci.println("Please enter valid IP-Address");
811             return;
812         }
813         try {
814             InetAddress.getByName(ovsdbserver);
815         }  catch (Exception e) {
816             e.printStackTrace();
817             ci.println("Please enter valid IP-Address");
818             return;
819         }
820         String port = ci.nextArgument();
821         if (port == null) {
822             port = "6634";
823         }
824
825         ci.println("connecting to ovsdb server : "+ovsdbserver+":"+port+" ... ");
826         Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
827         params.put(ConnectionConstants.ADDRESS, ovsdbserver);
828         params.put(ConnectionConstants.PORT, port);
829         Node node = connectionService.connect(bridgeName, params);
830         if (node != null) ci.println("Node Name: "+node.toString());
831         else ci.println("Could not connect to Node");
832     }
833
834     public void _addBridge (CommandInterpreter ci) {
835         String nodeName = ci.nextArgument();
836         if (nodeName == null) {
837             ci.println("Please enter Node Name");
838             return;
839         }
840         String bridgeName = ci.nextArgument();
841         if (bridgeName == null) {
842             ci.println("Please enter Bridge Name");
843             return;
844         }
845         Status status;
846
847         try {
848             Node node = Node.fromString(nodeName);
849             if (node == null) {
850                 ci.println("Invalid Node");
851                 return;
852             }
853             status = this.createBridgeDomain(node, bridgeName, null);
854             ci.println("Bridge creation status : "+status.toString());
855         } catch (Throwable e) {
856             // TODO Auto-generated catch block
857             e.printStackTrace();
858             ci.println("Failed to create Bridge "+bridgeName);
859         }
860     }
861
862     public void _getBridgeDomains (CommandInterpreter ci) {
863         String nodeName = ci.nextArgument();
864         if (nodeName == null) {
865             ci.println("Please enter Node Name");
866             return;
867         }
868         Status status;
869
870         List<String> brlist = new ArrayList<String>();
871         try {
872             Node node = Node.fromString(nodeName);
873             brlist = this.getBridgeDomains(node);
874             if (node == null) {
875                 ci.println("Invalid Node");
876                 return;
877             }
878             ci.println("Existing Bridges: "+brlist.toString());
879         } catch (Throwable e) {
880             e.printStackTrace();
881             ci.println("Failed to list Bridges");
882         }
883     }
884
885     public void _deleteBridgeDomain (CommandInterpreter ci) {
886         String nodeName = ci.nextArgument();
887         if (nodeName == null) {
888             ci.println("Please enter Node Name");
889             return;
890         }
891         String bridgeName = ci.nextArgument();
892         if (bridgeName == null) {
893             ci.println("Please enter Bridge Name");
894             return;
895         }
896         Status status;
897         try {
898             Node node = Node.fromString(nodeName);
899             if (node == null) {
900                 ci.println("Invalid Node");
901                 return;
902             }
903             status = this.deleteBridgeDomain(node, bridgeName);
904             ci.println("Bridge deletion status : "+status.toString());
905         } catch (Throwable e) {
906             e.printStackTrace();
907             ci.println("Failed to delete Bridge "+bridgeName);
908         }
909     }
910
911     public void _addPort (CommandInterpreter ci) {
912         String nodeName = ci.nextArgument();
913         if (nodeName == null) {
914             ci.println("Please enter Node Name");
915             return;
916         }
917
918         String bridgeName = ci.nextArgument();
919         if (bridgeName == null) {
920             ci.println("Please enter Bridge Name");
921             return;
922         }
923
924         String portName = ci.nextArgument();
925         if (portName == null) {
926             ci.println("Please enter Port Name");
927             return;
928         }
929
930         String type = ci.nextArgument();
931
932         Map<String, String> configs = new HashMap<String, String>();
933         while(true) {
934             String configKey = ci.nextArgument();
935             if (configKey == null) break;
936             String configValue = ci.nextArgument();
937             if (configValue == null) break;
938             configs.put(configKey, configValue);
939         }
940
941         Map<ConfigConstants, Object> customConfigs = null;
942         if (type != null) {
943             customConfigs = new HashMap<ConfigConstants, Object>();
944             customConfigs.put(ConfigConstants.TYPE, type);
945         }
946
947         if (configs.size() > 0) {
948             if (customConfigs == null) customConfigs = new HashMap<ConfigConstants, Object>();
949             customConfigs.put(ConfigConstants.CUSTOM, configs);
950             ci.println(customConfigs.toString());
951         }
952         Status status;
953         try {
954             Node node = Node.fromString(nodeName);
955             if (node == null) {
956                 ci.println("Invalid Node");
957                 return;
958             }
959             status = this.addPort(node, bridgeName, portName, customConfigs);
960             ci.println("Port creation status : "+status.toString());
961         } catch (Throwable e) {
962             // TODO Auto-generated catch block
963             e.printStackTrace();
964             ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
965         }
966     }
967
968     public void _deletePort (CommandInterpreter ci) {
969         String nodeName = ci.nextArgument();
970         if (nodeName == null) {
971             ci.println("Please enter Node Name");
972             return;
973         }
974
975         String bridgeName = ci.nextArgument();
976         if (bridgeName == null) {
977             ci.println("Please enter Bridge Name");
978             return;
979         }
980
981         String portName = ci.nextArgument();
982         if (portName == null) {
983             ci.println("Please enter Port Name");
984             return;
985         }
986
987         Status status;
988         try {
989             Node node = Node.fromString(nodeName);
990             if (node == null) {
991                 ci.println("Invalid Node");
992                 return;
993             }
994             status = this.deletePort(node, bridgeName, portName);
995             ci.println("Port deletion status : "+status.toString());
996         } catch (Throwable e) {
997             // TODO Auto-generated catch block
998             e.printStackTrace();
999             ci.println("Failed to delete Port "+portName+" in Bridge "+bridgeName);
1000         }
1001     }
1002
1003     public void _addPortVlan (CommandInterpreter ci) {
1004         String nodeName = ci.nextArgument();
1005         if (nodeName == null) {
1006             ci.println("Please enter Node Name");
1007             return;
1008         }
1009
1010         String bridgeName = ci.nextArgument();
1011         if (bridgeName == null) {
1012             ci.println("Please enter Bridge Name");
1013             return;
1014         }
1015
1016         String portName = ci.nextArgument();
1017         if (portName == null) {
1018             ci.println("Please enter Port Name");
1019             return;
1020         }
1021
1022         String vlan = ci.nextArgument();
1023         if (vlan == null) {
1024             ci.println("Please enter Valid Vlan");
1025             return;
1026         } else {
1027             try {
1028             Integer.parseInt(vlan);
1029             } catch (Exception e) {
1030                 ci.println("Please enter Valid Vlan");
1031                 return;
1032             }
1033         }
1034
1035         Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
1036         configs.put(ConfigConstants.TYPE, "VLAN");
1037         configs.put(ConfigConstants.VLAN, vlan);
1038
1039         Status status;
1040         try {
1041             Node node = Node.fromString(nodeName);
1042             if (node == null) {
1043                 ci.println("Invalid Node");
1044                 return;
1045             }
1046             status = this.addPort(node, bridgeName, portName, configs);
1047             ci.println("Port creation status : "+status.toString());
1048         } catch (Throwable e) {
1049             // TODO Auto-generated catch block
1050             e.printStackTrace();
1051             ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
1052         }
1053     }
1054
1055     public void _addTunnel (CommandInterpreter ci) {
1056         String nodeName = ci.nextArgument();
1057         if (nodeName == null) {
1058             ci.println("Please enter Node Name");
1059             return;
1060         }
1061
1062         String bridgeName = ci.nextArgument();
1063         if (bridgeName == null) {
1064             ci.println("Please enter Bridge Name");
1065             return;
1066         }
1067
1068         String portName = ci.nextArgument();
1069         if (portName == null) {
1070             ci.println("Please enter Port Name");
1071             return;
1072         }
1073
1074         String tunnelType = ci.nextArgument();
1075         if (tunnelType == null) {
1076             ci.println("Please enter Tunnel Type");
1077             return;
1078         }
1079
1080         String remoteIp = ci.nextArgument();
1081         if (remoteIp == null) {
1082             ci.println("Please enter valid Remote IP Address");
1083             return;
1084         }
1085
1086         try {
1087             InetAddress.getByName(remoteIp);
1088         }  catch (Exception e) {
1089             e.printStackTrace();
1090             ci.println("Please enter valid Remote IP Address");
1091             return;
1092         }
1093
1094         Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
1095         configs.put(ConfigConstants.TYPE, "TUNNEL");
1096         configs.put(ConfigConstants.TUNNEL_TYPE, tunnelType);
1097         configs.put(ConfigConstants.DEST_IP, remoteIp);
1098
1099         Status status;
1100         try {
1101             Node node = Node.fromString(nodeName);
1102             if (node == null) {
1103                 ci.println("Invalid Node");
1104                 return;
1105             }
1106             status = this.addPort(node, bridgeName, portName, configs);
1107             ci.println("Port creation status : "+status.toString());
1108         } catch (Throwable e) {
1109             // TODO Auto-generated catch block
1110             e.printStackTrace();
1111             ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
1112         }
1113     }
1114
1115     public void _printCache (CommandInterpreter ci) {
1116         String nodeName = ci.nextArgument();
1117         if (nodeName == null) {
1118             ci.println("Please enter Node Name");
1119             return;
1120         }
1121         Node node = Node.fromString(nodeName);
1122         if (node == null) {
1123             ci.println("Invalid Node");
1124             return;
1125         }
1126         inventoryServiceInternal.printCache(node);
1127     }
1128
1129     public void _forceConnect (CommandInterpreter ci) {
1130         String force = ci.nextArgument();
1131         if (force.equalsIgnoreCase("YES")) forceConnect = true;
1132         else if (force.equalsIgnoreCase("NO")) forceConnect = false;
1133         else ci.println("Please enter YES or NO.");
1134         ci.println("Current ForceConnect State : "+forceConnect);
1135         return;
1136     }
1137
1138     @Override
1139     public String getHelp() {
1140         StringBuffer help = new StringBuffer();
1141         help.append("---OVSDB CLI---\n");
1142         help.append("\t ovsconnect <ConnectionName> <ip-address>                        - Connect to OVSDB\n");
1143         help.append("\t addBridge <Node> <BridgeName>                                   - Add Bridge\n");
1144         help.append("\t getBridgeDomains <Node>                                         - Get Bridges\n");
1145         help.append("\t deleteBridgeDomain <Node> <BridgeName>                          - Delete a Bridge\n");
1146         help.append("\t addPort <Node> <BridgeName> <PortName> <type> <options pairs>   - Add Port\n");
1147         help.append("\t deletePort <Node> <BridgeName> <PortName>                       - Delete Port\n");
1148         help.append("\t addPortVlan <Node> <BridgeName> <PortName> <vlan>               - Add Port, Vlan\n");
1149         help.append("\t addTunnel <Node> <Bridge> <Port> <tunnel-type> <remote-ip>      - Add Tunnel\n");
1150         help.append("\t printCache <Node>                                               - Prints Table Cache");
1151         return help.toString();
1152     }
1153 }