From 5fc5b7a0eb523f9165912eae7d331bef958b7f3e Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Tue, 22 May 2012 21:37:16 +0530 Subject: [PATCH] CS-9919: Adding helper routines to query details of a port profile and associated policy maps. Also updating the error message logs. --- .../utils/cisco/n1kv/vsm/NetconfHelper.java | 29 +++- .../cloud/utils/cisco/n1kv/vsm/PolicyMap.java | 15 +++ .../utils/cisco/n1kv/vsm/PortProfile.java | 29 ++++ .../utils/cisco/n1kv/vsm/VsmCommand.java | 65 ++++++--- .../utils/cisco/n1kv/vsm/VsmOkResponse.java | 1 + .../cisco/n1kv/vsm/VsmPolicyMapResponse.java | 66 +++++++++ .../n1kv/vsm/VsmPortProfileResponse.java | 127 +++++++++++++++++- .../utils/cisco/n1kv/vsm/VsmResponse.java | 4 +- 8 files changed, 313 insertions(+), 23 deletions(-) create mode 100644 utils/src/com/cloud/utils/cisco/n1kv/vsm/PolicyMap.java create mode 100644 utils/src/com/cloud/utils/cisco/n1kv/vsm/PortProfile.java create mode 100644 utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmPolicyMapResponse.java diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java index 9ed83c7356c..0ad368a4dfe 100644 --- a/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java @@ -125,7 +125,7 @@ public class NetconfHelper { public void addPolicyMap(String name, int averageRate, int maxRate, int burstRate) throws CloudRuntimeException { - String command = VsmCommand.getPolicyMap(name, averageRate, maxRate, burstRate); + String command = VsmCommand.getAddPolicyMap(name, averageRate, maxRate, burstRate); if (command != null) { command = command.concat(SSH_NETCONF_TERMINATOR); send(command); @@ -180,18 +180,39 @@ public class NetconfHelper { } } - public void getPortProfileByName(String name) throws CloudRuntimeException { + public PortProfile getPortProfileByName(String name) throws CloudRuntimeException { String command = VsmCommand.getPortProfile(name); if (command != null) { command = command.concat(SSH_NETCONF_TERMINATOR); send(command); // parse the rpc reply. - VsmPortProfileResponse response = new VsmPortProfileResponse(receive().trim()); + String received = receive(); + VsmPortProfileResponse response = new VsmPortProfileResponse(received.trim()); if (!response.isResponseOk()) { throw new CloudRuntimeException("Error response while getting the port profile details."); + } else { + return response.getPortProfile(); } } else { - throw new CloudRuntimeException("Error generating rpc request for removing policy map."); + throw new CloudRuntimeException("Error generating rpc request for getting port profile."); + } + } + + public PolicyMap getPolicyMapByName(String name) throws CloudRuntimeException { + String command = VsmCommand.getPolicyMap(name); + if (command != null) { + command = command.concat(SSH_NETCONF_TERMINATOR); + send(command); + // parse the rpc reply. + String received = receive(); + VsmPolicyMapResponse response = new VsmPolicyMapResponse(received.trim()); + if (!response.isResponseOk()) { + throw new CloudRuntimeException("Error response while getting the port profile details."); + } else { + return response.getPolicyMap(); + } + } else { + throw new CloudRuntimeException("Error generating rpc request for getting policy map."); } } diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/PolicyMap.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/PolicyMap.java new file mode 100644 index 00000000000..08b552258b3 --- /dev/null +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/PolicyMap.java @@ -0,0 +1,15 @@ +package com.cloud.utils.cisco.n1kv.vsm; + +public class PolicyMap { + public String policyMapName; + public int committedRate; + public int burstRate; + public int peakRate; + + PolicyMap() { + policyMapName = null; + committedRate = 0; + burstRate = 0; + peakRate = 0; + } +} diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/PortProfile.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/PortProfile.java new file mode 100644 index 00000000000..10fc6f13fdd --- /dev/null +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/PortProfile.java @@ -0,0 +1,29 @@ +package com.cloud.utils.cisco.n1kv.vsm; + +import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.BindingType; +import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.PortProfileType; +import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.SwitchPortMode; + +public class PortProfile { + public PortProfileType type; + public SwitchPortMode mode; + public BindingType binding; + public String profileName; + public String inputPolicyMap; + public String outputPolicyMap; + public String vlan; + public boolean status; + public int maxPorts; + + PortProfile() { + profileName = null; + inputPolicyMap = null; + outputPolicyMap = null; + vlan = null; + status = false; + maxPorts = 32; + type = PortProfileType.none; + mode = SwitchPortMode.none; + binding = BindingType.none; + } +} diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java index 444e6e07938..d510d6d0676 100644 --- a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java @@ -79,10 +79,10 @@ public class VsmCommand { return serialize(domImpl, doc); } catch (ParserConfigurationException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating add port profile message : " + e.getMessage()); return null; } catch (DOMException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating add port profile message : " + e.getMessage()); return null; } } @@ -113,10 +113,10 @@ public class VsmCommand { return serialize(domImpl, doc); } catch (ParserConfigurationException e) { - s_logger.error("Error while creating update message : " + e.getMessage()); + s_logger.error("Error while creating update port profile message : " + e.getMessage()); return null; } catch (DOMException e) { - s_logger.error("Error while creating update message : " + e.getMessage()); + s_logger.error("Error while creating update port profile message : " + e.getMessage()); return null; } } @@ -146,15 +146,15 @@ public class VsmCommand { return serialize(domImpl, doc); } catch (ParserConfigurationException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating delete port profile message : " + e.getMessage()); return null; } catch (DOMException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating delete port profile message : " + e.getMessage()); return null; } } - public static String getPolicyMap(String name, int averageRate, int maxRate, int burstRate) { + public static String getAddPolicyMap(String name, int averageRate, int maxRate, int burstRate) { try { // Create the document and root element. DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); @@ -179,10 +179,10 @@ public class VsmCommand { return serialize(domImpl, doc); } catch (ParserConfigurationException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating policy map message : " + e.getMessage()); return null; } catch (DOMException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating policy map message : " + e.getMessage()); return null; } } @@ -212,10 +212,10 @@ public class VsmCommand { return serialize(domImpl, doc); } catch (ParserConfigurationException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating delete policy map message : " + e.getMessage()); return null; } catch (DOMException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating delete policy map message : " + e.getMessage()); return null; } } @@ -245,10 +245,10 @@ public class VsmCommand { return serialize(domImpl, doc); } catch (ParserConfigurationException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating attach/detach service policy message : " + e.getMessage()); return null; } catch (DOMException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating attach/detach service policy message : " + e.getMessage()); return null; } } @@ -282,10 +282,43 @@ public class VsmCommand { return serialize(domImpl, doc); } catch (ParserConfigurationException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating the message to get port profile details: " + e.getMessage()); return null; } catch (DOMException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating the message to get port profile details: " + e.getMessage()); + return null; + } + } + + public static String getPolicyMap(String name) { + try { + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + DOMImplementation domImpl = docBuilder.getDOMImplementation(); + Document doc = createDocument(domImpl); + + Element get = doc.createElement("nf:get"); + doc.getDocumentElement().appendChild(get); + + Element filter = doc.createElement("nf:filter"); + filter.setAttribute("type", "subtree"); + get.appendChild(filter); + + // Create the show port-profile name command. + Element show = doc.createElement("show"); + filter.appendChild(show); + Element policyMap = doc.createElement("policy-map"); + show.appendChild(policyMap); + Element nameNode = doc.createElement("name"); + nameNode.setTextContent(name); + policyMap.appendChild(nameNode); + + return serialize(domImpl, doc); + } catch (ParserConfigurationException e) { + s_logger.error("Error while creating the message to get policy map details : " + e.getMessage()); + return null; + } catch (DOMException e) { + s_logger.error("Error while creating the message to get policy map details : " + e.getMessage()); return null; } } @@ -312,7 +345,7 @@ public class VsmCommand { s_logger.error("Error while creating hello message : " + e.getMessage()); return null; } catch (DOMException e) { - s_logger.error("Error while creating delete message : " + e.getMessage()); + s_logger.error("Error while creating hello message : " + e.getMessage()); return null; } } diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmOkResponse.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmOkResponse.java index bdcffce7ef4..ed25238ed1f 100644 --- a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmOkResponse.java +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmOkResponse.java @@ -7,6 +7,7 @@ public class VsmOkResponse extends VsmResponse { VsmOkResponse(String response) { super(response); + initialize(); } protected void parse(Element root) { diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmPolicyMapResponse.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmPolicyMapResponse.java new file mode 100644 index 00000000000..ffd2088a9d6 --- /dev/null +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmPolicyMapResponse.java @@ -0,0 +1,66 @@ +package com.cloud.utils.cisco.n1kv.vsm; + +import org.apache.log4j.Logger; + +import org.w3c.dom.DOMException; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class VsmPolicyMapResponse extends VsmResponse{ + private static final Logger s_logger = Logger.getLogger(VsmPolicyMapResponse.class); + private static final String s_policyMapDetails = "__XML__OPT_Cmd_show_policy-map___readonly__"; + + private PolicyMap _policyMap = new PolicyMap(); + + VsmPolicyMapResponse(String response) { + super(response); + initialize(); + } + + public PolicyMap getPolicyMap() { + return _policyMap; + } + + protected void parse(Element root) { + NodeList list = root.getElementsByTagName("nf:rpc-error"); + if (list.getLength() == 0) { + // No rpc-error tag; means response was ok. + NodeList dataList = root.getElementsByTagName("nf:data"); + if (dataList.getLength() > 0) { + parseData(dataList.item(0)); + _responseOk = true; + } + } else { + super.parseError(list.item(0)); + _responseOk = false; + } + } + + protected void parseData(Node data) { + try { + NodeList list = ((Element)data).getElementsByTagName(s_policyMapDetails); + if (list.getLength() > 0) { + NodeList readOnlyList = ((Element)list.item(0)).getElementsByTagName("__readonly__"); + Element readOnly = (Element)readOnlyList.item(0); + + for (Node node = readOnly.getFirstChild(); + node != null; node = node.getNextSibling()) { + String currentNode = node.getNodeName(); + String value = node.getTextContent(); + if ("pmap-name-out".equalsIgnoreCase(currentNode)) { + _policyMap.policyMapName = value; + } else if ("cir".equalsIgnoreCase(currentNode)) { + _policyMap.committedRate = Integer.parseInt(value.trim()); + } else if ("bc".equalsIgnoreCase(currentNode)) { + _policyMap.burstRate = Integer.parseInt(value.trim()); + } else if ("pir".equalsIgnoreCase(currentNode)) { + _policyMap.peakRate = Integer.parseInt(value.trim()); + } + } + } + } catch (DOMException e) { + s_logger.error("Error parsing the response : " + e.toString()); + } + } +} diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmPortProfileResponse.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmPortProfileResponse.java index ed43bd8f1cc..6973c0ec828 100644 --- a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmPortProfileResponse.java +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmPortProfileResponse.java @@ -1,22 +1,145 @@ package com.cloud.utils.cisco.n1kv.vsm; +import org.apache.log4j.Logger; + +import org.w3c.dom.DOMException; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.util.StringTokenizer; + +import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.*; public class VsmPortProfileResponse extends VsmResponse { + private static final Logger s_logger = Logger.getLogger(VsmPortProfileResponse.class); + private static final String s_portProfileDetails = "__XML__OPT_Cmd_show_port_profile___readonly__"; + + private PortProfile _portProfile = new PortProfile(); + VsmPortProfileResponse(String response) { super(response); + initialize(); + } + + public PortProfile getPortProfile() { + return _portProfile; } protected void parse(Element root) { NodeList list = root.getElementsByTagName("nf:rpc-error"); if (list.getLength() == 0) { // No rpc-error tag; means response was ok. - assert(root.getElementsByTagName("nf:ok").getLength() > 0); - _responseOk = true; + NodeList dataList = root.getElementsByTagName("nf:data"); + if (dataList.getLength() > 0) { + parseData(dataList.item(0)); + _responseOk = true; + } } else { super.parseError(list.item(0)); _responseOk = false; } } + + protected void parseData(Node data) { + try { + NodeList list = ((Element)data).getElementsByTagName(s_portProfileDetails); + if (list.getLength() > 0) { + NodeList readOnlyList = ((Element)list.item(0)).getElementsByTagName("__readonly__"); + Element readOnly = (Element)readOnlyList.item(0); + + for (Node node = readOnly.getFirstChild(); + node != null; node = node.getNextSibling()) { + String currentNode = node.getNodeName(); + String value = node.getTextContent(); + if ("port_binding".equalsIgnoreCase(currentNode)) { + setPortBinding(value); + } else if ("profile_name".equalsIgnoreCase(currentNode)) { + // Set the port profile name. + _portProfile.profileName = value; + } else if ("profile_cfg".equalsIgnoreCase(currentNode)) { + setProfileConfiguration(value); + } else if ("type".equalsIgnoreCase(currentNode)) { + setPortType(value); + } else if ("status".equalsIgnoreCase(currentNode)) { + // Has the profile been enabled. + if (value.equalsIgnoreCase("1")) { + _portProfile.status = true; + } + } else if ("max_ports".equalsIgnoreCase(currentNode)) { + // Has the profile been enabled. + _portProfile.maxPorts = Integer.parseInt(value.trim()); + } + } + } + } catch (DOMException e) { + s_logger.error("Error parsing the response : " + e.toString()); + } + } + + private void setProfileConfiguration(String value) { + StringTokenizer tokens = new StringTokenizer(value.trim()); + if (tokens.hasMoreTokens()) { + String currentToken = tokens.nextToken(); + if ("switchport".equalsIgnoreCase(currentToken)) { + parseProfileMode(tokens); + } else if ("service-policy".equalsIgnoreCase(currentToken)) { + String ioType = tokens.nextToken(); + if ("input".equalsIgnoreCase(ioType)) { + _portProfile.inputPolicyMap = tokens.nextToken(); + } else if ("output".equalsIgnoreCase(ioType)) { + _portProfile.outputPolicyMap = tokens.nextToken(); + } + } + } + } + + private void parseProfileMode(StringTokenizer tokens) { + if (tokens.hasMoreTokens()) { + String firstToken = tokens.nextToken(); + if ("mode".equalsIgnoreCase(firstToken)) { + setPortMode(tokens.nextToken()); + } else if ("access".equalsIgnoreCase(firstToken)) { + if (tokens.hasMoreTokens()) { + String secondToken = tokens.nextToken(); + assert("vlan".equalsIgnoreCase(secondToken)); + if (tokens.hasMoreTokens()) { + _portProfile.vlan = tokens.nextToken(); + } + } + } + } + } + + private void setPortMode(String value) { + // Set the mode for port profile. + if ("access".equalsIgnoreCase(value)) { + _portProfile.mode = SwitchPortMode.access; + } else if ("trunk".equalsIgnoreCase(value)) { + _portProfile.mode = SwitchPortMode.trunk; + } else if ("privatevlanhost".equalsIgnoreCase(value)) { + _portProfile.mode = SwitchPortMode.privatevlanhost; + } else if ("privatevlanpromiscuous".equalsIgnoreCase(value)) { + _portProfile.mode = SwitchPortMode.privatevlanpromiscuous; + } + } + + private void setPortBinding(String value) { + // Set the binding type for the port profile. + if ("static".equalsIgnoreCase(value)) { + _portProfile.binding = BindingType.portbindingstatic; + } else if ("dynamic".equalsIgnoreCase(value)) { + _portProfile.binding = BindingType.portbindingdynamic; + } else if ("ephermal".equalsIgnoreCase(value)) { + _portProfile.binding = BindingType.portbindingephermal; + } + } + + private void setPortType(String value) { + // Set the type field (vethernet/ethernet). + if ("vethernet".equalsIgnoreCase(value)) { + _portProfile.type = PortProfileType.vethernet; + } else if ("ethernet".equalsIgnoreCase(value)) { + _portProfile.type = PortProfileType.ethernet; + } + } } diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmResponse.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmResponse.java index 6391f12d210..6270d45f912 100644 --- a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmResponse.java +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmResponse.java @@ -8,7 +8,6 @@ import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; -import org.w3c.dom.NodeList; import org.w3c.dom.DOMException; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSSerializer; @@ -73,7 +72,10 @@ public abstract class VsmResponse { _tag = ErrorTag.InUse; _type = ErrorType.rpc; _severity = ErrorSeverity.error; + _docResponse = null; + } + protected void initialize() { try { DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); docFactory.setNamespaceAware(true);