Codegen. ApiController. 'ENDPOINT_INTERCEPTOR' macro tests.

This commit is contained in:
lganzzzo 2019-10-02 03:30:52 +03:00
parent af8aef9745
commit d5b7cb536a
11 changed files with 349 additions and 10 deletions

View File

@ -396,14 +396,14 @@ Z__USER_PROXY_INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME( \
T* controller, \
const std::shared_ptr<oatpp::web::protocol::http::incoming::Request>& request \
) { \
auto prevMethod = static_cast<typename Handler<T>::Method>(Z__INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME); \
return Z__USER_INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME <T> (prevMethod, request); \
auto intercepted = static_cast<typename Handler<T>::Method>(Z__INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME); \
return Z__USER_INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME <T> (intercepted, request); \
} \
\
template<class T> \
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> \
Z__USER_INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME( \
typename Handler<T>::Method prevMethod, \
typename Handler<T>::Method intercepted, \
const std::shared_ptr<oatpp::web::protocol::http::incoming::Request>& request \
)
@ -510,13 +510,13 @@ Z__USER_PROXY_INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME( \
T* controller, \
const std::shared_ptr<oatpp::web::protocol::http::incoming::Request>& request \
) { \
auto prevMethod = static_cast<typename Handler<T>::MethodAsync>(Z__INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME); \
return Z__USER_INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME <T> (prevMethod, request); \
auto intercepted = static_cast<typename Handler<T>::MethodAsync>(Z__INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME); \
return Z__USER_INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME <T> (intercepted, request); \
} \
\
template<class T> \
oatpp::async::CoroutineStarterForResult<const std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>&> \
Z__USER_INTERCEPTOR_METHOD_##ENDPOINT_NAME ##_ ##NAME( \
typename Handler<T>::MethodAsync prevMethod, \
typename Handler<T>::MethodAsync intercepted, \
const std::shared_ptr<oatpp::web::protocol::http::incoming::Request>& request \
)

View File

@ -89,6 +89,19 @@ std::shared_ptr<const http::incoming::BodyDecoder> Request::getBodyDecoder() con
return m_bodyDecoder;
}
void Request::putHeader(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) {
m_headers[key] = value;
}
bool Request::putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) {
auto it = m_headers.find(key);
if(it == m_headers.end()) {
m_headers.insert({key, value});
return true;
}
return false;
}
oatpp::String Request::getHeader(const oatpp::data::share::StringKeyLabelCI_FAST& headerName) const{
auto it = m_headers.find(headerName);
if(it != m_headers.end()) {

View File

@ -126,10 +126,25 @@ public:
*/
std::shared_ptr<const http::incoming::BodyDecoder> getBodyDecoder() const;
/**
* Add http header.
* @param key - &id:oatpp::data::share::StringKeyLabelCI_FAST;.
* @param value - &id:oatpp::data::share::StringKeyLabel;.
*/
void putHeader(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value);
/**
* Add http header if not already exists.
* @param key - &id:oatpp::data::share::StringKeyLabelCI_FAST;.
* @param value - &id:oatpp::data::share::StringKeyLabel;.
* @return - `true` if header was added.
*/
bool putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value);
/**
* Get header value
* @param headerName
* @return header value
* @param headerName - &id:oatpp::data::share::StringKeyLabelCI_FAST;.
* @return - &id:oatpp::String;.
*/
oatpp::String getHeader(const oatpp::data::share::StringKeyLabelCI_FAST& headerName) const;

View File

@ -60,6 +60,14 @@ bool Response::putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_F
return false;
}
oatpp::String Response::getHeader(const oatpp::data::share::StringKeyLabelCI_FAST& headerName) const {
auto it = m_headers.find(headerName);
if(it != m_headers.end()) {
return it->second.toString();
}
return nullptr;
}
void Response::setConnectionUpgradeHandler(const std::shared_ptr<oatpp::network::server::ConnectionHandler>& handler) {
m_connectionUpgradeHandler = handler;
}

View File

@ -100,6 +100,13 @@ public:
*/
bool putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value);
/**
* Get header value
* @param headerName - &id:oatpp::data::share::StringKeyLabelCI_FAST;.
* @return - &id:oatpp::String;.
*/
oatpp::String getHeader(const oatpp::data::share::StringKeyLabelCI_FAST& headerName) const;
/**
* Set connection upgreade header. <br>
* Use it together with corresponding headers being set when Response is created as: <br>

View File

@ -51,14 +51,16 @@ add_executable(oatppAllTests
oatpp/web/FullAsyncTest.hpp
oatpp/web/FullTest.cpp
oatpp/web/FullTest.hpp
oatpp/web/FullAsyncClientTest.cpp
oatpp/web/FullAsyncClientTest.hpp
oatpp/web/app/Client.hpp
oatpp/web/app/BearerAuthorizationController.hpp
oatpp/web/app/BasicAuthorizationController.hpp
oatpp/web/app/Controller.hpp
oatpp/web/app/ControllerAsync.hpp
oatpp/web/app/DTOs.hpp
oatpp/web/FullAsyncClientTest.cpp
oatpp/web/FullAsyncClientTest.hpp
oatpp/web/app/ControllerWithInterceptors.hpp
oatpp/web/app/ControllerWithInterceptorsAsync.hpp
)
target_link_libraries(oatppAllTests PRIVATE oatpp PRIVATE oatpp-test)

View File

@ -26,6 +26,7 @@
#include "oatpp/web/app/Client.hpp"
#include "oatpp/web/app/ControllerWithInterceptorsAsync.hpp"
#include "oatpp/web/app/ControllerAsync.hpp"
#include "oatpp/web/client/HttpRequestExecutor.hpp"
@ -143,6 +144,7 @@ void FullAsyncTest::onRun() {
oatpp::test::web::ClientServerTestRunner runner;
runner.addController(app::ControllerAsync::createShared());
runner.addController(app::ControllerWithInterceptorsAsync::createShared());
runner.run([this, &runner] {
@ -256,6 +258,13 @@ void FullAsyncTest::onRun() {
}
{ // test interceptor GET
auto response = client->getInterceptors(connection);
OATPP_ASSERT(response->getStatusCode() == 200);
auto value = response->readBodyToString();
OATPP_ASSERT(value == "Hello World Async!!!");
}
if((i + 1) % iterationsStep == 0) {
auto ticks = oatpp::base::Environment::getMicroTickCount() - lastTick;
lastTick = oatpp::base::Environment::getMicroTickCount();

View File

@ -26,6 +26,7 @@
#include "oatpp/web/app/Client.hpp"
#include "oatpp/web/app/ControllerWithInterceptors.hpp"
#include "oatpp/web/app/Controller.hpp"
#include "oatpp/web/app/BasicAuthorizationController.hpp"
#include "oatpp/web/app/BearerAuthorizationController.hpp"
@ -140,6 +141,7 @@ void FullTest::onRun() {
oatpp::test::web::ClientServerTestRunner runner;
runner.addController(app::Controller::createShared());
runner.addController(app::ControllerWithInterceptors::createShared());
runner.addController(app::DefaultBasicAuthorizationController::createShared());
runner.addController(app::BasicAuthorizationController::createShared());
runner.addController(app::BearerAuthorizationController::createShared());
@ -353,6 +355,13 @@ void FullTest::onRun() {
}
{ // test interceptors
auto response = client->getInterceptors(connection);
OATPP_ASSERT(response->getStatusCode() == 200);
auto value = response->readBodyToString();
OATPP_ASSERT(value == "Hello World!!!");
}
if((i + 1) % iterationsStep == 0) {
auto ticks = oatpp::base::Environment::getMicroTickCount() - lastTick;
lastTick = oatpp::base::Environment::getMicroTickCount();

View File

@ -60,6 +60,8 @@ public:
API_CALL("GET", "chunked/{text-value}/{num-iterations}", getChunked, PATH(String, text, "text-value"), PATH(Int32, numIterations, "num-iterations"))
API_CALL("POST", "test/multipart/{chunk-size}", multipartTest, PATH(Int32, chunkSize, "chunk-size"), BODY(std::shared_ptr<MultipartBody>, body))
API_CALL("GET", "test/interceptors", getInterceptors)
API_CALL_ASYNC("GET", "/", getRootAsync)
API_CALL_ASYNC("GET", "/", getRootAsyncWithCKA, HEADER(String, connection, "Connection"))
API_CALL_ASYNC("GET", "params/{param}", getWithParamsAsync, PATH(String, param))

View File

@ -0,0 +1,114 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_test_web_app_ControllerWithInterceptors_hpp
#define oatpp_test_web_app_ControllerWithInterceptors_hpp
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/core/utils/ConversionUtils.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/macro/component.hpp"
#include <sstream>
namespace oatpp { namespace test { namespace web { namespace app {
namespace multipart = oatpp::web::mime::multipart;
class ControllerWithInterceptors : public oatpp::web::server::api::ApiController {
private:
static constexpr const char* TAG = "test::web::app::ControllerWithInterceptors";
public:
ControllerWithInterceptors(const std::shared_ptr<ObjectMapper>& objectMapper)
: oatpp::web::server::api::ApiController(objectMapper)
{}
public:
static std::shared_ptr<ControllerWithInterceptors> createShared(const std::shared_ptr<ObjectMapper>& objectMapper = OATPP_GET_COMPONENT(std::shared_ptr<ObjectMapper>)){
return std::make_shared<ControllerWithInterceptors>(objectMapper);
}
#include OATPP_CODEGEN_BEGIN(ApiController)
ENDPOINT_INTERCEPTOR(interceptor, inter1) {
/* assert order of interception */
OATPP_ASSERT(request->getHeader("header-in-inter2") == "inter2");
OATPP_ASSERT(request->getHeader("header-in-inter3") == "inter3");
/********************************/
request->putHeader("header-in-inter1", "inter1");
auto response = (this->*intercepted)(request);
response->putHeader("header-out-inter1", "inter1");
return response;
}
ENDPOINT_INTERCEPTOR(interceptor, inter2) {
/* assert order of interception */
OATPP_ASSERT(request->getHeader("header-in-inter3") == "inter3");
/********************************/
request->putHeader("header-in-inter2", "inter2");
auto response = (this->*intercepted)(request);
response->putHeader("header-out-inter2", "inter2");
return response;
}
ENDPOINT_INTERCEPTOR(interceptor, inter3) {
request->putHeader("header-in-inter3", "inter3");
auto response = (this->*intercepted)(request);
response->putHeader("header-out-inter3", "inter3");
return response;
}
ENDPOINT_INTERCEPTOR(interceptor, asserter) {
auto response = (this->*intercepted)(request);
OATPP_ASSERT(response->getHeader("header-out-inter1") == "inter1");
OATPP_ASSERT(response->getHeader("header-out-inter2") == "inter2");
OATPP_ASSERT(response->getHeader("header-out-inter3") == "inter3");
return response;
}
ENDPOINT("GET", "test/interceptors", interceptor,
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
OATPP_ASSERT(request->getHeader("header-in-inter1") == "inter1");
OATPP_ASSERT(request->getHeader("header-in-inter2") == "inter2");
OATPP_ASSERT(request->getHeader("header-in-inter3") == "inter3");
return createResponse(Status::CODE_200, "Hello World!!!");
}
#include OATPP_CODEGEN_END(ApiController)
};
}}}}
#endif /* oatpp_test_web_app_ControllerWithInterceptors_hpp */

View File

@ -0,0 +1,160 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_test_web_app_ControllerWithInterceptorsAsync_hpp
#define oatpp_test_web_app_ControllerWithInterceptorsAsync_hpp
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/core/utils/ConversionUtils.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/macro/component.hpp"
#include <sstream>
namespace oatpp { namespace test { namespace web { namespace app {
namespace multipart = oatpp::web::mime::multipart;
class ControllerWithInterceptorsAsync : public oatpp::web::server::api::ApiController {
private:
static constexpr const char* TAG = "test::web::app::ControllerWithInterceptorsAsync";
public:
ControllerWithInterceptorsAsync(const std::shared_ptr<ObjectMapper>& objectMapper)
: oatpp::web::server::api::ApiController(objectMapper)
{}
public:
static std::shared_ptr<ControllerWithInterceptorsAsync> createShared(const std::shared_ptr<ObjectMapper>& objectMapper = OATPP_GET_COMPONENT(std::shared_ptr<ObjectMapper>)){
return std::make_shared<ControllerWithInterceptorsAsync>(objectMapper);
}
#include OATPP_CODEGEN_BEGIN(ApiController)
ENDPOINT_INTERCEPTOR_ASYNC(Interceptor, inter1) {
/* assert order of interception */
OATPP_ASSERT(request->getHeader("header-in-inter2") == "inter2");
OATPP_ASSERT(request->getHeader("header-in-inter3") == "inter3");
/********************************/
request->putHeader("header-in-inter1", "inter1");
return (this->*intercepted)(request);
}
ENDPOINT_INTERCEPTOR_ASYNC(Interceptor, inter2) {
/* assert order of interception */
OATPP_ASSERT(request->getHeader("header-in-inter3") == "inter3");
/********************************/
request->putHeader("header-in-inter2", "inter2");
return (this->*intercepted)(request);
}
ENDPOINT_INTERCEPTOR_ASYNC(Interceptor, inter3) {
class IterceptorCoroutine : public oatpp::async::CoroutineWithResult<IterceptorCoroutine, const std::shared_ptr<OutgoingResponse>&> {
private:
ControllerWithInterceptorsAsync* m_this;
Handler<ControllerWithInterceptorsAsync>::MethodAsync m_intercepted;
std::shared_ptr<IncomingRequest> m_request;
public:
IterceptorCoroutine(ControllerWithInterceptorsAsync* _this,
const Handler<ControllerWithInterceptorsAsync>::MethodAsync& intercepted,
const std::shared_ptr<IncomingRequest>& request)
: m_this(_this)
, m_intercepted(intercepted)
, m_request(request)
{}
oatpp::async::Action act() override {
m_request->putHeader("header-in-inter3", "inter3");
return (m_this->*m_intercepted)(m_request).callbackTo(&IterceptorCoroutine::onResponse);
}
oatpp::async::Action onResponse(const std::shared_ptr<OutgoingResponse>& response) {
response->putHeader("header-out-inter3", "inter3");
return this->_return(response);
}
};
return IterceptorCoroutine::startForResult(this, intercepted, request);
}
ENDPOINT_INTERCEPTOR_ASYNC(Interceptor, asserter) {
class IterceptorCoroutine : public oatpp::async::CoroutineWithResult<IterceptorCoroutine, const std::shared_ptr<OutgoingResponse>&> {
private:
ControllerWithInterceptorsAsync* m_this;
Handler<ControllerWithInterceptorsAsync>::MethodAsync m_intercepted;
std::shared_ptr<IncomingRequest> m_request;
public:
IterceptorCoroutine(ControllerWithInterceptorsAsync* _this,
const Handler<ControllerWithInterceptorsAsync>::MethodAsync& intercepted,
const std::shared_ptr<IncomingRequest>& request)
: m_this(_this)
, m_intercepted(intercepted)
, m_request(request)
{}
oatpp::async::Action act() override {
return (m_this->*m_intercepted)(m_request).callbackTo(&IterceptorCoroutine::onResponse);
}
oatpp::async::Action onResponse(const std::shared_ptr<OutgoingResponse>& response) {
OATPP_ASSERT(response->getHeader("header-out-inter3") == "inter3");
return this->_return(response);
}
};
return IterceptorCoroutine::startForResult(this, intercepted, request);
}
ENDPOINT_ASYNC("GET", "test/interceptors", Interceptor) {
ENDPOINT_ASYNC_INIT(Interceptor)
Action act() {
OATPP_ASSERT(request->getHeader("header-in-inter1") == "inter1");
OATPP_ASSERT(request->getHeader("header-in-inter2") == "inter2");
OATPP_ASSERT(request->getHeader("header-in-inter3") == "inter3");
return _return(controller->createResponse(Status::CODE_200, "Hello World Async!!!"));
}
};
#include OATPP_CODEGEN_END(ApiController)
};
}}}}
#endif /* oatpp_test_web_app_ControllerWithInterceptorsAsync_hpp */