From: Adam Dickmeiss Date: Thu, 5 Jan 2006 16:39:37 +0000 (+0000) Subject: RouterFleXML now stores routes and filters internally. X-Git-Tag: YP2.0.0.2~115 X-Git-Url: http://sru.miketaylor.org.uk/?a=commitdiff_plain;h=0e4bd2f722c9cf0a83e7e4ef3d936c60c9419add;p=metaproxy-moved-to-github.git RouterFleXML now stores routes and filters internally. --- diff --git a/src/factory_filter.cpp b/src/factory_filter.cpp index de786ff..d48d2dd 100644 --- a/src/factory_filter.cpp +++ b/src/factory_filter.cpp @@ -1,4 +1,4 @@ -/* $Id: factory_filter.cpp,v 1.1 2006-01-04 14:30:51 adam Exp $ +/* $Id: factory_filter.cpp,v 1.2 2006-01-05 16:39:37 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -29,8 +29,8 @@ namespace yp2 { }; } -yp2::FactoryFilterException::FactoryFilterException(const std::string message) - : std::runtime_error("FilterException: " + message) +yp2::FactoryFilter::NotFound::NotFound(const std::string message) + : std::runtime_error(message) { } @@ -70,7 +70,7 @@ yp2::filter::Base* yp2::FactoryFilter::create(std::string fi) if (it == m_p->m_fcm.end()){ std::string msg = "filter type '" + fi + "' not found"; - throw yp2::FactoryFilterException(msg); + throw NotFound(msg); } // call create function return (it->second()); diff --git a/src/factory_filter.hpp b/src/factory_filter.hpp index ab2acd8..7ecb706 100644 --- a/src/factory_filter.hpp +++ b/src/factory_filter.hpp @@ -1,4 +1,4 @@ -/* $Id: factory_filter.hpp,v 1.1 2006-01-04 14:30:51 adam Exp $ +/* $Id: factory_filter.hpp,v 1.2 2006-01-05 16:39:37 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -18,11 +18,6 @@ #include "filter.hpp" namespace yp2 { - class FactoryFilterException : public std::runtime_error { - public: - FactoryFilterException(const std::string message); - }; - class FactoryFilter : public boost::noncopyable { typedef yp2::filter::Base* (*CreateFilterCallback)(); @@ -41,6 +36,12 @@ namespace yp2 { yp2::filter::Base* create(std::string fi); bool add_creator_dyn(const std::string &fi, const std::string &path); + + + class NotFound : public std::runtime_error { + public: + NotFound(const std::string msg); + }; private: boost::scoped_ptr m_p; }; diff --git a/src/router.hpp b/src/router.hpp index 28279de..31836ae 100644 --- a/src/router.hpp +++ b/src/router.hpp @@ -1,4 +1,4 @@ -/* $Id: router.hpp,v 1.6 2005-11-10 23:10:42 adam Exp $ +/* $Id: router.hpp,v 1.7 2006-01-05 16:39:37 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -23,8 +23,7 @@ namespace yp2 RouterException(const std::string message) : std::runtime_error("RouterException: " + message){}; }; - - + class Router : boost::noncopyable { public: Router(){}; @@ -33,14 +32,6 @@ namespace yp2 /// determines next Filter to use from current Filter and Package virtual const filter::Base *move(const filter::Base *filter, const Package *package) const = 0; - - /// re-read configuration of routing tables - //virtual void configure(){}; - - /// add routing rule expressed as Filter to Router - //virtual Router & rule(const filter::Base &filter){ - // return *this; - //} }; } #endif diff --git a/src/router_flexml.cpp b/src/router_flexml.cpp index 2abdfa8..d4e24d7 100644 --- a/src/router_flexml.cpp +++ b/src/router_flexml.cpp @@ -1,4 +1,4 @@ -/* $Id: router_flexml.cpp,v 1.9 2006-01-04 14:30:51 adam Exp $ +/* $Id: router_flexml.cpp,v 1.10 2006-01-05 16:39:37 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -21,6 +21,10 @@ namespace yp2 { + class RouterFleXML::Route { + friend class RouterFleXML::Rep; + std::list > m_list; + }; class RouterFleXML::Rep { friend class RouterFleXML; Rep(); @@ -31,9 +35,7 @@ namespace yp2 { IdFilterMap m_id_filter_map; - void create_filter(std::string type, - const xmlDoc * xmldoc, - std::string id = ""); + std::map m_routes; void parse_xml_config_dom(xmlDocPtr doc); @@ -52,13 +54,17 @@ namespace yp2 { const xmlNode* jump_to_next(const xmlNode* node, int xml_node_type); const xmlNode* jump_to_children(const xmlNode* node, int xml_node_type); + void parse_xml_filters(xmlDocPtr doc, const xmlNode *node); + void parse_xml_routes(xmlDocPtr doc, const xmlNode *node); + bool m_xinclude; private: FactoryFilter *m_factory; // TODO shared_ptr }; } -const xmlNode* yp2::RouterFleXML::Rep::jump_to_children(const xmlNode* node, int xml_node_type) +const xmlNode* yp2::RouterFleXML::Rep::jump_to_children(const xmlNode* node, + int xml_node_type) { node = node->children; for (; node && node->type != xml_node_type; node = node->next) @@ -66,7 +72,8 @@ const xmlNode* yp2::RouterFleXML::Rep::jump_to_children(const xmlNode* node, int return node; } -const xmlNode* yp2::RouterFleXML::Rep::jump_to_next(const xmlNode* node, int xml_node_type) +const xmlNode* yp2::RouterFleXML::Rep::jump_to_next(const xmlNode* node, + int xml_node_type) { node = node->next; for (; node && node->type != xml_node_type; node = node->next) @@ -74,7 +81,8 @@ const xmlNode* yp2::RouterFleXML::Rep::jump_to_next(const xmlNode* node, int xml return node; } -const xmlNode* yp2::RouterFleXML::Rep::jump_to(const xmlNode* node, int xml_node_type) +const xmlNode* yp2::RouterFleXML::Rep::jump_to(const xmlNode* node, + int xml_node_type) { for (; node && node->type != xml_node_type; node = node->next) ; @@ -102,40 +110,16 @@ bool yp2::RouterFleXML::Rep::check_element_yp2(const xmlNode *ptr, const std::string &name) { if (!is_element_yp2(ptr, name)) - throw XMLError("Error. Expected element name " + name); + throw XMLError("Expected element name " + name); return true; } -void yp2::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc) -{ - if (!doc) - throw XMLError("Empty XML Document"); - - const xmlNode* root = xmlDocGetRootElement(doc); - - check_element_yp2(root, "yp2"); - std::cout << "processing /yp2" << std::endl; - - // process node which is expected first element node - const xmlNode* node = jump_to_children(root, XML_ELEMENT_NODE); - //for (; node && node->type != XML_ELEMENT_NODE; node = node->next) - // ; - - check_element_yp2(node, "start"); - - std::cout << "processing /yp2/start" << std::endl; - - // process node which is expected second element node - node = jump_to_next(node, XML_ELEMENT_NODE); - check_element_yp2(node, "filters"); - std::cout << "processing /yp2/filters" << std::endl; - - // process nodes in next level - const xmlNode* node2 = jump_to_children(node, XML_ELEMENT_NODE); - +void yp2::RouterFleXML::Rep::parse_xml_filters(xmlDocPtr doc, + const xmlNode *node) +{ unsigned int filter_nr = 0; - while(node2 && check_element_yp2(node2, "filter")) + while(node && check_element_yp2(node, "filter")) { filter_nr++; std::cout << "processing /yp2/filters/filter[" @@ -144,7 +128,7 @@ void yp2::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc) const struct _xmlAttr *attr; std::string id_value; std::string type_value; - for (attr = node2->properties; attr; attr = attr->next) + for (attr = node->properties; attr; attr = attr->next) { std::string name = std::string((const char *) attr->name); std::string value; @@ -157,16 +141,15 @@ void yp2::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc) else if (name == "type") type_value = value; else - throw XMLError("Error. Only attribute id or type allowed in filter element. Got " + name); + throw XMLError("Only attribute id or type allowed" + " in filter element. Got " + name); std::cout << "attr " << name << "=" << value << "\n"; - - //const xmlNode *val; } yp2::filter::Base* filter_base = m_factory->create(type_value); - filter_base->configure(node2); + filter_base->configure(node); if (m_id_filter_map.find(id_value) != m_id_filter_map.end()) throw XMLError("Filter " + id_value + " already defined"); @@ -174,33 +157,92 @@ void yp2::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc) m_id_filter_map[id_value] = boost::shared_ptr(filter_base); - node2 = jump_to_next(node2, XML_ELEMENT_NODE); + node = jump_to_next(node, XML_ELEMENT_NODE); } - - // process node which is expected third element node - node = jump_to_next(node, XML_ELEMENT_NODE); - check_element_yp2(node, "routes"); - std::cout << "processing /yp2/routes" << std::endl; - - // process nodes in next level - node2 = jump_to_children(node, XML_ELEMENT_NODE); - check_element_yp2(node2, "route"); - +} + +void yp2::RouterFleXML::Rep::parse_xml_routes(xmlDocPtr doc, + const xmlNode *node) +{ + check_element_yp2(node, "route"); + unsigned int route_nr = 0; - while(is_element_yp2(node2, "router")) + while(is_element_yp2(node, "route")) { route_nr++; + + const struct _xmlAttr *attr; + std::string id_value; + for (attr = node->properties; attr; attr = attr->next) + { + std::string name = std::string((const char *) attr->name); + std::string value; + + if (attr->children && attr->children->type == XML_TEXT_NODE) + value = std::string((const char *)attr->children->content); + + if (name == "id") + id_value = value; + else + throw XMLError("Only attribute refid allowed route element. Got " + name); + + std::cout << "attr " << name << "=" << value << "\n"; + } + + Route route; + std::cout << "processing /yp2/routes/route[" << route_nr << "]" << std::endl; // process nodes in third level - const xmlNode* node3 = jump_to_children(node2, XML_ELEMENT_NODE); - + + const xmlNode* node3 = jump_to_children(node, XML_ELEMENT_NODE); + unsigned int filter3_nr = 0; while(node3 && check_element_yp2(node3, "filter")) { filter3_nr++; + const struct _xmlAttr *attr; + std::string refid_value; + std::string type_value; + for (attr = node3->properties; attr; attr = attr->next) + { + std::string name = std::string((const char *) attr->name); + std::string value; + + if (attr->children && attr->children->type == XML_TEXT_NODE) + value = std::string((const char *)attr->children->content); + + if (name == "refid") + refid_value = value; + else if (name == "type") + type_value = value; + else + throw XMLError("Only attribute refid or type" + " allowed in filter element. Got " + name); + + std::cout << "attr " << name << "=" << value << "\n"; + } + if (refid_value.length()) + { + std::map >::iterator it; + it = m_id_filter_map.find(refid_value); + if (it == m_id_filter_map.end()) + throw XMLError("Unknown filter refid " + refid_value); + else + route.m_list.push_back(it->second); + } + else if (type_value.length()) + { + yp2::filter::Base* filter_base = m_factory->create(type_value); + + filter_base->configure(node3); + + route.m_list.push_back( + boost::shared_ptr(filter_base)); + } std::cout << "processing /yp2/routes/route[" << route_nr << "]/filter[" << filter3_nr << "]" << std::endl; @@ -208,20 +250,52 @@ void yp2::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc) node3 = jump_to_next(node3, XML_ELEMENT_NODE); } - node2 = jump_to_next(node2, XML_ELEMENT_NODE); + std::map::iterator it; + it = m_routes.find(id_value); + if (it != m_routes.end()) + throw XMLError("Route id='" + id_value + "' already exist"); + else + m_routes[id_value] = route; + node = jump_to_next(node, XML_ELEMENT_NODE); } -} +} -void yp2::RouterFleXML::Rep::create_filter(std::string type, - const xmlDoc * xmldoc, - std::string id) +void yp2::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc) { - std::cout << "Created Filter type='" << type - << "' id='" << id << "'" << std::endl; -} + if (!doc) + throw XMLError("Empty XML Document"); + + const xmlNode* root = xmlDocGetRootElement(doc); + + check_element_yp2(root, "yp2"); + + std::cout << "processing /yp2" << std::endl; + + // process node which is expected first element node + const xmlNode* node = jump_to_children(root, XML_ELEMENT_NODE); + //for (; node && node->type != XML_ELEMENT_NODE; node = node->next) + // ; + + check_element_yp2(node, "start"); + + std::cout << "processing /yp2/start" << std::endl; + + // process node which is expected second element node + node = jump_to_next(node, XML_ELEMENT_NODE); + check_element_yp2(node, "filters"); + std::cout << "processing /yp2/filters" << std::endl; + + parse_xml_filters(doc, jump_to_children(node, XML_ELEMENT_NODE)); + + // process node which is expected third element node + node = jump_to_next(node, XML_ELEMENT_NODE); + check_element_yp2(node, "routes"); + std::cout << "processing /yp2/routes" << std::endl; + + parse_xml_routes(doc, jump_to_children(node, XML_ELEMENT_NODE)); +} -yp2::RouterFleXML::Rep::Rep() : - m_xinclude(false) +yp2::RouterFleXML::Rep::Rep() : m_xinclude(false) { } diff --git a/src/router_flexml.hpp b/src/router_flexml.hpp index 814d4c1..be7b66d 100644 --- a/src/router_flexml.hpp +++ b/src/router_flexml.hpp @@ -1,4 +1,4 @@ -/* $Id: router_flexml.hpp,v 1.9 2006-01-04 14:30:51 adam Exp $ +/* $Id: router_flexml.hpp,v 1.10 2006-01-05 16:39:37 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -17,6 +17,7 @@ namespace yp2 class RouterFleXML : public yp2::Router { class Rep; + class Route; public: RouterFleXML(std::string xmlconf, yp2::FactoryFilter &factory); diff --git a/src/test_router_flexml.cpp b/src/test_router_flexml.cpp index 5cefd7a..5bed848 100644 --- a/src/test_router_flexml.cpp +++ b/src/test_router_flexml.cpp @@ -1,4 +1,4 @@ -/* $Id: test_router_flexml.cpp,v 1.11 2006-01-04 14:30:51 adam Exp $ +/* $Id: test_router_flexml.cpp,v 1.12 2006-01-05 16:39:37 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -17,11 +17,12 @@ using namespace boost::unit_test; -static bool tfilter_destroyed = false; +static int tfilter_ref = 0; class TFilter: public yp2::filter::Base { public: void process(yp2::Package & package) const {}; - ~TFilter() { tfilter_destroyed = true; }; + TFilter() { tfilter_ref++; }; + ~TFilter() { tfilter_ref--; }; }; static yp2::filter::Base* filter_creator() @@ -29,6 +30,7 @@ static yp2::filter::Base* filter_creator() return new TFilter; } +// Pass well-formed XML and valid configuration to it (implicit NS) BOOST_AUTO_UNIT_TEST( test_router_flexml_1 ) { try @@ -53,7 +55,11 @@ BOOST_AUTO_UNIT_TEST( test_router_flexml_1 ) " \n" " \n" " \n" - " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" "\n"; @@ -61,6 +67,7 @@ BOOST_AUTO_UNIT_TEST( test_router_flexml_1 ) yp2::FactoryStatic factory; factory.add_creator("tfilter", filter_creator); yp2::RouterFleXML rflexml(xmlconf, factory); + BOOST_CHECK_EQUAL(tfilter_ref, 2); } catch ( std::runtime_error &e) { std::cout << "std::runtime error: " << e.what() << "\n"; @@ -69,12 +76,13 @@ BOOST_AUTO_UNIT_TEST( test_router_flexml_1 ) catch ( ... ) { BOOST_CHECK (false); } - BOOST_CHECK(tfilter_destroyed == true); + BOOST_CHECK_EQUAL(tfilter_ref, 0); } +// Pass non-wellformed XML BOOST_AUTO_UNIT_TEST( test_router_flexml_2 ) { - bool got_xml_error = false; + bool got_error_as_expected = false; try { std::string xmlconf_invalid = "\n" @@ -88,18 +96,19 @@ BOOST_AUTO_UNIT_TEST( test_router_flexml_2 ) yp2::RouterFleXML rflexml(xmlconf_invalid, factory); } catch ( yp2::RouterFleXML::XMLError &e) { - got_xml_error = true; + std::cout << "XMLError: " << e.what() << "\n"; + got_error_as_expected = true; } catch ( std::runtime_error &e) { std::cout << "std::runtime error: " << e.what() << "\n"; - BOOST_CHECK (false); } catch ( ... ) { ; } - BOOST_CHECK(got_xml_error); + BOOST_CHECK(got_error_as_expected); } +// Pass well-formed XML with explicit NS BOOST_AUTO_UNIT_TEST( test_router_flexml_3 ) { try @@ -135,6 +144,41 @@ BOOST_AUTO_UNIT_TEST( test_router_flexml_3 ) } } +// Pass well-formed XML but bad filter type +BOOST_AUTO_UNIT_TEST( test_router_flexml_4 ) +{ + bool got_error_as_expected = false; + try + { + std::string xmlconf = "\n" + "\n" + " \n" + " \n" + " \n" + " 210\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"; + + yp2::FactoryStatic factory; + factory.add_creator("tfilter", filter_creator); + yp2::RouterFleXML rflexml(xmlconf, factory); + } + catch ( yp2::FactoryFilter::NotFound &e) { + std::cout << "yp2::FactoryFilter::NotFound: " << e.what() << "\n"; + got_error_as_expected = true; + } + catch ( std::runtime_error &e) { + std::cout << "std::runtime error: " << e.what() << "\n"; + } + BOOST_CHECK(got_error_as_expected); +} + /* * Local variables: