Commit 4491b464 by Amir Aharon

end of day - add libebent-dev to depemdemcies and finished writing EvppServer

parent 22c972c4
......@@ -35,9 +35,9 @@
"/usr/include/x86_64-linux-gnu",
"/usr/include",
"${workspaceRoot}/../3party",
"${workspaceRoot}/../3party/evpp/build-release/include",
"${workspaceRoot}/src"
],
"compileCommands": "./compile_commands.json",
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
......
......@@ -24,10 +24,28 @@
{
"label": "build",
"type": "shell",
// Make this the default build command.
"group": {
"kind": "build",
"isDefault": true
},
"command": "docker exec -it devenv make",
"problemMatcher": [
"$gcc"
]
// "problemMatcher": {
// "severity": "error",
// "base": "$gcc",
// "fileLocation": ["relative","${workspaceRoot}"],
// "pattern": {
// "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
// "file": 1,
// "line": 2,
// "column": 3,
// "severity": 4,
// "message": 5
// }
// }
},
{
"label": "clean",
......
......@@ -8,12 +8,13 @@ set(Microservice_VERSION_STRING ${Microservice_VERSION_MAJOR}.${Microservice_VER
# type build flags
#set(CMAKE_BUILD_TYPE Release)
set(CMAKE_BINARY_DIR build)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -g")
set(CMAKE_CXX_FLAGS_DEBUG "-O0")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# linked libs and their locations
set ( PROJECT_LINK_LIBS -lPocoFoundation -ljson -lhiredis -lcpprest -lcppmetrics -lboost_random -lboost_timer -lboost_chrono
......
......@@ -6,4 +6,4 @@
# Created on May 8, 2016, 9:59:18 AM
#
sudo apt-get install -y libhiredis0.10 libhiredis-dev libzmq3 libzmq3-dev liblog4cpp5 liblog4cpp5-dev \
libgoogle-glog-dev libboost-all-dev libssl-dev uuid-dev libzmqpp-dev libmhash-dev libevent-2.0
\ No newline at end of file
libgoogle-glog-dev libboost-all-dev libssl-dev uuid-dev libzmqpp-dev libmhash-dev libevent-dev
\ No newline at end of file
......@@ -59,6 +59,10 @@ namespace nsMicroservice_Constants
static const int EXIT_MSG_LEN = strlen(EXIT_MSG);
static const int REQUEST_MSG_INITIAL_SIZE = 1024;
static const char *const NOT_IMPLEMENTED = "Not Implemented";
static const std::string STD_STRING_CONTENT_TYPE_JSON = std::string(CONTENT_TYPE_JSON);
static const std::string STD_STRING_HEADER_CONTENT_TYPE = std::string(HEADER_CONTENT_TYPE);
static const std::string STD_STRING_CONTENT_TYPE_TEXT = std::string("text/html");
static const std::string RCID_HEADER = std::string("X-RCID");
}
/*
......
#include "Microservice_IRestServerEvppImpl.h"
#include <signal.h>
#include <handlers/Microservice_Reactor.h>
#include <evhttp.h>
#include <utils/CommonUtils.h>
static const int SLEEP_INTERVAL = 1; // IN MICROSEC
static int s_sig_num = 0;
const char* Microservice_IRequestRestEvppImpl::GetMethod(){
auto type = connParams_.ctx_->req()->type;
const char *method;
switch (type) {
case EVHTTP_REQ_GET:
method = "GET";
break;
case EVHTTP_REQ_POST:
method = "POST";
break;
case EVHTTP_REQ_HEAD:
method = "HEAD";
break;
case EVHTTP_REQ_PUT:
method = "PUT";
break;
case EVHTTP_REQ_DELETE:
method = "DELETE";
break;
case EVHTTP_REQ_OPTIONS:
method = "OPTIONS";
break;
case EVHTTP_REQ_TRACE:
method = "TRACE";
break;
case EVHTTP_REQ_CONNECT:
method = "CONNECT";
break;
case EVHTTP_REQ_PATCH:
method = "PATCH";
break;
default:
method = nullptr;
break;
}
return (method);
}
void DefaultHandler(evpp::EventLoop* loop,
const evpp::http::ContextPtr& ctx,
const evpp::http::HTTPSendResponseCallback& cb) {
std::stringstream oss;
oss << "func=" << __FUNCTION__ << " OK"
<< " ip=" << ctx->remote_ip() << "\n"
<< " uri=" << ctx->uri() << "\n"
<< " body=" << ctx->body().ToString() << "\n";
ctx->AddResponseHeader("Content-Type", "application/octet-stream");
ctx->AddResponseHeader("Server", "evpp");
oss << "Nothing to see in " << "\n"
<< "uri = " << ctx->uri() << "\n"
<< ".. move along" << "\n";
ctx->set_response_http_code(404);
ctx->AddResponseHeader(nsMicroservice_Constants::STD_STRING_HEADER_CONTENT_TYPE,
nsMicroservice_Constants::STD_STRING_CONTENT_TYPE_TEXT);
ctx->AddResponseHeader("Server", "ipgms");
cb(oss.str());
}
......@@ -56,20 +99,174 @@ void Microservice_IRestServerEvppImpl::registerService(nsMicroservice_Iface::ISe
}
void Microservice_IRestServerEvppImpl::run(){
}
void Microservice_IRestServerEvppImpl::start(){
p_runThread_ = new std::thread(std::bind([this](){
p_server_->Start();
while (!p_server_->IsStopped() && s_sig_num == 0) {
usleep(SLEEP_INTERVAL);
}
// stopping if not stopped already
if (!p_server_->IsStopped())
p_server_->Stop();
}));
}
void Microservice_IRestServerEvppImpl::stop(){
if (p_runThread_){
s_sig_num = 1;
p_runThread_->join();
}
}
bool Microservice_IRestServerEvppImpl::init(){
p_server_ = new evpp::http::Server(p_param_->getWorkerThreadsNum());
p_server_->SetThreadDispatchPolicy(evpp::ThreadDispatchPolicy::kIPAddressHashing);
p_server_->RegisterDefaultHandler(&DefaultHandler);
p_server_->RegisterHandler("/",
[this](evpp::EventLoop* loop,
const evpp::http::ContextPtr& ctx,
const evpp::http::HTTPSendResponseCallback& cb) {
EvppConnParams connParams(ctx,cb);
this->HandleRequest(connParams);
});
p_server_->Init(p_param_->getPort());
return true;
}
void Microservice_IRestServerEvppImpl::HandleRequest(EvppConnParams &connParams){
const char* pba_Uri = connParams.ctx_->uri().c_str();
if (pba_Uri[0] == '/')
{
const char* pba_NextSlash = strchr(pba_Uri + 1, '/');
if (pba_NextSlash)
{
std::string apiContextPath(pba_Uri,(int)(pba_NextSlash - pba_Uri));
std::string key(nsMicroservice_Iface::IRestServer::TYPE);
key.append(nsMicroservice_Constants::TYPE_PREFIX_SEPERATOR).append(apiContextPath);
if(p_reactor_)
HandleNewRequest(connParams, key, apiContextPath);
else
SendGeneralError(connParams,500,"Missing Reactor body!");
}
else
SendNotImplemented(connParams);
}
else
SendNotImplemented(connParams);
}
void Microservice_IRestServerEvppImpl::SendGeneralError(EvppConnParams &connParams,
int respCode,
const char *error){
connParams.ctx_->set_response_http_code(respCode);
std::string errorString = std::string(error);
connParams.ctx_->AddResponseHeader("Content-Type", "text/html");
connParams.ctx_->AddResponseHeader("Server", "ipgms");
connParams.cb_(errorString);
}
void Microservice_IRestServerEvppImpl::HandleNewRequest(EvppConnParams &connParams,
std::string key,
std::string& apiContextPath){
MSRetStat retStat;
Microservice_IRequestRestEvppImpl evppReqRestImpl(connParams);
Microservice_IResponseRestEvppImpl evppRespRestImpl(connParams);
cMicroservice_RequestContext ctx(this,
&evppRespRestImpl,
&evppReqRestImpl);
retStat = ParseRequest(connParams, ctx, apiContextPath);
if (retStat.IsSuccess())
p_reactor_->Delegate(key, &ctx);
else
SendGeneralError(connParams, 500, "Failed in parsing...kus restek! yored lekafa..");
}
void Microservice_IRestServerEvppImpl::SendNotImplemented(EvppConnParams &connParams){
SendGeneralError(connParams,501,nsMicroservice_Constants::NOT_IMPLEMENTED);
}
MSRetStat Microservice_IRestServerEvppImpl::ParseRequest(EvppConnParams &connParams,
cMicroservice_RequestContext& ctx,
std::string& apiContextPath){
/*
* getting params
*/
auto p_request = ((Microservice_IRequestRestEvppImpl*)ctx.mpti_Request);
char* buff = p_request->GetBuffer();
const auto uriLen = connParams.ctx_->uri().length();
memcpy(buff, connParams.ctx_->uri().c_str(),
(uriLen < nsMicroservice_Constants::MAX_URI_LENGTH) ? uriLen : nsMicroservice_Constants::MAX_URI_LENGTH - 1);
buff[uriLen] = CNULL;
char* pba_ParamsStr = &buff[apiContextPath.length()];
char* pba_token = strtok(pba_ParamsStr,nsMicroservice_Constants::SLASH_SEPERATOR);
while(pba_token)
{
ctx.mc_Params.push_back(pba_token);
pba_token = strtok(NULL,nsMicroservice_Constants::SLASH_SEPERATOR);
}
/*
* getting query parameters
*/
GetQueryParams(ctx);
/*
* Log request
*/
LogRequest(p_request);
/**
* get crud method
*/
ctx.crudMethod = GetCrudMethod(p_request);
return MSRetStat();
}
void Microservice_IRestServerEvppImpl::LogRequest(Microservice_IRequestRestEvppImpl* p_request) {
//return connParams_.ctx_->req()->type;
if (p_logger_->getLevel() == cMicroservice_Enums::eLogLevel::eDebug) {
std::string str("Received request: ");
str.append(p_request->GetMethod());
str.append(", uri: ").append(p_request->GetRelativePath());
if (p_request->GetQueryString())
str.append(", query string: ").append(p_request->GetQueryString());
p_logger_->debug(str);
}
}
void
Microservice_IRestServerEvppImpl::GetQueryParams(cMicroservice_RequestContext &ctx) {
/*
* getting query parameters
*/
if (!ctx.mpti_Request->GetQueryString())
return;
// reusing the buffer in the request
auto p_request = ((Microservice_IRequestRestEvppImpl*)ctx.mpti_Request);
char* buff = p_request->GetBuffer();
*buff = CNULL;
DequeStringMap* pc_queryParams = &ctx.mc_QueryParameters;
const auto queryLen = strlen(p_request->GetQueryString());
memcpy(buff, p_request->GetQueryString(),
(queryLen < nsMicroservice_Constants::MAX_URI_LENGTH) ? queryLen : nsMicroservice_Constants::MAX_URI_LENGTH - 1);
buff[queryLen] = CNULL;
CommonUtils::BuildQueryParams(buff,pc_queryParams);
}
eCrudMethod Microservice_IRestServerEvppImpl::GetCrudMethod(Microservice_IRequestRestEvppImpl* p_request) {
auto iter = _microservice_RestCrudMap.find(std::string(p_request->GetMethod()));
if (iter != _microservice_RestCrudMap.end())
return iter->second;
return eCrudMethod::eMaxMethods;
}
......@@ -7,6 +7,14 @@
#include <thread>
#include <evpp/http/http_server.h>
struct EvppConnParams {
const evpp::http::ContextPtr& ctx_;
const evpp::http::HTTPSendResponseCallback& cb_;
EvppConnParams(const evpp::http::ContextPtr& ctx, const evpp::http::HTTPSendResponseCallback& cb) :
ctx_(ctx),cb_(cb) {}
};
class Microservice_IResponseRestEvppImpl: public nsMicroservice_Iface::IResponse
{
// for cloning
......@@ -17,68 +25,86 @@ class Microservice_IResponseRestEvppImpl: public nsMicroservice_Iface::IResponse
// {}
//Evpppp::socket* p_respConnection_;
EvppConnParams connParams_;
std::uint64_t rcid_;
public:
Microservice_IResponseRestEvppImpl() : rcid_(0) {}
Microservice_IResponseRestEvppImpl(EvppConnParams connParams) : connParams_(connParams), rcid_(0) {}
Microservice_IResponseRestEvppImpl(EvppConnParams connParams, std::uint64_t rcid) : connParams_(connParams), rcid_(rcid) {}
void Send(const char* response) override {
// if (p_respConnection_) {
// /**
// * building restresponse msg
// */
// respBuilder_.Clear();
// auto restResponse = common::context::CreateRestResponseDirect(respBuilder_,rcid_,response);
// respBuilder_.Finish(restResponse);
// p_respConnection_->send_raw((const char *) respBuilder_.GetBufferPointer(), respBuilder_.GetSize(), Evpppp::socket::dont_wait);
// }
std::string strResponse = std::string(response);
connParams_.ctx_->AddResponseHeader(nsMicroservice_Constants::STD_STRING_HEADER_CONTENT_TYPE,
nsMicroservice_Constants::STD_STRING_CONTENT_TYPE_JSON);
if (rcid_ > 0)
connParams_.ctx_->AddResponseHeader(nsMicroservice_Constants::RCID_HEADER,std::to_string(rcid_));
connParams_.cb_(strResponse);
}
void Reset() override { /*p_respConnection_ = nullptr; */}
void setParams(/*Evpppp::socket *p_respConnection, */std::uint64_t rcid) {
//p_respConnection_ = p_respConnection;
rcid_ = rcid;
}
// void setParams(/*Evpppp::socket *p_respConnection, */std::uint64_t rcid) {
// //p_respConnection_ = p_respConnection;
// rcid_ = rcid;
// }
virtual nsMicroservice_Iface::IResponse *clone() override {
return new Microservice_IResponseRestEvppImpl();
return new Microservice_IResponseRestEvppImpl(connParams_,rcid_);
}
};
class Microservice_IRequestRestEvppImpl: public nsMicroservice_Iface::IRequest {
public:
Microservice_IRequestRestEvppImpl() {}
Microservice_IRequestRestEvppImpl(EvppConnParams connParams): connParams_(connParams) {
queryString_ = ParseQueryString();
}
const char *GetQueryString() override {
const char *ParseQueryString() {
// if (p_restMsg_)
// return p_restMsg_->queryString()->c_str();
auto uri = connParams_.ctx_->original_uri();
const char* start = strchr(const_cast<char*>(uri), '?');
if (start) {
return (start+1);
}
return nullptr;
}
const char *GetQueryString() override {
return queryString_;
}
const char *GetRelativePath() override {
// if (p_restMsg_)
// return p_restMsg_->url()->c_str();
return nullptr;
return connParams_.ctx_->uri().c_str();
}
const char *GetContent() override {
// if (p_restMsg_)
// return p_restMsg_->content()->c_str();
return nullptr;
return connParams_.ctx_->body().data();
}
void Reset() override {
// p_restMsg_ = nullptr;
}
private:
const char* GetMethod();
char* GetBuffer() { return buff_; }
private:
EvppConnParams connParams_;
const char* queryString_;
char buff_[nsMicroservice_Constants::MAX_URI_LENGTH];
};
class Microservice_IRestServerEvppImpl : public nsMicroservice_Iface::IRestServer , public nsMicroservice_Iface::IContainer {
public:
Microservice_IRestServerEvppImpl(cMicroservice_RestServerParams* p_param);
Microservice_IRestServerEvppImpl(const Microservice_IRestServerEvppImpl& orig) {}
......@@ -92,10 +118,11 @@ public:
void registerService(nsMicroservice_Iface::IServiceDiscovery* pc_ServiceDiscovery, std::string& id) override;
void run() override;
void start();
void stop() override;
virtual bool init() override;
void HandleRequest(EvppConnParams &connParams);
void SendNotImplemented(EvppConnParams &connParams);
private:
evpp::http::Server* p_server_;
......@@ -107,6 +134,20 @@ private:
// consts
static constexpr uint32_t SLEEP_INTERVAL = 1; //useconds
void SendGeneralError(EvppConnParams &connParams,
int respCode,
const char *error);
void HandleNewRequest(EvppConnParams &connParams,
std::string key,
std::string& apiContextPath);
MSRetStat ParseRequest(EvppConnParams &connParams,
cMicroservice_RequestContext& ctx,
std::string& apiContextPath);
void LogRequest(Microservice_IRequestRestEvppImpl* p_request);
void GetQueryParams(cMicroservice_RequestContext &ctx);
eCrudMethod GetCrudMethod(Microservice_IRequestRestEvppImpl* p_request);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment