Commit aba499b3 authored by Tarun Prabhu's avatar Tarun Prabhu

Contains a number of changes for handling v1 and v2 of rspecs. V2 is known

to be buggy and support for extensions needs to tested and in some cases,
there's more stuff that needs to go in as extensions.
parent 70796e9e
......@@ -187,9 +187,10 @@ void read_physical_topology(char *filename) {
#ifdef WITH_XML
if (ptop_xml_input) {
cout << "Physical Graph: " << parse_ptop_xml(PG,SG,filename) << endl;
} else if (ptop_rspec_input) {
cout << "Physical Graph: " << parse_ptop_rspec (PG, SG, filename) << endl;
cout << "Physical Graph: " << parse_ptop_xml(PG,SG,filename) << endl;
}
else if (ptop_rspec_input) {
cout << "Physical Graph: " << parse_advertisement(PG, SG, filename) << endl;
}
else {
cout << "Physical Graph: " << parse_ptop(PG,SG,ptopfile) << endl;
......@@ -310,7 +311,7 @@ void read_virtual_topology(char *filename) {
cout << "Virtual Graph: " << parse_vtop_xml(VG,filename) << endl;
}
else if (vtop_rspec_input){
cout << "Virtual Graph: " << parse_vtop_rspec (VG, filename) << endl ;
cout << "Virtual Graph: " << parse_request (VG, filename) << endl;
}
else {
cout << "Virtual Graph: " << parse_top(VG,topfile) << endl;
......
......@@ -15,10 +15,126 @@
XERCES_CPP_NAMESPACE_USE
using namespace std;
using namespace rspec_emulab_extension;
emulab_operator emulab_extensions_parser::readOperator(DOMElement* tag)
{
struct emulab_operator op = { "", NORMAL_OPERATOR };
if (this->hasAttribute(tag, "global_operator")) {
op.op = this->getAttribute(tag, "global_operator");
op.type = GLOBAL_OPERATOR;
}
else if (this->hasAttribute(tag, "local_operator")) {
op.op = this->getAttribute(tag, "local_operator");
op.type = LOCAL_OPERATOR;
}
return op;
}
vector<struct fd> emulab_extensions_parser::readAllFeaturesDesires
(DOMElement* elem)
{
DOMNodeList* fdNodes = elem->getElementsByTagName(XStr("fd").x());
vector<struct fd> fds;
for (int i = 0; i < fdNodes->getLength(); i++) {
fds.push_back(this->readFeatureDesire
(dynamic_cast<DOMElement*>(fdNodes->item(i))));
}
return fds;
}
struct fd emulab_extensions_parser::readFeatureDesire (DOMElement* tag)
{
struct fd fdObject = {
this->getAttribute(tag, "fd_name"),
rspec_parser_helper::stringToNum
(this->getAttribute(tag, "fd_weight")),
this->hasAttribute(tag, "violatable"),
this->readOperator(tag)
};
return fdObject;
}
vector<struct property> emulab_extensions_parser::readAllProperties
(DOMElement* elem)
{
DOMNodeList* propNodes = elem->getElementsByTagName(XStr("property").x());
vector<struct property> properties;
for (int i = 0; i < propNodes->getLength(); i++) {
properties.push_back(this->readProperty
(dynamic_cast<DOMElement*>(propNodes->item(i))));
}
return properties;
}
struct property emulab_extensions_parser::readProperty (DOMElement* tag)
{
struct property propertyObject = {
this->getAttribute(tag, "property_name"),
this->getAttribute(tag, "property_value"),
rspec_parser_helper::stringToNum
(this->getAttribute(tag, "property_penalty")),
this->hasAttribute(tag, "violatable"),
this->readOperator(tag)
};
return propertyObject;
}
struct hardness emulab_extensions_parser::readHardness (DOMElement* tag)
{
struct hardness hardnessObject;
if (this->hasChild(tag, "hard")) {
// XXX: This is a temporary fix. We will need to deal with hard
// vclasses correctly at some point
hardnessObject.type = HARD_VCLASS;
}
else /* (this->hasChildTag(tag, "soft")) */ {
hardnessObject.weight
= rspec_parser_helper::stringToNum (this->readChild(tag, "weight"));
hardnessObject.type = SOFT_VCLASS;
}
return hardnessObject;
}
vector<struct vclass> emulab_extensions_parser::readAllVClasses
(DOMElement* elem)
{
DOMNodeList* vclassNodes =
elem->getElementsByTagName(XStr("vtop_vclass").x());
vector<struct vclass> vclasses;
for (int i = 0; i < vclassNodes->getLength(); i++) {
vclasses.push_back(this->readVClass
(dynamic_cast<DOMElement*>(vclassNodes->item(i))));
}
return vclasses;
}
struct vclass emulab_extensions_parser::readVClass (DOMElement* tag)
{
struct vclass vclassObject = {
this->getAttribute(tag, "name"),
this->readHardness(tag),
this->readChild(tag, "physical_type")
};
return vclassObject;
}
string emulab_extensions_parser::readTypeSlots (DOMElement* tag)
{
DOMElement* typeSlotsNode
= dynamic_cast<DOMElement*>
((tag->getElementsByTagName(XStr("emulab:ext_node_type").x()))
->item(0));
return (this->getAttribute(typeSlotsNode, "type_slots"));
}
bool emulab_extensions_parser::readStaticType (DOMElement* tag)
{
DOMElement* typeSlotsNode
= dynamic_cast<DOMElement*>
((tag->getElementsByTagName(XStr("emulab:ext_node_type").x()))
->item(0));
return (typeSlotsNode->hasAttribute(XStr("static").x()));
}
#endif // WITH_XML
......@@ -10,81 +10,96 @@
#ifdef WITH_XML
#include <string>
#include <vector>
#include <xercesc/dom/DOM.hpp>
#include "rspec_parser_helper.h"
#define LOCAL_OPERATOR 0
#define GLOBAL_OPERATOR 1
namespace rspec_emulab_extension {
#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:
#define LOCAL_OPERATOR 0
#define GLOBAL_OPERATOR 1
#define NORMAL_OPERATOR 2
#define HARD_VCLASS 0
#define SOFT_VCLASS 1
struct emulab_operator {
std::string op;
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);
};
};
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 type;
std::string physicalType;
};
struct property {
std::string name;
std::string value;
float penalty;
bool violatable;
struct emulab_operator op;
};
class emulab_extensions_parser : public rspec_parser_helper {
private:
int type;
struct emulab_operator readOperator(xercesc::DOMElement* tag);
struct hardness readHardness (xercesc::DOMElement* tag);
public:
// Constructor
emulab_extensions_parser(int type) { this->type = type; }
// Functions
std::vector<struct fd> readAllFeaturesDesires
(xercesc::DOMElement* ele);
struct fd readFeatureDesire (xercesc::DOMElement* tag);
struct node_flags readNodeFlag (xercesc::DOMElement* tag);
struct link_flags readLinkFlag (xercesc::DOMElement* tag);
std::vector<struct property> readAllProperties
(xercesc::DOMElement* elem);
struct property readProperty (xercesc::DOMElement* tag);
std::vector<struct vclass> readAllVClasses (xercesc::DOMElement*);
struct vclass readVClass (xercesc::DOMElement* tag);
std::string readAssignedTo (xercesc::DOMElement* tag);
std::string readHintTo (xercesc::DOMElement* tag);
std::string readTypeSlots (xercesc::DOMElement* tag);
bool readStaticType (xercesc::DOMElement* tag);
};
} // namespace rspec_emulab_extension
#endif // WITH_XML
......
......@@ -15,7 +15,9 @@ static const char rcsid[] = "$Id: parse_advertisement_rspec.cc,v 1.7 2009-10-21
#include "parse_advertisement_rspec.h"
#include "xmlhelpers.h"
#include "parse_error_handler.h"
#include "rspec_parser_helper.h"
#include "rspec_parser_v1.h"
#include "rspec_parser_v2.h"
#include <fstream>
#include <map>
......@@ -54,7 +56,8 @@ extern name_vclass_map vclass_map;
// This is a hash map of the entire physical topology
// because it takes far too long for it to search the XML DOM tree.
map<string, DOMElement*>* advertisement_elements = new map<string, DOMElement*>();
map<string, DOMElement*>* advertisement_elements
= new map<string, DOMElement*>();
DOMElement* advt_root = NULL;
/*
......@@ -70,16 +73,12 @@ static rspec_parser* rspecParser;
* These are not meant to be used outside of this file, so they are only
* declared in here
*/
bool populate_nodes_rspec(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
static bool populate_nodes(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
set<string> &unavailable);
bool populate_links_rspec(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
static bool populate_links(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
set<string> &unavailable);
void populate_policies(DOMElement *root);
int parse_fds_xml (const DOMElement* tag, node_fd_set *fd_set);
int parse_ptop_rspec(tb_pgraph &pg, tb_sgraph &sg, char *filename) {
int parse_advertisement(tb_pgraph &pg, tb_sgraph &sg, char *filename) {
/*
* Fire up the XML parser
*/
......@@ -94,16 +93,7 @@ int parse_ptop_rspec(tb_pgraph &pg, tb_sgraph &sg, char *filename) {
domParser->setDoNamespaces(true);
domParser->setDoSchema(true);
domParser->setValidationSchemaFullChecking(true);
//TODO: Determine version number here
rspecParser = new rspec_parser_v1(RSPEC_TYPE_ADVT);
/*
* Must validate against the ptop schema
*/
/* domParser -> setExternalSchemaLocation
("http://www.protogeni.net/resources/rspec/0.1 " SCHEMA_LOCATION);*/
/*
* Just use a custom error handler - must admin it's not clear to me why
* we are supposed to use a SAX error handler for this, but this is what
......@@ -131,17 +121,33 @@ int parse_ptop_rspec(tb_pgraph &pg, tb_sgraph &sg, char *filename) {
* Get the root of the document - we're going to be using the same root
* for all subsequent calls
*/
DOMDocument *doc = domParser->getDocument();
DOMDocument* doc = domParser->getDocument();
advt_root = doc->getDocumentElement();
set<string> unavailable; // this should really be an unordered_set,
// but that's not very portable yet
int rspecVersion = rspec_parser_helper::getRspecVersion(advt_root);
switch (rspecVersion)
{
case 1:
rspecParser = new rspec_parser_v1(RSPEC_TYPE_ADVT);
break;
case 2:
rspecParser = new rspec_parser_v2(RSPEC_TYPE_ADVT);
break;
default:
cerr << "ERROR: Unsupported rspec ver. " << rspecVersion
<< " ... Aborting " << endl;
exit(EXIT_FATAL);
}
XMLDEBUG("Found rspec ver. " << rspecVersion << endl);
bool is_physical;
XStr type (advt_root->getAttribute(XStr("type").x()));
if (strcmp(type.c(), "advertisement") == 0)
is_physical = true;
else if (strcmp(type.c(), "request") == 0)
is_physical = false;
else if (strcmp(type.c(), "request") == 0)
is_physical = false;
// XXX: Not sure about datetimes, so they are strings for now
XStr generated (advt_root->getAttribute(XStr("generated").x()));
......@@ -152,25 +158,20 @@ int parse_ptop_rspec(tb_pgraph &pg, tb_sgraph &sg, char *filename) {
* structures
*/
XMLDEBUG("starting node population" << endl);
if (!populate_nodes_rspec(advt_root,pg,sg,unavailable)) {
if (!populate_nodes(advt_root,pg,sg,unavailable)) {
cerr << "Error reading nodes from physical topology "
<< filename << endl;
exit(EXIT_FATAL);
}
XMLDEBUG("finishing node population" << endl);
// cerr << "Dummy fun: ";
// rspecParser->dummyFun();
XMLDEBUG("starting link population" << endl);
if (!populate_links_rspec(advt_root,pg,sg,unavailable)) {
XMLDEBUG("starting link population" << endl);
if (!populate_links(advt_root,pg,sg,unavailable)) {
cerr << "Error reading links from physical topology "
<< filename << endl;
exit(EXIT_FATAL);
}
XMLDEBUG("finishing link population" << endl);
// TODO: We need to do something about these policies
//populate_policies(root);
cerr << "RSpec parsing finished" << endl;
}
......@@ -178,14 +179,14 @@ int parse_ptop_rspec(tb_pgraph &pg, tb_sgraph &sg, char *filename) {
* All done, clean up memory
*/
// XMLPlatformUtils::Terminate();
free(rspecParser);
free(rspecParser);
return 0;
}
/*
* Pull nodes from the document, and populate assign's own data structures
*/
bool populate_nodes_rspec(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
bool populate_nodes(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
set<string> &unavailable) {
bool is_ok = true;
pair<map<string, DOMElement*>::iterator, bool> insert_ret;
......@@ -381,7 +382,7 @@ bool populate_nodes_rspec(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
/*
* Pull the links from the ptop file, and populate assign's own data sturctures
*/
bool populate_links_rspec(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
bool populate_links(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
set<string> &unavailable) {
bool is_ok = true;
......
......@@ -26,7 +26,7 @@
#include <xercesc/sax/HandlerBase.hpp>
XERCES_CPP_NAMESPACE_USE
int parse_ptop_rspec(tb_pgraph &PG, tb_sgraph &SG, char *filename);
int parse_advertisement(tb_pgraph &PG, tb_sgraph &SG, char *filename);
#endif // for __PARSE_ADVERTISEMENT_RSPEC_H
......
......@@ -66,35 +66,20 @@ static rspec_parser* rspecParser;
* These are not meant to be used outside of this file,so they are only
* declared in here
*/
bool populate_nodes_rspec(DOMElement *root, tb_vgraph &vg,
static bool populate_nodes(DOMElement *root, tb_vgraph &vg,
map< pair<string, string>,
pair<string, string> >* fixed_interfaces);
bool populate_links_rspec(DOMElement *root, tb_vgraph &vg,
static bool populate_links(DOMElement *root, tb_vgraph &vg,
map< pair<string, string>,
pair<string, string> >* fixed_interfaces);
bool populate_vclasses_rspec (DOMElement *root, tb_vgraph &vg);
string generate_virtualNodeId (string virtual_id);
string generate_virtualIfaceId(string node_name, int interface_number);
DOMElement* appendChildTagWithData (DOMElement* parent,
const char*tag_name,
const char* tag_name,
const char* child_value);
string generate_virtualNodeId (string virtual_id);
string generate_virtualIfaceId(string node_name, int interface_number);
string numToString (int num);
string numToString (double num);
float stringToNum (string str);
int getRspecVersion (DOMElement* root);
bool hasComponentSpec (DOMElement* element);
void populate_policies(DOMElement *root);
int parse_fds_xml (const DOMElement* tag, node_fd_set *fd_set);
int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
int parse_request(tb_vgraph &vg, char *filename) {
/*
* Fire up the XML domParser
*/
......@@ -109,6 +94,7 @@ int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
domParser->setDoNamespaces(true);
domParser->setDoSchema(true);
domParser->setValidationSchemaFullChecking(true);
//domParser->setExternalSchemaLocation("http://www.protogeni.net/resources/rspec/2 http://www.protogeni.net/resources/rspec/2/request.xsd");
/*
* Just use a custom error handler - must admin it's not clear to me why
......@@ -146,7 +132,7 @@ int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
{
cerr << "Error: RSpec type must be \"request\"" << endl;
exit (EXIT_FATAL);
}
}
// NOTE: Not sure about datetimes. They are strings for now
XStr generated (request_root->getAttribute(XStr("generated").x()));
......@@ -154,9 +140,7 @@ int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
// Initialize the rspec parser with the correct object depending
// on the version of the rspec.
// getRspecVerson converts the v0.1 to v1.
int rspecVersion = getRspecVersion(request_root);
int rspecVersion = rspec_parser_helper::getRspecVersion(request_root);
switch (rspecVersion)
{
case 1:
......@@ -179,7 +163,7 @@ int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
* structures
*/
XMLDEBUG("starting node population" << endl);
if (!populate_nodes_rspec(request_root,vg, &fixed_interfaces)) {
if (!populate_nodes(request_root,vg, &fixed_interfaces)) {
cerr << "Error reading nodes from virtual topology "
<< filename << endl;
exit(EXIT_FATAL);
......@@ -187,7 +171,7 @@ int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
XMLDEBUG("finishing node population" << endl);
XMLDEBUG("starting link population" << endl);
if (!populate_links_rspec(request_root,vg, &fixed_interfaces)) {
if (!populate_links(request_root,vg, &fixed_interfaces)) {
cerr << "Error reading links from virtual topology "
<< filename << endl;
exit(EXIT_FATAL);
......@@ -208,7 +192,9 @@ int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
return 0;
}
bool populate_node(DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pair<string,string> >* fixed_interfaces)
bool populate_node(DOMElement* elt,
tb_vgraph &vg, map< pair<string,string>,
pair<string,string> >* fixed_interfaces)
{
bool hasVirtualId;
string virtualId = rspecParser->readVirtualId(elt, hasVirtualId);
......@@ -247,7 +233,7 @@ bool populate_node(DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pai
<< " were not unique." << endl;
return false;
}
fixed_interfaces->insert(fixedIfacesOnNode.begin(), fixedIfacesOnNode.end());
fixed_interfaces->insert(fixedIfacesOnNode.begin(),fixedIfacesOnNode.end());
/* Deal with the location tag */
cerr << "WARNING: Country information will be ignored" << endl;
......@@ -259,6 +245,7 @@ bool populate_node(DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pai
int typeCount;
vector<struct node_type> types = rspecParser->readNodeTypes(elt, typeCount);
cerr << " Here " << endl;
bool no_type = (typeCount == 0);
if (typeCount > 1) {
cerr << "ERROR: Too many node types (" << typeCount << ") on "
......@@ -272,6 +259,8 @@ bool populate_node(DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pai
bool isUnlimited = (typeSlots == 1000);
cerr << "Done parsing node types " << endl;
/*
* Make a tb_ptype structure for this guy - or just add this node to
* it if it already exists
......@@ -351,6 +340,8 @@ bool populate_node(DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pai
virtual_nodes.push_back(vv);
put(vvertex_pmap,vv,v);
// If a component manager has been specified, then the node must be
// managed by that CM. We implement this as a desire.
if (hasCMId)
{
tb_node_featuredesire node_fd (
......@@ -367,7 +358,7 @@ bool populate_node(DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pai
/*
* Pull nodes from the document, and populate assign's own data structures
*/
bool populate_nodes_rspec(DOMElement *root, tb_vgraph &vg, map< pair<string, string>, pair<string, string> >* fixed_interfaces) {
bool populate_nodes(DOMElement *root, tb_vgraph &vg, map< pair<string, string>, pair<string, string> >* fixed_interfaces) {
bool is_ok = true;
/*
* Get a list of all nodes in this document
......@@ -499,11 +490,11 @@ bool populate_link (DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pa
XStr(interface.virtualNodeId
+ string(":") + str_lan_id).x());
appendChildTagWithData(link, "bandwidth",
numToString(bandwidth).c_str());
rspecParser->numToString(bandwidth).c_str());
appendChildTagWithData(link, "latency",
numToString(latency).c_str());
rspecParser->numToString(latency).c_str());
appendChildTagWithData(link, "packet_loss",
numToString(packetLoss).c_str());
rspecParser->numToString(packetLoss).c_str());
DOMElement* src_interface_ref
= doc->createElement(XStr("interface_ref").x());
......@@ -667,7 +658,7 @@ bool populate_link (DOMElement* elt, tb_vgraph &vg, map< pair<string,string>, pa
/*
* Pull the links from the ptop file, and populate assign's own data sturctures
*/
bool populate_links_rspec(DOMElement *root, tb_vgraph &vg, map< pair<string, string>, pair<string, string> >* fixed_interfaces) {
bool populate_links(DOMElement *root, tb_vgraph &vg, map< pair<string, string>, pair<string, string> >* fixed_interfaces) {
bool is_ok = true;
......@@ -687,6 +678,16 @@ bool populate_links_rspec(DOMElement *root, tb_vgraph &vg, map< pair<string, str
return is_ok;
}
DOMElement* appendChildTagWithData (DOMElement* parent,
const char* tag_name,
const char* child_value)
{
DOMElement* child = doc->createElement(XStr(tag_name).x());
child->appendChild(doc->createTextNode(XStr(child_value).x()));
parent->appendChild(child);
return child;
}
string generate_virtualNodeId (string virtual_id)
{
std:ostringstream oss;
......@@ -697,14 +698,6 @@ string generate_virtualNodeId (string virtual_id)
return oss.str();
}
DOMElement* appendChildTagWithData (DOMElement* parent, const char*tag_name, const char* child_value)
{
DOMElement* child = doc->createElement(XStr(tag_name).x());
child->appendChild(doc->createTextNode(XStr(child_value).x()));
parent->appendChild(child);
return child;
}
string generate_virtualIfaceId (string lan_name, int interface_number)
{
std:ostringstream oss;
......@@ -712,39 +705,4 @@ string generate_virtualIfaceId (string lan_name, int interface_number)
return oss.str();
}
string numToString(int num)
{
std::ostringstream oss;
oss << num;
return oss.str();
}
string numToString(double num)
{
std::ostringstream oss;
oss << num;
return oss.str();
}
float stringToNum (string s)
{
float num;
std::istringstream iss(s);
iss >> num;
return num;
}
int getRspecVersion (DOMElement* root)
{
string schemaLocAttr =
string (XStr(root->getAttribute(XStr("xsi:schemaLocation").x())).c());
string schemaLocation = schemaLocAttr.substr(0,schemaLocAttr.find(' '));
float tmpRspecVersion
= stringToNum(schemaLocation.substr(schemaLocation.rfind('/')+1));
int rspecVersion = (int)tmpRspecVersion;
if (tmpRspecVersion < 1)
rspecVersion = 1;
return rspecVersion;
}
#endif
......@@ -24,9 +24,8 @@
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/sax/HandlerBase.hpp>
XERCES_CPP_NAMESPACE_USE
int parse_vtop_rspec(tb_vgraph &VG, char *filename);
int parse_request(tb_vgraph &VG, char *filename);
#endif // for __PARSE_REQUEST_RSPEC_H
......
......@@ -18,6 +18,19 @@
#include "xstr.h"
#include <xercesc/dom/DOM.hpp>
using namespace rspec_emulab_extension;
rspec_parser :: rspec_parser (int type)
{