Commit 70796e9e authored by Tarun Prabhu's avatar Tarun Prabhu

Big commit with a lot of changes to add the rspec parser base class as well as...

Big commit with a lot of changes to add the rspec parser base class as well as for version 1 and version 2. These changes are not throughly tested yet, and the
extension support hasn't yet been integrated into the main parser. The v1 and v2 support has.
parent aa1dd338
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#ifdef NEW_GCC #ifdef NEW_GCC
#include <ext/hash_map> #include <ext/hash_map>
#include <ext/hash_fun.h> #include <ext/hash_fun.h>
using namespace __gnu_cxx; using namespace __gnu_cxx;
#define RANDOM() random() #define RANDOM() random()
#else #else
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2008, 2009 University of Utah and the Flux Group.
* All rights reserved.
*/
/*
* XML Parser for emulab extensions for rspec
*/
#ifdef WITH_XML
#include "emulab_extensions_parser.h"
XERCES_CPP_NAMESPACE_USE
using namespace std;
struct fd emulab_extensions_parser::readFeatureDesire (DOMElement* tag)
{
}
#endif // WITH_XML
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2008, 2009 University of Utah and the Flux Group.
* All rights reserved.
*/
#ifndef __EMULAB_EXTENSIONS_PARSER_H__
#define __EMULAB_EXTENSIONS_PARSER_H__
#ifdef WITH_XML
#include <string>
#include <xercesc/dom/DOM.hpp>
#include "rspec_parser_helper.h"
#define LOCAL_OPERATOR 0
#define GLOBAL_OPERATOR 1
#define HARD 0
#define SOFT 1
struct emulab_operator {
std::string op;
int type;
};
struct fd
{
std::string fd_name;
float fd_weight;
bool violatable;
struct emulab_operator op;
};
struct node_flags
{
int trivialBandwidth;
std::string subnodeOf;
bool unique;
bool disallowTrivialMix;
};
struct link_flags
{
bool noDelay;
bool multiplexOk;
bool trivialOk;
std::string fixSrcIface;
std::string fixDstIface;
};
struct hardness {
int type;
float weight;
};
struct vclass {
std::string name;
struct hardness;
std::string physicalType;
};
struct property {
std::string name;
float value;
float penalty;
bool violatable;
struct emulab_operator op;
};
class emulab_extensions_parser : public rspec_parser_helper {
private:
int type;
public:
// Constructor
emulab_extensions_parser(int type) { this->type = type; }
// Functions
struct fd readFeatureDesire (xercesc::DOMElement* tag);
struct node_flags readNodeFlag (xercesc::DOMElement* tag);
struct link_flags readLinkFlag (xercesc::DOMElement* tag);
struct property readProperty (xercesc::DOMElement* tag);
struct vclass readVClass (xercesc::DOMElement* tag);
std::string readAssignedTo (xercesc::DOMElement* tag);
std::string readHintTo (xercesc::DOMElement* tag);
};
#endif // WITH_XML
#endif // __EMULAB_EXTENSIONS_PARSER_H__
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <cstring>
using namespace std; using namespace std;
#ifdef NEW_GCC #ifdef NEW_GCC
#include <ext/hash_fun.h> #include <ext/hash_fun.h>
//#include <hash_fun.h>
using namespace __gnu_cxx; using namespace __gnu_cxx;
#else #else
#include <stl_hash_fun.h> #include <stl_hash_fun.h>
......
This diff is collapsed.
This diff is collapsed.
...@@ -18,31 +18,6 @@ ...@@ -18,31 +18,6 @@
#include "xstr.h" #include "xstr.h"
#include <xercesc/dom/DOM.hpp> #include <xercesc/dom/DOM.hpp>
// Returns the attribute value and an out paramter if the attribute exists
string rspec_parser :: getAttribute(const DOMElement* tag,
const string attrName,
bool& hasAttr)
{
hasAttr = tag->hasAttribute(XStr(attrName.c_str()).x());
if (hasAttr)
return XStr(tag->getAttribute(XStr(attrName.c_str()).x())).c();
return "";
}
bool rspec_parser :: hasAttribute(const DOMElement* tag, const string attrName)
{
return (tag->hasAttribute(XStr(attrName).x()));
}
string rspec_parser :: readSubnodeOf (const DOMElement* tag, bool& isSubnode)
{
isSubnode = hasChildTag(tag, "subnode_of");
string rv = "";
if (isSubnode)
rv = XStr(getChildValue(tag, "subnode_of")).c();
return rv;
}
struct link_interface rspec_parser :: getIface (const DOMElement* tag) struct link_interface rspec_parser :: getIface (const DOMElement* tag)
{ {
bool exists; bool exists;
...@@ -58,7 +33,7 @@ struct link_interface rspec_parser :: getIface (const DOMElement* tag) ...@@ -58,7 +33,7 @@ struct link_interface rspec_parser :: getIface (const DOMElement* tag)
// Returns the component_id. Sets an out parameter to true if an ID is present // Returns the component_id. Sets an out parameter to true if an ID is present
string rspec_parser :: readPhysicalId (const DOMElement* tag, string rspec_parser :: readPhysicalId (const DOMElement* tag,
bool& hasComponentId) bool& hasComponentId)
{ {
return (this->getAttribute(tag, "component_id", hasComponentId)); return (this->getAttribute(tag, "component_id", hasComponentId));
} }
...@@ -71,9 +46,16 @@ string rspec_parser :: readVirtualId (const DOMElement* tag, bool& hasClientId) ...@@ -71,9 +46,16 @@ string rspec_parser :: readVirtualId (const DOMElement* tag, bool& hasClientId)
// Returns the CMID and sets an out parameter to true if an ID is present // Returns the CMID and sets an out parameter to true if an ID is present
string rspec_parser :: readComponentManagerId (const DOMElement* tag, string rspec_parser :: readComponentManagerId (const DOMElement* tag,
bool& cmId) bool& hasCmId)
{ {
return (this->getAttribute(tag, "component_manager_id", cmId)); return (this->getAttribute(tag, "component_manager_id", hasCmId));
}
string rspec_parser::readVirtualizationType (const DOMElement* tag,
bool& hasVirtualizationType)
{
return(this->getAttribute(tag, "virtualization_type",
hasVirtualizationType));
} }
// //
...@@ -81,7 +63,7 @@ string rspec_parser :: readComponentManagerId (const DOMElement* tag, ...@@ -81,7 +63,7 @@ string rspec_parser :: readComponentManagerId (const DOMElement* tag,
// Returns true if the latitude and longitude tags are present // Returns true if the latitude and longitude tags are present
// Absence of the country tag will be caught by the schema validator // Absence of the country tag will be caught by the schema validator
vector<string> rspec_parser :: readLocation (const DOMElement* tag, vector<string> rspec_parser :: readLocation (const DOMElement* tag,
int& rvLength) int& rvLength)
{ {
bool hasCountry, hasLatitude, hasLongitude; bool hasCountry, hasLatitude, hasLongitude;
...@@ -100,11 +82,12 @@ vector<string> rspec_parser :: readLocation (const DOMElement* tag, ...@@ -100,11 +82,12 @@ vector<string> rspec_parser :: readLocation (const DOMElement* tag,
// Returns a list of node_type elements // Returns a list of node_type elements
// The out parameter contains the number of elements found // The out parameter contains the number of elements found
list<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node, vector<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node,
int& typeCount) int& typeCount,
int unlimitedSlots)
{ {
DOMNodeList* nodeTypes = node->getElementsByTagName(XStr("node_type").x()); DOMNodeList* nodeTypes = node->getElementsByTagName(XStr("node_type").x());
list<struct node_type> types; vector<struct node_type> types;
for (int i = 0; i < nodeTypes->getLength(); i++) for (int i = 0; i < nodeTypes->getLength(); i++)
{ {
DOMElement *tag = dynamic_cast<DOMElement*>(nodeTypes->item(i)); DOMElement *tag = dynamic_cast<DOMElement*>(nodeTypes->item(i));
...@@ -113,8 +96,8 @@ list<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node, ...@@ -113,8 +96,8 @@ list<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node,
int typeSlots; int typeSlots;
string slot = XStr(tag->getAttribute(XStr("type_slots").x())).c(); string slot = XStr(tag->getAttribute(XStr("type_slots").x())).c();
if (slot.compare("unlimited") == 0) if (slot == "unlimited")
typeSlots = 1000; typeSlots = unlimitedSlots;
else else
typeSlots = atoi(slot.c_str()); typeSlots = atoi(slot.c_str());
...@@ -126,9 +109,13 @@ list<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node, ...@@ -126,9 +109,13 @@ list<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node,
return types; return types;
} }
int rspec_parser::readInterfacesOnNode (const DOMElement* node, bool& allUnique) // Returns any fixed interfaces which are found
map< pair<string, string>, pair<string, string> >
rspec_parser::readInterfacesOnNode (const DOMElement* node,
bool& allUnique)
{ {
DOMNodeList* ifaces = node->getElementsByTagName(XStr("interface").x()); DOMNodeList* ifaces = node->getElementsByTagName(XStr("interface").x());
map< pair<string, string>, pair<string, string> > fixedInterfaces;
allUnique = true; allUnique = true;
for (int i = 0; i < ifaces->getLength(); i++) for (int i = 0; i < ifaces->getLength(); i++)
{ {
...@@ -145,32 +132,42 @@ int rspec_parser::readInterfacesOnNode (const DOMElement* node, bool& allUnique) ...@@ -145,32 +132,42 @@ int rspec_parser::readInterfacesOnNode (const DOMElement* node, bool& allUnique)
{ {
nodeId = this->readVirtualId (node, hasAttr); nodeId = this->readVirtualId (node, hasAttr);
ifaceId = XStr(iface->getAttribute(XStr("client_id").x())).c(); ifaceId = XStr(iface->getAttribute(XStr("client_id").x())).c();
if (iface->hasAttribute(XStr("component_id").x()))
{
bool hasComponentId;
string componentNodeId =
this->readPhysicalId (node, hasComponentId);
string componentIfaceId =
this->getAttribute(iface, "component_id");
fixedInterfaces.insert
(make_pair
(make_pair(nodeId,ifaceId),
make_pair(componentNodeId,componentIfaceId)));
}
} }
allUnique &= ((this->ifacesSeen).insert allUnique &= ((this->ifacesSeen).insert
(pair<string, string>(nodeId, ifaceId))).second; (pair<string, string>(nodeId, ifaceId))).second;
} }
return (ifaces->getLength()); return (fixedInterfaces);
} }
// Returns a link_characteristics element // Returns a link_characteristics element
struct link_characteristics rspec_parser :: readLinkCharacteristics struct link_characteristics rspec_parser :: readLinkCharacteristics
(const DOMElement* link, (const DOMElement* link,
int defaultBandwidth, int& count,
int unlimitedBandwidth, int defaultBandwidth,
int& count) int unlimitedBandwidth)
{ {
bool hasBandwidth, hasLatency, hasPacketLoss; bool hasBandwidth, hasLatency, hasPacketLoss;
string strBw = this->getAttribute(link, "bandwidth", hasBandwidth); string strBw = this->readChild(link, "bandwidth", hasBandwidth);
string strLat = this->getAttribute(link, "latency", hasLatency); string strLat = this->readChild(link, "latency", hasLatency);
string strLoss = this->getAttribute(link, "packet_loss", hasPacketLoss); string strLoss = this->readChild(link, "packet_loss", hasPacketLoss);
int bandwidth = 0, latency = 0; int bandwidth = 0, latency = 0;
float packetLoss = 0.0; float packetLoss = 0.0;
if (!hasBandwidth) if (!hasBandwidth)
bandwidth = defaultBandwidth; bandwidth = defaultBandwidth;
else if(strBw == "unlimited") else if(strBw == "unlimited")
// This is the bandwidth used to simulate an unlimited value
// We don't expect it to change, so it's constant here
bandwidth = unlimitedBandwidth; bandwidth = unlimitedBandwidth;
else else
bandwidth = atoi(strBw.c_str()); bandwidth = atoi(strBw.c_str());
...@@ -190,35 +187,43 @@ vector<struct link_interface> rspec_parser :: readLinkInterface ...@@ -190,35 +187,43 @@ vector<struct link_interface> rspec_parser :: readLinkInterface
ifaceCount = ifaceRefs->getLength(); ifaceCount = ifaceRefs->getLength();
if (ifaceCount != 2) { if (ifaceCount != 2) {
ifaceCount = -1; ifaceCount = RSPEC_ERROR_BAD_IFACE_COUNT;
return vector<link_interface>(); return vector<struct link_interface>();
} }
struct link_interface srcIface struct link_interface srcIface
= this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(0))); = this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(0)));
struct link_interface dstIface struct link_interface dstIface
= this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(1))); = this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(1)));
pair<string, string> srcNodeIface; pair<string, string> srcNodeIface;
pair<string, string> dstNodeIface; pair<string, string> dstNodeIface;
if (this->rspecType == RSPEC_TYPE_ADVT) if (this->rspecType == RSPEC_TYPE_ADVT)
{ {
srcNodeIface = make_pair(srcIface.physicalNodeId, srcIface.physicalIfaceId); srcNodeIface
dstNodeIface = make_pair(dstIface.physicalNodeId, dstIface.physicalIfaceId); = make_pair(srcIface.physicalNodeId, srcIface.physicalIfaceId);
dstNodeIface
= make_pair(dstIface.physicalNodeId, dstIface.physicalIfaceId);
} }
else // (this->rspecType == RSPEC_TYPE_REQ) else // (this->rspecType == RSPEC_TYPE_REQ)
{ {
srcNodeIface = make_pair(srcIface.virtualNodeId, srcIface.virtualIfaceId); srcNodeIface
dstNodeIface = make_pair(dstIface.virtualNodeId, dstIface.virtualIfaceId); = make_pair(srcIface.virtualNodeId, srcIface.virtualIfaceId);
dstNodeIface
= make_pair(dstIface.virtualNodeId, dstIface.virtualIfaceId);
} }
vector<struct link_interface> rv; vector<struct link_interface> rv;
// Check if the node-interface pair has been seen before. // Check if the node-interface pair has been seen before.
// If it hasn't, it is an error // If it hasn't, it is an error
if ((this->ifacesSeen).find(srcNodeIface) == (this->ifacesSeen).end() if ((this->ifacesSeen).find(srcNodeIface) == (this->ifacesSeen).end())
|| (this->ifacesSeen).find(dstNodeIface) == (this->ifacesSeen).end()) {
ifaceCount = RSPEC_ERROR_UNSEEN_NODEIFACE_SRC;
return rv;
}
if ((this->ifacesSeen).find(dstNodeIface) == (this->ifacesSeen).end())
{ {
ifaceCount = -1; ifaceCount = RSPEC_ERROR_UNSEEN_NODEIFACE_DST;
return rv; return rv;
} }
...@@ -227,4 +232,44 @@ vector<struct link_interface> rspec_parser :: readLinkInterface ...@@ -227,4 +232,44 @@ vector<struct link_interface> rspec_parser :: readLinkInterface
return rv; return rv;
} }
vector<struct link_type> rspec_parser::readLinkTypes (const DOMElement* link,
int& typeCount)
{
DOMNodeList* linkTypes = link->getElementsByTagName(XStr("link_type").x());
vector<struct link_type> types;
for (int i = 0; i < linkTypes->getLength(); i++)
{
DOMElement *tag = dynamic_cast<DOMElement*>(linkTypes->item(i));
string name = XStr(tag->getAttribute(XStr("name").x())).c();
string typeName = XStr(tag->getAttribute(XStr("type_name").x())).c();
struct link_type type = {name, typeName};
types.push_back(type);
}
typeCount = linkTypes->getLength();
return types;
}
void rspec_parser :: dummyFun ()
{
}
string rspec_parser :: readSubnodeOf (const DOMElement* tag, bool& isSubnode)
{
return (this->readChild(tag, "subnode_of", isSubnode));
}
string rspec_parser :: readExclusive (const DOMElement* tag, bool& isExclusive)
{
return (this->readChild(tag, "exclusive", isExclusive));
}
string rspec_parser :: readAvailable (const DOMElement* tag, bool& isAvailable)
{
return (this->readChild(tag, "available", isAvailable));
}
#endif #endif
...@@ -20,10 +20,16 @@ ...@@ -20,10 +20,16 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <xercesc/dom/DOM.hpp> #include <xercesc/dom/DOM.hpp>
#include "rspec_parser_helper.h"
#include "emulab_extensions_parser.h"
#define RSPEC_TYPE_ADVT 0 #define RSPEC_TYPE_ADVT 0
#define RSPEC_TYPE_REQ 1 #define RSPEC_TYPE_REQ 1
#define RSPEC_ERROR_BAD_IFACE_COUNT -1
#define RSPEC_ERROR_UNSEEN_NODEIFACE_SRC -2
#define RSPEC_ERROR_UNSEEN_NODEIFACE_DST -3
struct node_type struct node_type
{ {
std::string typeName; std::string typeName;
...@@ -31,6 +37,12 @@ struct node_type ...@@ -31,6 +37,12 @@ struct node_type
bool isStatic; bool isStatic;
}; };
struct link_type
{
std::string name;
std::string typeName;
};
struct link_characteristics struct link_characteristics
{ {
int bandwidth; int bandwidth;
...@@ -52,54 +64,79 @@ struct node_interface ...@@ -52,54 +64,79 @@ struct node_interface
std::string clientId; std::string clientId;
}; };
class rspec_parser class rspec_parser : public rspec_parser_helper
{ {
private: private:
// std::string getAttribute (const xercesc::DOMElement*,
// const std::string,
// bool&);
// std::string getAttribute(const xercesc::DOMElement*, const std::string);
// bool hasAttribute (const xercesc::DOMElement*, const std::string);
// std::string readChild (const xercesc::DOMElement*, const char*, bool&);
protected: protected:
// Extensions parser object
emulab_extensions_parser* emulabExtensions;
int rspecType; int rspecType;
std::set< std::pair<std::string, std::string> >ifacesSeen; std::set< std::pair<std::string, std::string> >ifacesSeen;
std::string getAttribute (const xercesc::DOMElement*, const std::string,
bool&);
bool hasAttribute (const xercesc::DOMElement*, const std::string);
struct link_interface getIface (const xercesc::DOMElement*); struct link_interface getIface (const xercesc::DOMElement*);
public: public:
// Constructors and destructors
rspec_parser () { } rspec_parser(int type) {
rspec_parser(int type) { this->rspecType = type; } this->emulabExtensions = new emulab_extensions_parser(type);
this->rspecType = type;
}
~rspec_parser() {
free (this->emulabExtensions);
}
// Common functions // Common functions
virtual std::string readPhysicalId (const xercesc::DOMElement*, bool&); virtual std::string readPhysicalId (const xercesc::DOMElement*, bool&);
virtual std::string readVirtualId (const xercesc::DOMElement*, bool&); virtual std::string readVirtualId (const xercesc::DOMElement*, bool&);
virtual std::string readComponentManagerId (const xercesc::DOMElement*, virtual std::string readComponentManagerId (const xercesc::DOMElement*,
bool&); bool&);
virtual std::string readVirtualizationType (const xercesc::DOMElement*,
bool&);
// Functions for nodes
virtual std::vector<std::string>
readLocation(const xercesc::DOMElement*, int&);
virtual std::vector<struct node_type>
readNodeTypes (const xercesc::DOMElement*,
int&, int unlimitedSlots=1000);
// Reads subnode tag // Reads subnode tag, if present
virtual std::string readSubnodeOf (const xercesc::DOMElement*, bool&); virtual std::string readSubnodeOf (const xercesc::DOMElement*, bool&);
// Functions for nodes // Reads the exclusive tag if present
virtual std::vector<std::string> readLocation(const xercesc::DOMElement*, virtual std::string readExclusive (const xercesc::DOMElement*, bool&);
int&);
virtual std::list<struct node_type> // Reads the available tag, if present
readNodeTypes (const xercesc::DOMElement*, int&); virtual std::string readAvailable (const xercesc::DOMElement*, bool&);
// Functions for links // Functions for links
virtual struct link_characteristics virtual struct link_characteristics
readLinkCharacteristics (const xercesc::DOMElement*, readLinkCharacteristics (const xercesc::DOMElement*,
int defaultBandwidth, int&,
int unlimitedBandwidth, int defaultBandwidth = -1,
int&); int unlimitedBandwidth = -1);
// Reads the interfaces on a link
virtual std::vector< struct link_interface > virtual std::vector< struct link_interface >
readLinkInterface (const xercesc::DOMElement*, int&); readLinkInterface (const xercesc::DOMElement*, int&);
// Reads the link types
virtual std::vector< struct link_type >
readLinkTypes (const xercesc::DOMElement*, int&);
// Reads all the interfaces on a node // Reads all the interfaces on a node
// Returns the number of interfaces found. // Returns the number of interfaces found.
// This only populates the internal data structures of the object. // This only populates the internal data structures of the object.
// Ideally, this ought to be done automatically, but in the current setup, // Ideally, this ought to be done automatically,
// there doesn't seem to be a clean way of making it happen. // but there doesn't seem to be a clean way of making it happen.
virtual int readInterfacesOnNode (const xercesc::DOMElement*, bool&); virtual std::map< std::pair<std::string, std::string>,
std::pair<std::string, std::string> >
readInterfacesOnNode (const xercesc::DOMElement*, bool&);
virtual void dummyFun(); virtual void dummyFun();
}; };
......
...@@ -76,7 +76,7 @@ vector<struct link_interface> rspec_parser_v1::readLinkInterface ...@@ -76,7 +76,7 @@ vector<struct link_interface> rspec_parser_v1::readLinkInterface
ifaceCount = ifaceRefs->getLength(); ifaceCount = ifaceRefs->getLength();
if (ifaceCount != 2) { if (ifaceCount != 2) {
ifaceCount = -1; ifaceCount = RSPEC_ERROR_BAD_IFACE_COUNT;
return vector<link_interface>(); return vector<link_interface>();
} }
...@@ -85,10 +85,10 @@ vector<struct link_interface> rspec_parser_v1::readLinkInterface ...@@ -85,10 +85,10 @@ vector<struct link_interface> rspec_parser_v1::readLinkInterface
struct link_interface dstIface struct link_interface dstIface
= this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(1))); = this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(1)));
cerr << "(" << srcIface.physicalNodeId << "," // cerr << "(" << srcIface.physicalNodeId << ","
<< srcIface.physicalIfaceId << ")" << endl; // << srcIface.physicalIfaceId << ")" << endl;
cerr << "(" << dstIface.physicalNodeId << "," // cerr << "(" << dstIface.physicalNodeId << ","
<< dstIface.physicalIfaceId << ")" << endl; // << dstIface.physicalIfaceId << ")" << endl;
pair<string, string> srcNodeIface; pair<string, string> srcNodeIface;
pair<string, string> dstNodeIface; pair<string, string> dstNodeIface;
...@@ -108,20 +108,16 @@ vector<struct link_interface> rspec_parser_v1::readLinkInterface ...