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 @@
#ifdef NEW_GCC
#include <ext/hash_map>
#include <ext/hash_fun.h>
using namespace __gnu_cxx;
#define RANDOM() random()
#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 @@
#include <iostream>
#include <map>
#include <cstring>
using namespace std;
#ifdef NEW_GCC
#include <ext/hash_fun.h>
//#include <hash_fun.h>
using namespace __gnu_cxx;
#else
#include <stl_hash_fun.h>
......
This diff is collapsed.
This diff is collapsed.
......@@ -18,31 +18,6 @@
#include "xstr.h"
#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)
{
bool exists;
......@@ -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
string rspec_parser :: readPhysicalId (const DOMElement* tag,
bool& hasComponentId)
bool& hasComponentId)
{
return (this->getAttribute(tag, "component_id", hasComponentId));
}
......@@ -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
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,
// Returns true if the latitude and longitude tags are present
// Absence of the country tag will be caught by the schema validator
vector<string> rspec_parser :: readLocation (const DOMElement* tag,
int& rvLength)
int& rvLength)
{
bool hasCountry, hasLatitude, hasLongitude;
......@@ -100,11 +82,12 @@ vector<string> rspec_parser :: readLocation (const DOMElement* tag,
// Returns a list of node_type elements
// The out parameter contains the number of elements found
list<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node,
int& typeCount)
vector<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node,
int& typeCount,
int unlimitedSlots)
{
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++)
{
DOMElement *tag = dynamic_cast<DOMElement*>(nodeTypes->item(i));
......@@ -113,8 +96,8 @@ list<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node,
int typeSlots;
string slot = XStr(tag->getAttribute(XStr("type_slots").x())).c();
if (slot.compare("unlimited") == 0)
typeSlots = 1000;
if (slot == "unlimited")
typeSlots = unlimitedSlots;
else
typeSlots = atoi(slot.c_str());
......@@ -126,9 +109,13 @@ list<struct node_type> rspec_parser::readNodeTypes (const DOMElement* node,
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());
map< pair<string, string>, pair<string, string> > fixedInterfaces;
allUnique = true;
for (int i = 0; i < ifaces->getLength(); i++)
{
......@@ -145,32 +132,42 @@ int rspec_parser::readInterfacesOnNode (const DOMElement* node, bool& allUnique)
{
nodeId = this->readVirtualId (node, hasAttr);
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
(pair<string, string>(nodeId, ifaceId))).second;
(pair<string, string>(nodeId, ifaceId))).second;
}
return (ifaces->getLength());
return (fixedInterfaces);
}
// Returns a link_characteristics element
struct link_characteristics rspec_parser :: readLinkCharacteristics
(const DOMElement* link,
int defaultBandwidth,
int unlimitedBandwidth,
int& count)
(const DOMElement* link,
int& count,
int defaultBandwidth,
int unlimitedBandwidth)
{
bool hasBandwidth, hasLatency, hasPacketLoss;
string strBw = this->getAttribute(link, "bandwidth", hasBandwidth);
string strLat = this->getAttribute(link, "latency", hasLatency);
string strLoss = this->getAttribute(link, "packet_loss", hasPacketLoss);
string strBw = this->readChild(link, "bandwidth", hasBandwidth);
string strLat = this->readChild(link, "latency", hasLatency);
string strLoss = this->readChild(link, "packet_loss", hasPacketLoss);
int bandwidth = 0, latency = 0;
float packetLoss = 0.0;
if (!hasBandwidth)
bandwidth = defaultBandwidth;
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;
else
bandwidth = atoi(strBw.c_str());
......@@ -190,35 +187,43 @@ vector<struct link_interface> rspec_parser :: readLinkInterface
ifaceCount = ifaceRefs->getLength();
if (ifaceCount != 2) {
ifaceCount = -1;
return vector<link_interface>();
ifaceCount = RSPEC_ERROR_BAD_IFACE_COUNT;
return vector<struct link_interface>();
}
struct link_interface srcIface
= this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(0)));
= this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(0)));
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> dstNodeIface;
if (this->rspecType == RSPEC_TYPE_ADVT)
{
srcNodeIface = make_pair(srcIface.physicalNodeId, srcIface.physicalIfaceId);
dstNodeIface = make_pair(dstIface.physicalNodeId, dstIface.physicalIfaceId);
srcNodeIface
= make_pair(srcIface.physicalNodeId, srcIface.physicalIfaceId);
dstNodeIface
= make_pair(dstIface.physicalNodeId, dstIface.physicalIfaceId);
}
else // (this->rspecType == RSPEC_TYPE_REQ)
{
srcNodeIface = make_pair(srcIface.virtualNodeId, srcIface.virtualIfaceId);
dstNodeIface = make_pair(dstIface.virtualNodeId, dstIface.virtualIfaceId);
srcNodeIface
= make_pair(srcIface.virtualNodeId, srcIface.virtualIfaceId);
dstNodeIface
= make_pair(dstIface.virtualNodeId, dstIface.virtualIfaceId);
}
vector<struct link_interface> rv;
// Check if the node-interface pair has been seen before.
// If it hasn't, it is an error
if ((this->ifacesSeen).find(srcNodeIface) == (this->ifacesSeen).end()
|| (this->ifacesSeen).find(dstNodeIface) == (this->ifacesSeen).end())
if ((this->ifacesSeen).find(srcNodeIface) == (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;
}
......@@ -227,4 +232,44 @@ vector<struct link_interface> rspec_parser :: readLinkInterface
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
......@@ -20,10 +20,16 @@
#include <utility>
#include <vector>
#include <xercesc/dom/DOM.hpp>
#include "rspec_parser_helper.h"
#include "emulab_extensions_parser.h"
#define RSPEC_TYPE_ADVT 0
#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
{
std::string typeName;
......@@ -31,6 +37,12 @@ struct node_type
bool isStatic;
};
struct link_type
{
std::string name;
std::string typeName;
};
struct link_characteristics
{
int bandwidth;
......@@ -52,54 +64,79 @@ struct node_interface
std::string clientId;
};
class rspec_parser
class rspec_parser : public rspec_parser_helper
{
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:
// Extensions parser object
emulab_extensions_parser* emulabExtensions;
int rspecType;
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*);
public:
rspec_parser () { }
rspec_parser(int type) { this->rspecType = type; }
// Constructors and destructors
rspec_parser(int type) {
this->emulabExtensions = new emulab_extensions_parser(type);
this->rspecType = type;
}
~rspec_parser() {
free (this->emulabExtensions);
}
// Common functions
virtual std::string readPhysicalId (const xercesc::DOMElement*, bool&);
virtual std::string readVirtualId (const xercesc::DOMElement*, bool&);
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&);
// Functions for nodes
virtual std::vector<std::string> readLocation(const xercesc::DOMElement*,
int&);
virtual std::list<struct node_type>
readNodeTypes (const xercesc::DOMElement*, int&);
// Reads the exclusive tag if present
virtual std::string readExclusive (const xercesc::DOMElement*, bool&);
// Reads the available tag, if present
virtual std::string readAvailable (const xercesc::DOMElement*, bool&);
// Functions for links
virtual struct link_characteristics
readLinkCharacteristics (const xercesc::DOMElement*,
int defaultBandwidth,
int unlimitedBandwidth,
int&);
int&,
int defaultBandwidth = -1,
int unlimitedBandwidth = -1);
// Reads the interfaces on a link
virtual std::vector< struct link_interface >
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
// Returns the number of interfaces found.
// This only populates the internal data structures of the object.
// Ideally, this ought to be done automatically, but in the current setup,
// there doesn't seem to be a clean way of making it happen.
virtual int readInterfacesOnNode (const xercesc::DOMElement*, bool&);
// Ideally, this ought to be done automatically,
// but there doesn't seem to be a clean way of making it happen.
virtual std::map< std::pair<std::string, std::string>,
std::pair<std::string, std::string> >
readInterfacesOnNode (const xercesc::DOMElement*, bool&);
virtual void dummyFun();
};
......
......@@ -76,7 +76,7 @@ vector<struct link_interface> rspec_parser_v1::readLinkInterface
ifaceCount = ifaceRefs->getLength();
if (ifaceCount != 2) {
ifaceCount = -1;
ifaceCount = RSPEC_ERROR_BAD_IFACE_COUNT;
return vector<link_interface>();
}
......@@ -85,10 +85,10 @@ vector<struct link_interface> rspec_parser_v1::readLinkInterface
struct link_interface dstIface
= this->getIface(dynamic_cast<DOMElement*>(ifaceRefs->item(1)));
cerr << "(" << srcIface.physicalNodeId << ","
<< srcIface.physicalIfaceId << ")" << endl;
cerr << "(" << dstIface.physicalNodeId << ","
<< dstIface.physicalIfaceId << ")" << endl;
// cerr << "(" << srcIface.physicalNodeId << ","
// << srcIface.physicalIfaceId << ")" << endl;
// cerr << "(" << dstIface.physicalNodeId << ","
// << dstIface.physicalIfaceId << ")" << endl;
pair<string, string> srcNodeIface;
pair<string, string> dstNodeIface;
......@@ -108,20 +108,16 @@ vector<struct link_interface> rspec_parser_v1::readLinkInterface
// If it hasn't, it is an error
if ((this->ifacesSeen).find(srcNodeIface) == ifacesSeen.end())
{
// cout << "Could not find src (" << srcIface.physicalNodeId << ","
// << srcIface.physicalIfaceId << ")" << endl;
cout << "Could not find " << srcNodeIface.first
<< " " << srcNodeIface.second << endl;
ifaceCount = -1;
ifaceCount = RSPEC_ERROR_UNSEEN_NODEIFACE_SRC;
return rv;
}
if ((this->ifacesSeen).find(dstNodeIface) == ifacesSeen.end())
{
// cout << "Could not find dst (" << dstIface.physicalNodeId << ","
// << dstIface.physicalIfaceId << ")" << endl;
cout << "Could not find " << dstNodeIface.first
<< " " << dstNodeIface.second << endl;
ifaceCount = -1;
ifaceCount = RSPEC_ERROR_UNSEEN_NODEIFACE_DST;
return rv;
}
......@@ -143,11 +139,13 @@ struct link_interface rspec_parser_v1::getIface (const DOMElement* tag)
return rv;
}
int rspec_parser_v1::readInterfacesOnNode (const DOMElement* node,
bool& allUnique)
map< pair<string, string>, pair<string, string> >
rspec_parser_v1::readInterfacesOnNode (const DOMElement* node,
bool& allUnique)
{
bool exists;
DOMNodeList* ifaces = node->getElementsByTagName(XStr("interface").x());
map< pair<string, string>, pair<string, string> > fixedInterfaces;
allUnique = true;
for (int i = 0; i < ifaces->getLength(); i++)
{
......@@ -164,12 +162,21 @@ int rspec_parser_v1::readInterfacesOnNode (const DOMElement* node,
{
nodeId = this->readVirtualId (node, hasAttr);
ifaceId = XStr(iface->getAttribute(XStr("virtual_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)));
}
}
cout << "(" << nodeId << "," << ifaceId << ")" << endl;
//cout << "(" << nodeId << "," << ifaceId << ")" << endl;
allUnique &= ((this->ifacesSeen).insert
(pair<string, string>(nodeId, ifaceId))).second;
}
return (ifaces->getLength());
return fixedInterfaces;
}
void rspec_parser_v1 :: dummyFun ()
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2008 University of Utah and the Flux Group.
* Copyright (c) 2010 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -35,13 +35,15 @@ class rspec_parser_v1 : public rspec_parser
public:
rspec_parser_v1 (int type) { this->rspecType = type; }
rspec_parser_v1 (int type) : rspec_parser(type) { ; }
std::string readPhysicalId (const xercesc::DOMElement*, bool&);
std::string readVirtualId (const xercesc::DOMElement*, bool&);
std::string readComponentManagerId (const xercesc::DOMElement*, bool&);
int readInterfacesOnNode (const xercesc::DOMElement* node, bool& allUnique);
std::map< std::pair<std::string, std::string>,
std::pair<std::string, std::string> >
readInterfacesOnNode (const xercesc::DOMElement*, bool&);
std::vector<struct link_interface> readLinkInterface
(const xercesc::DOMElement* link, int& ifaceCount);
struct link_interface getIface (const xercesc::DOMElement*);
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2010 University of Utah and the Flux Group.
* All rights reserved.
*/
/*
* XML parser for RSPEC version 2.0
*/
#ifdef WITH_XML
#include "rspec_parser_v2.h"
#include "rspec_parser.h"
#include <string>
#include <vector>
#include <xercesc/dom/DOM.hpp>
#include "xstr.h"
XERCES_CPP_NAMESPACE_USE
using namespace std;
vector<struct link_interface> rspec_parser_v2::readLinkInterface
(const DOMElement* link,
int& ifaceCount)
{
DOMNodeList* properties = link->getElementsByTagName(XStr("property").x());
ifaceCount = properties->getLength();
if (ifaceCount == 0) {
ifaceCount = RSPEC_ERROR_BAD_IFACE_COUNT;
return vector<struct link_interface>();
}
vector<struct link_interface> rv;
for (int i = 0; i < ifaceCount; i++)
{
DOMElement* property = dynamic_cast<DOMElement*>(properties->item(i));
string sourceId = this->getAttribute(property, "source_id");
string destId = this->getAttribute(property, "dest_id");
struct link_interface srcIface, dstIface;
if (this->rspecType == RSPEC_TYPE_ADVT)
{
srcIface.physicalNodeId = sourceId;
dstIface.physicalNodeId = destId;
}
else // if (this->rspecType == RSPEC_TYPE_REQ)
{
srcIface.virtualNodeId = sourceId;
dstIface.virtualNodeId = destId;
}
// Check if the node has been seen before. If not, it is an error
if ((this->nodesSeen).find(sourceId) == (this->nodesSeen).end()) {
ifaceCount = RSPEC_ERROR_UNSEEN_NODEIFACE_SRC;
return vector<struct link_interface>();
}
if ((this->nodesSeen).find(sourceId) == (this->nodesSeen).end()) {
ifaceCount = RSPEC_ERROR_UNSEEN_NODEIFACE_DST;
return vector<struct link_interface>();
}
rv.push_back(srcIface);
rv.push_back(dstIface);
}
return rv;
}
/* ************* WARNING. Need clarification ***************/
// XXX: 0 or more link properties are allowed.
// I am returning only the first one if this is the case.
// Perhaps we should return an error instead. This needs to be sorted out
// Returns a link_characteristics element
struct link_characteristics rspec_parser_v2 :: readLinkCharacteristics
(const DOMElement* link,
int& count,
int defaultBandwidth,