1 package org.opendaylight.ovsdb.internal;
3 import java.net.InetAddress;
4 import java.net.UnknownHostException;
7 import org.eclipse.osgi.framework.console.CommandInterpreter;
8 import org.eclipse.osgi.framework.console.CommandProvider;
9 import org.opendaylight.ovsdb.database.OVSBridge;
10 import org.opendaylight.ovsdb.database.OVSInstance;
11 import org.opendaylight.ovsdb.database.OvsdbType;
12 import org.opendaylight.controller.sal.connection.ConnectionConstants;
13 import org.opendaylight.controller.sal.core.Node;
14 import org.opendaylight.controller.sal.core.NodeConnector;
15 import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants;
16 import org.opendaylight.controller.sal.networkconfig.bridgedomain.IPluginInBridgeDomainConfigService;
17 import org.opendaylight.controller.sal.utils.Status;
18 import org.opendaylight.controller.sal.utils.StatusCode;
19 import org.osgi.framework.BundleContext;
20 import org.osgi.framework.FrameworkUtil;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
24 public class ConfigurationService implements IPluginInBridgeDomainConfigService, CommandProvider
26 private static final Logger logger = LoggerFactory
27 .getLogger(ConfigurationService.class);
29 IConnectionServiceInternal connectionService;
30 boolean forceConnect = false;
36 * Function called by the dependency manager when at least one dependency
37 * become unsatisfied or when the component is shutting down because for
38 * example bundle is being stopped.
45 * Function called by dependency manager after "init ()" is called and after
46 * the services provided by the class are registered in the service registry
50 registerWithOSGIConsole();
53 private void registerWithOSGIConsole() {
54 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
56 bundleContext.registerService(CommandProvider.class.getName(), this,
61 * Function called by the dependency manager before the services exported by
62 * the component are unregistered, this will be followed by a "destroy ()"
69 public void setConnectionServiceInternal(IConnectionServiceInternal connectionService) {
70 this.connectionService = connectionService;
73 public void unsetConnectionServiceInternal(IConnectionServiceInternal connectionService) {
74 if (this.connectionService == connectionService) {
75 this.connectionService = null;
79 private Connection getConnection (Node node) {
81 Connection connection = connectionService.getConnection(node);
82 if (connection == null || connection.getSocket() == null) {
87 * This is possible only when the connection is disconnected due to any reason.
88 * But, we have to implement ECHO handling else, it results in timeout and the
89 * connection being partially closed from the server side and the client Socket
90 * seems to be up. Hence forcing the issue for now till we implement the ECHO.
92 if (connection.getSocket().isClosed() || forceConnect) {
93 String address = connection.getSocket().getInetAddress().getHostAddress();
94 Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
95 params.put(ConnectionConstants.ADDRESS, address);
96 params.put(ConnectionConstants.PORT, connection.getSocket().getPort()+"");
97 node = connectionService.connect(connection.getIdentifier(), params);
98 connection = connectionService.getConnection(node);
100 if (connection == null || connection.getSocket() == null || connection.getSocket().isClosed()) {
107 * @param node Node serving this configuration service
108 * @param bridgeConnectorIdentifier String representation of a Bridge Connector
109 * @return Bridge Connector configurations
112 public Status createBridgeDomain(Node node, String bridgeIdentifier,
113 Map<ConfigConstants, Object> configs) throws Throwable {
115 if (connectionService == null) {
116 logger.error("Couldn't refer to the ConnectionService");
117 return new Status(StatusCode.NOSERVICE);
120 Connection connection = this.getConnection(node);
121 if (connection == null || connection.getSocket() == null) {
122 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
125 if (connection != null) {
126 String newBridge = "new_bridge";
127 String newInterface = "new_interface";
128 String newPort = "new_port";
129 String newSwitch = "new_switch";
131 Object addSwitchRequest;
133 OVSInstance instance = OVSInstance.monitorOVS(connection);
135 if(instance != null){
136 List<String> bridgeUuidPair = new ArrayList<String>();
137 bridgeUuidPair.add("named-uuid");
138 bridgeUuidPair.add(newBridge);
140 List<Object> mutation = new ArrayList<Object>();
141 mutation.add("bridges");
142 mutation.add("insert");
143 mutation.add(bridgeUuidPair);
145 List<Object> mutations = new ArrayList<Object>();
146 mutations.add(mutation);
148 List<String> ovsUuidPair = new ArrayList<String>();
149 ovsUuidPair.add("uuid");
150 ovsUuidPair.add(instance.getUuid());
152 List<Object> whereInner = new ArrayList<Object>();
153 whereInner.add("_uuid");
154 whereInner.add("==");
155 whereInner.add(ovsUuidPair);
157 List<Object> where = new ArrayList<Object>();
158 where.add(whereInner);
160 addSwitchRequest = new MutateRequest("Open_vSwitch", where, mutations);
163 Map<String, Object> vswitchRow = new HashMap<String, Object>();
164 ArrayList<String> bridges = new ArrayList<String>();
165 bridges.add("named-uuid");
166 bridges.add(newBridge);
167 vswitchRow.put("bridges", bridges);
168 addSwitchRequest = new InsertRequest("insert", "Open_vSwitch", newSwitch, vswitchRow);
171 Map<String, Object> bridgeRow = new HashMap<String, Object>();
172 bridgeRow.put("name", bridgeIdentifier);
173 ArrayList<String> ports = new ArrayList<String>();
174 ports.add("named-uuid");
176 bridgeRow.put("ports", ports);
177 InsertRequest addBridgeRequest = new InsertRequest("insert", "Bridge", newBridge, bridgeRow);
179 Map<String, Object> portRow = new HashMap<String, Object>();
180 portRow.put("name", bridgeIdentifier);
181 ArrayList<String> interfaces = new ArrayList<String>();
182 interfaces.add("named-uuid");
183 interfaces.add(newInterface);
184 portRow.put("interfaces", interfaces);
185 InsertRequest addPortRequest = new InsertRequest("insert", "Port", newPort, portRow);
187 Map<String, Object> interfaceRow = new HashMap<String, Object>();
188 interfaceRow.put("name", bridgeIdentifier);
189 interfaceRow.put("type", "internal");
190 InsertRequest addIntfRequest = new InsertRequest("insert", "Interface", newInterface, interfaceRow);
192 Object[] params = {"Open_vSwitch", addSwitchRequest, addIntfRequest, addPortRequest, addBridgeRequest};
193 OvsdbMessage msg = new OvsdbMessage("transact", params);
195 connection.sendMessage(msg);
200 return new Status(StatusCode.SUCCESS);
204 * Create a Port Attached to a Bridge
205 * Ex. ovs-vsctl add-port br0 vif0
206 * @param node Node serving this configuration service
207 * @param bridgeDomainIdentifier String representation of a Bridge Domain
208 * @param portIdentifier String representation of a user defined Port Name
211 public Status addPort(Node node, String bridgeIdentifier, String portIdentifier, Map<ConfigConstants, Object> configs) {
213 if (connectionService == null) {
214 logger.error("Couldn't refer to the ConnectionService");
215 return new Status(StatusCode.NOSERVICE);
217 Connection connection = this.getConnection(node);
218 if (connection == null || connection.getSocket() == null) {
219 return new Status(StatusCode.NOSERVICE, "Connection to ovsdb-server not available");
222 if (connection != null) {
223 String newInterface = "new_interface";
224 String newPort = "new_port";
226 Map<String, OVSBridge> existingBridges = OVSBridge.monitorBridge(connection);
228 OVSBridge bridge = existingBridges.get(bridgeIdentifier);
230 List<String> portUuidPair = new ArrayList<String>();
231 portUuidPair.add("named-uuid");
232 portUuidPair.add(newPort);
234 List<Object> mutation = new ArrayList<Object>();
235 mutation.add("ports");
236 mutation.add("insert");
237 mutation.add(portUuidPair);
238 List<Object> mutations = new ArrayList<Object>();
239 mutations.add(mutation);
241 List<String> bridgeUuidPair = new ArrayList<String>();
242 bridgeUuidPair.add("uuid");
243 bridgeUuidPair.add(bridge.getUuid());
245 List<Object> whereInner = new ArrayList<Object>();
246 whereInner.add("_uuid");
247 whereInner.add("==");
248 whereInner.add(bridgeUuidPair);
250 List<Object> where = new ArrayList<Object>();
251 where.add(whereInner);
253 MutateRequest mutateBridgeRequest = new MutateRequest("Bridge", where, mutations);
255 Map<String, Object> portRow = new HashMap<String, Object>();
256 portRow.put("name", portIdentifier);
257 String portType = null;
258 if (configs != null) {
259 portType = (String)configs.get(ConfigConstants.TYPE);
260 if (portType != null && portType.equalsIgnoreCase(OvsdbType.PortType.VLAN.name())) {
262 portRow.put("tag", Integer.parseInt((String)configs.get(ConfigConstants.VLAN)));
263 } catch (Exception e) {
267 ArrayList<String> interfaces = new ArrayList<String>();
268 interfaces.add("named-uuid");
269 interfaces.add(newInterface);
270 portRow.put("interfaces", interfaces);
271 InsertRequest addPortRequest = new InsertRequest("insert", "Port", newPort, portRow);
273 Map<String, Object> interfaceRow = new HashMap<String, Object>();
274 interfaceRow.put("name", portIdentifier);
277 if (portType != null && portType.equalsIgnoreCase(OvsdbType.PortType.TUNNEL.name())) {
278 interfaceRow.put("type", configs.get(ConfigConstants.TUNNEL_TYPE));
279 ArrayList<Object> intopt = new ArrayList<Object>();
280 interfaceRow.put("options", intopt);
281 ArrayList<Object> intoptmap = new ArrayList<Object>();
282 ArrayList<String> intoptep = new ArrayList<String>();
284 intopt.add(intoptmap);
285 intoptmap.add(intoptep);
286 intoptep.add("remote_ip");
287 intoptep.add((String)configs.get(ConfigConstants.DEST_IP));
289 InsertRequest addIntfRequest = new InsertRequest("insert", "Interface", newInterface, interfaceRow);
291 Object[] params = {"Open_vSwitch", mutateBridgeRequest, addIntfRequest, addPortRequest};
292 OvsdbMessage msg = new OvsdbMessage("transact", params);
294 connection.sendMessage(msg);
299 return new Status(StatusCode.SUCCESS);
302 * Implements the OVS Connection for Managers
304 * @param node Node serving this configuration service
305 * @param String with IP and connection types
307 @SuppressWarnings("unchecked")
308 public boolean setManager(Node node, String managerip) throws Throwable{
310 if (connectionService == null) {
311 logger.error("Couldn't refer to the ConnectionService");
314 Connection connection = this.getConnection(node);
315 if (connection == null || connection.getSocket() == null) {
319 if (connection != null) {
320 String newmanager = "new_manager";
322 OVSInstance instance = OVSInstance.monitorOVS(connection);
324 Map ovsoutter = new LinkedHashMap();
325 Map ovsinner = new LinkedHashMap();
326 ArrayList ovsalist1 = new ArrayList();
327 ArrayList ovsalist2 = new ArrayList();
328 ArrayList ovsalist3 = new ArrayList();
329 ArrayList ovsalist4 = new ArrayList();
332 ovsoutter.put("where", ovsalist1);
333 ovsalist1.add(ovsalist2);
334 ovsalist2.add("_uuid");
336 ovsalist2.add(ovsalist3);
337 ovsalist3.add("uuid");
338 ovsalist3.add(instance.getUuid());
339 ovsoutter.put("op", "update");
340 ovsoutter.put("table", "Open_vSwitch");
341 ovsoutter.put("row", ovsinner);
342 ovsinner.put("manager_options", ovsalist4);
343 ovsalist4.add("named-uuid");
344 ovsalist4.add(newmanager);
346 Map mgroutside = new LinkedHashMap();
347 Map mgrinside = new LinkedHashMap();
349 //Manager Table Insert
350 mgroutside.put("uuid-name", newmanager);
351 mgroutside.put("op", "insert");
352 mgroutside.put("table","Manager");
353 mgroutside.put("row", mgrinside);
354 mgrinside.put("target", managerip);
356 Object[] params = {"Open_vSwitch", ovsoutter, mgroutside};
357 OvsdbMessage msg = new OvsdbMessage("transact", params);
359 connection.sendMessage(msg);
369 public Status addBridgeDomainConfig(Node node, String bridgeIdentfier,
370 Map<ConfigConstants, Object> configs) {
371 String mgmt = (String)configs.get(ConfigConstants.MGMT);
374 if (setManager(node, mgmt)) return new Status(StatusCode.SUCCESS);
375 } catch (Throwable e) {
376 // TODO Auto-generated catch block
378 return new Status(StatusCode.INTERNALERROR);
381 return new Status(StatusCode.BADREQUEST);
385 public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier,
386 Map<ConfigConstants, Object> configs) {
387 // TODO Auto-generated method stub
392 public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier) {
393 // TODO Auto-generated method stub
398 public Node getBridgeDomainNode(Node node, String bridgeIdentifier) {
399 // TODO Auto-generated method stub
404 public Map<ConfigConstants, Object> getPortConfigs(Node node, String bridgeIdentifier,
405 String portIdentifier) {
406 // TODO Auto-generated method stub
411 public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier,
412 Map<ConfigConstants, Object> configs) {
413 // TODO Auto-generated method stub
418 public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier,
419 Map<ConfigConstants, Object> configs) {
420 // TODO Auto-generated method stub
425 public Status deleteBridgeDomain(Node node, String bridgeIdentifier) {
426 // TODO Auto-generated method stub
431 public Map<ConfigConstants, Object> getBridgeDomainConfigs(Node node, String bridgeIdentifier) {
432 // TODO Auto-generated method stub
437 public List<String> getBridgeDomains(Node node) {
439 Connection connection = connectionService.getConnection(node);
440 Map<String, OVSBridge> existingBridges = OVSBridge.monitorBridge(connection);
441 List<String> bridgeDomains = new ArrayList<String>(existingBridges.keySet());
442 return bridgeDomains;
446 public NodeConnector getNodeConnector(Node arg0, String arg1, String arg2) {
450 public void _ovsconnect (CommandInterpreter ci) {
451 String bridgeName = ci.nextArgument();
452 if (bridgeName == null) {
453 ci.println("Please enter Bridge Name");
457 String ovsdbserver = ci.nextArgument();
458 if (ovsdbserver == null) {
459 ci.println("Please enter valid IP-Address");
463 InetAddress.getByName(ovsdbserver);
464 } catch (Exception e) {
466 ci.println("Please enter valid IP-Address");
469 String port = ci.nextArgument();
474 ci.println("connecting to ovsdb server : "+ovsdbserver+":"+port+" ... ");
475 Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
476 params.put(ConnectionConstants.ADDRESS, ovsdbserver);
477 params.put(ConnectionConstants.PORT, port);
478 Node node = connectionService.connect(bridgeName, params);
479 if (node != null) ci.println("Node Name: "+node.toString());
480 else ci.println("Could not connect to Node");
483 public void _addBridge (CommandInterpreter ci) {
484 String nodeName = ci.nextArgument();
485 if (nodeName == null) {
486 ci.println("Please enter Node Name");
490 String bridgeName = ci.nextArgument();
491 if (bridgeName == null) {
492 ci.println("Please enter Bridge Name");
497 status = this.createBridgeDomain(Node.fromString(nodeName), bridgeName, null);
498 ci.println("Bridge creation status : "+status.toString());
499 } catch (Throwable e) {
500 // TODO Auto-generated catch block
502 ci.println("Failed to create Bridge "+bridgeName);
506 public void _addPort (CommandInterpreter ci) {
507 String nodeName = ci.nextArgument();
508 if (nodeName == null) {
509 ci.println("Please enter Node Name");
513 String bridgeName = ci.nextArgument();
514 if (bridgeName == null) {
515 ci.println("Please enter Bridge Name");
519 String portName = ci.nextArgument();
520 if (portName == null) {
521 ci.println("Please enter Port Name");
527 status = this.addPort(Node.fromString(nodeName), bridgeName, portName, null);
528 ci.println("Port creation status : "+status.toString());
529 } catch (Throwable e) {
530 // TODO Auto-generated catch block
532 ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
536 public void _addPortVlan (CommandInterpreter ci) {
537 String nodeName = ci.nextArgument();
538 if (nodeName == null) {
539 ci.println("Please enter Node Name");
543 String bridgeName = ci.nextArgument();
544 if (bridgeName == null) {
545 ci.println("Please enter Bridge Name");
549 String portName = ci.nextArgument();
550 if (portName == null) {
551 ci.println("Please enter Port Name");
555 String vlan = ci.nextArgument();
557 ci.println("Please enter Valid Vlan");
561 Integer.parseInt(vlan);
562 } catch (Exception e) {
563 ci.println("Please enter Valid Vlan");
568 Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
569 configs.put(ConfigConstants.TYPE, "VLAN");
570 configs.put(ConfigConstants.VLAN, vlan);
574 status = this.addPort(Node.fromString(nodeName), bridgeName, portName, configs);
575 ci.println("Port creation status : "+status.toString());
576 } catch (Throwable e) {
577 // TODO Auto-generated catch block
579 ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
583 public void _addTunnel (CommandInterpreter ci) {
584 String nodeName = ci.nextArgument();
585 if (nodeName == null) {
586 ci.println("Please enter Node Name");
590 String bridgeName = ci.nextArgument();
591 if (bridgeName == null) {
592 ci.println("Please enter Bridge Name");
596 String portName = ci.nextArgument();
597 if (portName == null) {
598 ci.println("Please enter Port Name");
602 String tunnelType = ci.nextArgument();
603 if (tunnelType == null) {
604 ci.println("Please enter Tunnel Type");
608 String remoteIp = ci.nextArgument();
609 if (remoteIp == null) {
610 ci.println("Please enter valid Remote IP Address");
615 InetAddress.getByName(remoteIp);
616 } catch (Exception e) {
618 ci.println("Please enter valid Remote IP Address");
622 Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
623 configs.put(ConfigConstants.TYPE, "TUNNEL");
624 configs.put(ConfigConstants.TUNNEL_TYPE, tunnelType);
625 configs.put(ConfigConstants.DEST_IP, remoteIp);
629 status = this.addPort(Node.fromString(nodeName), bridgeName, portName, configs);
630 ci.println("Port creation status : "+status.toString());
631 } catch (Throwable e) {
632 // TODO Auto-generated catch block
634 ci.println("Failed to create Port "+portName+" in Bridge "+bridgeName);
638 public void _forceConnect (CommandInterpreter ci) {
639 String force = ci.nextArgument();
640 if (force.equalsIgnoreCase("YES")) forceConnect = true;
641 else if (force.equalsIgnoreCase("NO")) forceConnect = false;
642 else ci.println("Please enter YES or NO.");
643 ci.println("Current ForceConnect State : "+forceConnect);
648 public String getHelp() {
649 StringBuffer help = new StringBuffer();
650 help.append("---OVSDB CLI---\n");
651 help.append("\t ovsconnect <ConnectionName> <ip-address> - Connect to OVSDB\n");
652 help.append("\t addBridge <Node> <BridgeName> - Add Bridge\n");
653 help.append("\t addPort <Node> <BridgeName> <PortName> - Add Port\n");
654 help.append("\t addPortVlan <Node> <BridgeName> <PortName> <vlan> - Add Port, Vlan\n");
655 help.append("\t addTunnel <Node> <Bridge> <Port> <tunnel-type> <remote-ip> - Add Tunnel\n");
656 help.append("\t forceConnect <yes|no> - Force a new OVSDB Connection for every command (Workaround)");
657 return help.toString();