From d5b031ae45177bd33411d88bc089a90c6842d156 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 19 Jun 2016 20:51:55 +0100 Subject: Pass input parameters, write output objects --- icespider/core/Jamfile.jam | 4 ++ icespider/core/ihttpRequest.cpp | 36 ++++++++++++++++++ icespider/core/ihttpRequest.h | 25 ++++++++++--- icespider/unittests/Jamfile.jam | 7 ++++ icespider/unittests/testApp.cpp | 75 +++++++++++++++++++++++++++++++++---- icespider/unittests/testCompile.cpp | 3 +- 6 files changed, 137 insertions(+), 13 deletions(-) diff --git a/icespider/core/Jamfile.jam b/icespider/core/Jamfile.jam index d00669f..6a99e84 100644 --- a/icespider/core/Jamfile.jam +++ b/icespider/core/Jamfile.jam @@ -1,10 +1,14 @@ lib adhocutil : : : : /usr/include/adhocutil ; +lib slicer : : : : /usr/include/slicer ; +lib boost_system ; lib icespider-core : [ glob-tree *.cpp : bin ] : ../common adhocutil + slicer + boost_system ../common : : . diff --git a/icespider/core/ihttpRequest.cpp b/icespider/core/ihttpRequest.cpp index 0e14957..de26a1c 100644 --- a/icespider/core/ihttpRequest.cpp +++ b/icespider/core/ihttpRequest.cpp @@ -1,4 +1,5 @@ #include "ihttpRequest.h" +#include namespace IceSpider { IHttpRequest::IHttpRequest(const Core * c) : @@ -11,5 +12,40 @@ namespace IceSpider { { return Ice::Context(); } + + Slicer::DeserializerPtr + IHttpRequest::getDeserializer() const + { + return Slicer::StreamDeserializerFactory::createNew( + getHeaderParam("Content-Type"), getInputStream()); + } + + Slicer::SerializerPtr + IHttpRequest::getSerializer() const + { + return Slicer::StreamSerializerFactory::createNew( + "application/json", getOutputStream()); + } + +#define getParams(T) \ + template<> T IHttpRequest::getURLParam(const std::string & key) const { \ + return boost::lexical_cast(getURLParam(key)); } \ + template<> T IHttpRequest::getQueryStringParam(const std::string & key) const { \ + return boost::lexical_cast(getQueryStringParam(key)); } \ + template<> T IHttpRequest::getHeaderParam(const std::string & key) const { \ + return boost::lexical_cast(getHeaderParam(key)); } + template<> std::string IHttpRequest::getURLParam(const std::string & key) const { \ + return getURLParam(key); } + template<> std::string IHttpRequest::getQueryStringParam(const std::string & key) const { \ + return getQueryStringParam(key); } + template<> std::string IHttpRequest::getHeaderParam(const std::string & key) const { \ + return getHeaderParam(key); } + + getParams(bool); + getParams(Ice::Short); + getParams(Ice::Int); + getParams(Ice::Long); + getParams(Ice::Float); + getParams(Ice::Double); } diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h index 2193a67..6b1a3b0 100644 --- a/icespider/core/ihttpRequest.h +++ b/icespider/core/ihttpRequest.h @@ -6,6 +6,7 @@ #include #include #include +#include namespace IceSpider { class Core; @@ -18,16 +19,30 @@ namespace IceSpider { virtual std::string getRequestPath() const = 0; virtual UserIceSpider::HttpMethod getRequestMethod() const = 0; + virtual std::string getURLParam(const std::string &) const = 0; + virtual std::string getQueryStringParam(const std::string &) const = 0; + virtual std::string getHeaderParam(const std::string &) const = 0; + virtual Slicer::DeserializerPtr getDeserializer() const; + virtual Slicer::SerializerPtr getSerializer() const; + virtual std::istream & getInputStream() const = 0; + virtual std::ostream & getOutputStream() const = 0; + template - T getURLParam(const std::string & key) const { (void)key; return T(); } + T getURLParam(const std::string & key) const; template - T getBodyParam(const std::string & key) const { (void)key; return T(); } + T getBodyParam(const std::string &) const + { + return Slicer::DeserializeAnyWith(getDeserializer()); + } template - T getQueryStringParam(const std::string & key) const { (void)key; return T(); } + T getQueryStringParam(const std::string & key) const; template - T getHeaderParam(const std::string & key) const { (void)key; return T(); } + T getHeaderParam(const std::string & key) const; template - void response(const T &) const { } + void response(const T & t) const + { + Slicer::SerializeAnyWith(t, getSerializer()); + } const Core * core; }; diff --git a/icespider/unittests/Jamfile.jam b/icespider/unittests/Jamfile.jam index 9388f37..b9a861b 100644 --- a/icespider/unittests/Jamfile.jam +++ b/icespider/unittests/Jamfile.jam @@ -17,6 +17,8 @@ actions routes2cpp bind ICESPIDER } lib adhocutil : : : : /usr/include/adhocutil ; +lib slicer : : : : /usr/include/slicer ; +lib slicer-json : : : : /usr/include/slicer ; lib boost_utf : : boost_unit_test_framework ; lib dl ; path-constant me : . ; @@ -58,6 +60,8 @@ run testCommon test-api adhocutil + slicer + slicer-json ../common//icespider-common ../core//icespider-core ../common//icespider-common @@ -69,6 +73,9 @@ run lib test-api : test-api.ice : + yes + slicer + adhocutil ..//pthread ..//Ice ..//IceUtil diff --git a/icespider/unittests/testApp.cpp b/icespider/unittests/testApp.cpp index 08c03b4..aa00c43 100644 --- a/icespider/unittests/testApp.cpp +++ b/icespider/unittests/testApp.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,38 @@ class TestRequest : public IceSpider::IHttpRequest { return method; } + std::string getURLParam(const std::string & key) const override + { + return AdHoc::safeMapLookup(url, key); + } + + std::string getQueryStringParam(const std::string & key) const override + { + return AdHoc::safeMapLookup(qs, key); + } + + std::string getHeaderParam(const std::string & key) const override + { + return AdHoc::safeMapLookup(hdr, key); + } + + std::istream & getInputStream() const override + { + return input; + } + + std::ostream & getOutputStream() const override + { + return output; + } + + typedef std::map MapVars; + MapVars url; + MapVars qs; + MapVars hdr; + mutable std::stringstream input; + mutable std::stringstream output; + const HttpMethod method; const std::string path; }; @@ -92,33 +125,61 @@ class TestSerice : public TestIceSpider::TestApi { public: TestIceSpider::SomeModelPtr index(const Ice::Current &) override { - return NULL; + return new TestIceSpider::SomeModel("index"); } - TestIceSpider::SomeModelPtr withParams(const std::string &, Ice::Int, const Ice::Current &) override + TestIceSpider::SomeModelPtr withParams(const std::string & s, Ice::Int i, const Ice::Current &) override { - return NULL; + BOOST_REQUIRE_EQUAL(s, "something"); + BOOST_REQUIRE_EQUAL(i, 1234); + return new TestIceSpider::SomeModel("withParams"); } - void returnNothing(const std::string &, const Ice::Current &) override + void returnNothing(const std::string & s, const Ice::Current &) override { + BOOST_REQUIRE_EQUAL(s, "some value"); } - void complexParam(const std::string &, const TestIceSpider::SomeModelPtr &, const Ice::Current &) override + void complexParam(const std::string & s, const TestIceSpider::SomeModelPtr & m, const Ice::Current &) override { + BOOST_REQUIRE_EQUAL(s, "1234"); + BOOST_REQUIRE(m); + BOOST_REQUIRE_EQUAL("some value", m->value); } }; -BOOST_AUTO_TEST_CASE( testGetIndex ) +BOOST_AUTO_TEST_CASE( testCallMethods ) { auto adp = communicator->createObjectAdapterWithEndpoints("test", "default"); auto obj = adp->addWithUUID(new TestSerice()); adp->activate(); - TestRequest requestGetIndex(this, HttpMethod::GET, "/"); fprintf(stderr, "%s\n", obj->ice_id().c_str()); communicator->getProperties()->setProperty("N13TestIceSpider7TestApiE", communicator->proxyToString(obj)); + + TestRequest requestGetIndex(this, HttpMethod::GET, "/"); process(&requestGetIndex); + BOOST_REQUIRE_EQUAL(requestGetIndex.output.str(), "{\"value\":\"index\"}"); + + TestRequest requestGetItem(this, HttpMethod::GET, "/view/something/1234"); + requestGetItem.url["s"] = "something"; + requestGetItem.url["i"] = "1234"; + process(&requestGetItem); + BOOST_REQUIRE_EQUAL(requestGetItem.output.str(), "{\"value\":\"withParams\"}"); + + TestRequest requestDeleteItem(this, HttpMethod::DELETE, "/some value"); + requestDeleteItem.url["s"] = "some value"; + process(&requestDeleteItem); + BOOST_REQUIRE(requestDeleteItem.output.str().empty()); + + TestRequest requestUpdateItem(this, HttpMethod::POST, "/1234"); + requestUpdateItem.url["id"] = "1234"; + requestUpdateItem.hdr["Content-Type"] = "application/json"; + requestUpdateItem.input << "{\"value\": \"some value\"}"; + process(&requestUpdateItem); + BOOST_REQUIRE(requestDeleteItem.output.str().empty()); + adp->deactivate(); } BOOST_AUTO_TEST_SUITE_END(); + diff --git a/icespider/unittests/testCompile.cpp b/icespider/unittests/testCompile.cpp index b7ce0f5..4325c16 100644 --- a/icespider/unittests/testCompile.cpp +++ b/icespider/unittests/testCompile.cpp @@ -59,12 +59,13 @@ BOOST_AUTO_TEST_CASE( testCompile ) auto input = rootDir / "testRoutes.json"; auto output = binDir / "testRoutes.cpp"; auto outputso = boost::filesystem::change_extension(output, ".so"); - auto libGenDir = (rootDir / "bin" / modeDir); + auto libGenDir = (rootDir / "bin" / modeDir / "slicer-yes"); rc.compile(input, output); auto compileCommand = boost::algorithm::join>({ "gcc", "-shared", "-std=c++1y", "-fPIC", " -fvisibility=hidden", "-O3", "-Wl,--warn-once,--gc-sections", "-I", "/usr/include/adhocutil", + "-I", "/usr/include/slicer", "-I", (rootDir.parent_path() / "core").string(), "-I", (rootDir.parent_path() / "common").string(), "-I", (rootDir.parent_path() / "common" / "bin" / modeDir).string(), -- cgit v1.2.3