mirror of https://gitee.com/bigwinds/arangodb
add translator to VelocyPackHelper and headerOption to Vpp Protocol
This commit is contained in:
parent
86f887db92
commit
8f5e6f65d6
|
@ -31,6 +31,7 @@
|
|||
#include "GeneralServer/GeneralServerFeature.h"
|
||||
#include "GeneralServer/RestHandler.h"
|
||||
#include "GeneralServer/RestHandlerFactory.h"
|
||||
#include "Rest/CommonDefines.h"
|
||||
#include "Logger/LoggerFeature.h"
|
||||
#include "Scheduler/Scheduler.h"
|
||||
#include "Scheduler/SchedulerFeature.h"
|
||||
|
@ -160,12 +161,15 @@ std::unique_ptr<basics::StringBuffer> createChunkForNetworkSingle(
|
|||
VppCommTask::VppCommTask(GeneralServer* server, TRI_socket_t sock,
|
||||
ConnectionInfo&& info, double timeout)
|
||||
: Task("VppCommTask"),
|
||||
GeneralCommTask(server, sock, std::move(info), timeout) {
|
||||
GeneralCommTask(server, sock, std::move(info), timeout),
|
||||
_headerOptions(VPackOptions::Defaults) {
|
||||
_protocol = "vpp";
|
||||
_readBuffer->reserve(
|
||||
_bufferLength); // ATTENTION <- this is required so we do not
|
||||
// loose information during a resize
|
||||
// connectionStatisticsAgentSetVpp();
|
||||
_headerOptions.attributeTranslator =
|
||||
basics::VelocyPackHelper::getHeaderTranslator();
|
||||
}
|
||||
|
||||
void VppCommTask::addResponse(VppResponse* response) {
|
||||
|
@ -397,7 +401,7 @@ bool VppCommTask::processRead() {
|
|||
if (doExecute) {
|
||||
VPackSlice header = message.header();
|
||||
LOG_TOPIC(DEBUG, Logger::COMMUNICATION)
|
||||
<< "got request:" << header.toJson();
|
||||
<< "got request:" << header.toJson(&_headerOptions);
|
||||
int type = meta::underlyingValue(GeneralRequest::RequestType::ILLEGAL);
|
||||
try {
|
||||
type = header.get("type").getInt();
|
||||
|
@ -412,6 +416,7 @@ bool VppCommTask::processRead() {
|
|||
// the handler will take ownersip of this pointer
|
||||
std::unique_ptr<VppRequest> request(new VppRequest(
|
||||
_connectionInfo, std::move(message), chunkHeader._messageID));
|
||||
request->setHeaderOptions(&_headerOptions);
|
||||
GeneralServerFeature::HANDLER_FACTORY->setRequestContext(request.get());
|
||||
// make sure we have a database
|
||||
if (request->requestContext() == nullptr) {
|
||||
|
@ -426,6 +431,7 @@ bool VppCommTask::processRead() {
|
|||
std::unique_ptr<VppResponse> response(
|
||||
new VppResponse(GeneralResponse::ResponseCode::SERVER_ERROR,
|
||||
chunkHeader._messageID));
|
||||
response->setHeaderOptions(&_headerOptions);
|
||||
executeRequest(std::move(request), std::move(response));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ class VppCommTask : public GeneralCommTask {
|
|||
// will be cleaned
|
||||
};
|
||||
ProcessReadVariables _processReadVariables;
|
||||
velocypack::Options _headerOptions;
|
||||
|
||||
struct ChunkHeader {
|
||||
std::size_t _headerLength;
|
||||
|
|
|
@ -49,6 +49,7 @@ unsigned long long XXH64(const void* input, size_t length,
|
|||
using VelocyPackHelper = arangodb::basics::VelocyPackHelper;
|
||||
|
||||
static std::unique_ptr<VPackAttributeTranslator> Translator;
|
||||
static std::unique_ptr<VPackAttributeTranslator> HeaderTranslator;
|
||||
static std::unique_ptr<VPackAttributeExcludeHandler> ExcludeHandler;
|
||||
|
||||
// attribute exclude handler for skipping over system attributes
|
||||
|
@ -130,6 +131,17 @@ void VelocyPackHelper::initialize() {
|
|||
TRI_ASSERT(VPackSlice(Translator->translate(ToAttribute - AttributeBase))
|
||||
.copyString() == StaticStrings::ToString);
|
||||
|
||||
HeaderTranslator.reset(new VPackAttributeTranslator);
|
||||
HeaderTranslator->add("version", 6);
|
||||
HeaderTranslator->add("type", 7);
|
||||
HeaderTranslator->add("database", 8);
|
||||
HeaderTranslator->add("requestType", 9);
|
||||
HeaderTranslator->add("request", 0);
|
||||
HeaderTranslator->add("parameter", -1);
|
||||
HeaderTranslator->add("meta", -2);
|
||||
HeaderTranslator->add("responseCode", -3);
|
||||
HeaderTranslator->seal();
|
||||
|
||||
// initialize exclude handler for system attributes
|
||||
ExcludeHandler.reset(new SystemAttributeExcludeHandler);
|
||||
}
|
||||
|
@ -159,6 +171,11 @@ arangodb::velocypack::AttributeTranslator* VelocyPackHelper::getTranslator() {
|
|||
return Translator.get();
|
||||
}
|
||||
|
||||
arangodb::velocypack::AttributeTranslator*
|
||||
VelocyPackHelper::getHeaderTranslator() {
|
||||
return HeaderTranslator.get();
|
||||
}
|
||||
|
||||
bool VelocyPackHelper::AttributeSorterUTF8::operator()(
|
||||
std::string const& l, std::string const& r) const {
|
||||
// use UTF-8-based comparison of attribute names
|
||||
|
|
|
@ -57,6 +57,7 @@ class VelocyPackHelper {
|
|||
|
||||
static arangodb::velocypack::AttributeExcludeHandler* getExcludeHandler();
|
||||
static arangodb::velocypack::AttributeTranslator* getTranslator();
|
||||
static arangodb::velocypack::AttributeTranslator* getHeaderTranslator();
|
||||
|
||||
struct VPackHash {
|
||||
size_t operator()(arangodb::velocypack::Slice const&) const;
|
||||
|
|
|
@ -26,97 +26,97 @@
|
|||
|
||||
namespace arangodb {
|
||||
|
||||
enum class ContentType {
|
||||
CUSTOM, // use Content-Type from _headers
|
||||
JSON, // application/json
|
||||
VPACK, // application/x-velocypack
|
||||
TEXT, // text/plain
|
||||
HTML, // text/html
|
||||
DUMP, // application/x-arango-dump
|
||||
UNSET
|
||||
};
|
||||
|
||||
enum class ProtocolVersion { HTTP_1_0, HTTP_1_1, VPP_1_0, UNKNOWN };
|
||||
|
||||
enum ConnectionType {
|
||||
CONNECTION_NONE,
|
||||
CONNECTION_KEEP_ALIVE,
|
||||
CONNECTION_CLOSE
|
||||
};
|
||||
// VSTREAM_CRED: This method is used for sending Authentication
|
||||
// request,i.e; username and password.
|
||||
// enum class ContentType {
|
||||
// CUSTOM, // use Content-Type from _headers
|
||||
// JSON, // application/json
|
||||
// VPACK, // application/x-velocypack
|
||||
// TEXT, // text/plain
|
||||
// HTML, // text/html
|
||||
// DUMP, // application/x-arango-dump
|
||||
// UNSET
|
||||
// };
|
||||
//
|
||||
// VSTREAM_REGISTER: This Method is used for registering event of
|
||||
// some kind
|
||||
// enum class ProtocolVersion { HTTP_1_0, HTTP_1_1, VPP_1_0, UNKNOWN };
|
||||
//
|
||||
// VSTREAM_STATUS: Returns STATUS code and message for a given
|
||||
// request
|
||||
enum class RequestType {
|
||||
DELETE_REQ = 0, // windows redefines DELETE
|
||||
GET,
|
||||
HEAD,
|
||||
OPTIONS,
|
||||
POST,
|
||||
PUT,
|
||||
PATCH,
|
||||
VSTREAM_CRED,
|
||||
VSTREAM_REGISTER,
|
||||
VSTREAM_STATUS,
|
||||
ILLEGAL // must be last
|
||||
};
|
||||
|
||||
enum class ResponseCode {
|
||||
CONTINUE = 100,
|
||||
SWITCHING_PROTOCOLS = 101,
|
||||
PROCESSING = 102,
|
||||
|
||||
OK = 200,
|
||||
CREATED = 201,
|
||||
ACCEPTED = 202,
|
||||
PARTIAL = 203,
|
||||
NO_CONTENT = 204,
|
||||
RESET_CONTENT = 205,
|
||||
PARTIAL_CONTENT = 206,
|
||||
|
||||
MOVED_PERMANENTLY = 301,
|
||||
FOUND = 302,
|
||||
SEE_OTHER = 303,
|
||||
NOT_MODIFIED = 304,
|
||||
TEMPORARY_REDIRECT = 307,
|
||||
PERMANENT_REDIRECT = 308,
|
||||
|
||||
BAD = 400,
|
||||
UNAUTHORIZED = 401,
|
||||
PAYMENT_REQUIRED = 402,
|
||||
FORBIDDEN = 403,
|
||||
NOT_FOUND = 404,
|
||||
METHOD_NOT_ALLOWED = 405,
|
||||
NOT_ACCEPTABLE = 406,
|
||||
REQUEST_TIMEOUT = 408,
|
||||
CONFLICT = 409,
|
||||
GONE = 410,
|
||||
LENGTH_REQUIRED = 411,
|
||||
PRECONDITION_FAILED = 412,
|
||||
REQUEST_ENTITY_TOO_LARGE = 413,
|
||||
REQUEST_URI_TOO_LONG = 414,
|
||||
UNSUPPORTED_MEDIA_TYPE = 415,
|
||||
REQUESTED_RANGE_NOT_SATISFIABLE = 416,
|
||||
EXPECTATION_FAILED = 417,
|
||||
I_AM_A_TEAPOT = 418,
|
||||
UNPROCESSABLE_ENTITY = 422,
|
||||
LOCKED = 423,
|
||||
PRECONDITION_REQUIRED = 428,
|
||||
TOO_MANY_REQUESTS = 429,
|
||||
REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
|
||||
UNAVAILABLE_FOR_LEGAL_REASONS = 451,
|
||||
|
||||
SERVER_ERROR = 500,
|
||||
NOT_IMPLEMENTED = 501,
|
||||
BAD_GATEWAY = 502,
|
||||
SERVICE_UNAVAILABLE = 503,
|
||||
HTTP_VERSION_NOT_SUPPORTED = 505,
|
||||
BANDWIDTH_LIMIT_EXCEEDED = 509,
|
||||
NOT_EXTENDED = 510
|
||||
};
|
||||
// enum ConnectionType {
|
||||
// CONNECTION_NONE,
|
||||
// CONNECTION_KEEP_ALIVE,
|
||||
// CONNECTION_CLOSE
|
||||
// };
|
||||
// // VSTREAM_CRED: This method is used for sending Authentication
|
||||
// // request,i.e; username and password.
|
||||
// //
|
||||
// // VSTREAM_REGISTER: This Method is used for registering event of
|
||||
// // some kind
|
||||
// //
|
||||
// // VSTREAM_STATUS: Returns STATUS code and message for a given
|
||||
// // request
|
||||
// enum class RequestType {
|
||||
// DELETE_REQ = 0, // windows redefines DELETE
|
||||
// GET,
|
||||
// HEAD,
|
||||
// OPTIONS,
|
||||
// POST,
|
||||
// PUT,
|
||||
// PATCH,
|
||||
// VSTREAM_CRED,
|
||||
// VSTREAM_REGISTER,
|
||||
// VSTREAM_STATUS,
|
||||
// ILLEGAL // must be last
|
||||
// };
|
||||
//
|
||||
// enum class ResponseCode {
|
||||
// CONTINUE = 100,
|
||||
// SWITCHING_PROTOCOLS = 101,
|
||||
// PROCESSING = 102,
|
||||
//
|
||||
// OK = 200,
|
||||
// CREATED = 201,
|
||||
// ACCEPTED = 202,
|
||||
// PARTIAL = 203,
|
||||
// NO_CONTENT = 204,
|
||||
// RESET_CONTENT = 205,
|
||||
// PARTIAL_CONTENT = 206,
|
||||
//
|
||||
// MOVED_PERMANENTLY = 301,
|
||||
// FOUND = 302,
|
||||
// SEE_OTHER = 303,
|
||||
// NOT_MODIFIED = 304,
|
||||
// TEMPORARY_REDIRECT = 307,
|
||||
// PERMANENT_REDIRECT = 308,
|
||||
//
|
||||
// BAD = 400,
|
||||
// UNAUTHORIZED = 401,
|
||||
// PAYMENT_REQUIRED = 402,
|
||||
// FORBIDDEN = 403,
|
||||
// NOT_FOUND = 404,
|
||||
// METHOD_NOT_ALLOWED = 405,
|
||||
// NOT_ACCEPTABLE = 406,
|
||||
// REQUEST_TIMEOUT = 408,
|
||||
// CONFLICT = 409,
|
||||
// GONE = 410,
|
||||
// LENGTH_REQUIRED = 411,
|
||||
// PRECONDITION_FAILED = 412,
|
||||
// REQUEST_ENTITY_TOO_LARGE = 413,
|
||||
// REQUEST_URI_TOO_LONG = 414,
|
||||
// UNSUPPORTED_MEDIA_TYPE = 415,
|
||||
// REQUESTED_RANGE_NOT_SATISFIABLE = 416,
|
||||
// EXPECTATION_FAILED = 417,
|
||||
// I_AM_A_TEAPOT = 418,
|
||||
// UNPROCESSABLE_ENTITY = 422,
|
||||
// LOCKED = 423,
|
||||
// PRECONDITION_REQUIRED = 428,
|
||||
// TOO_MANY_REQUESTS = 429,
|
||||
// REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
|
||||
// UNAVAILABLE_FOR_LEGAL_REASONS = 451,
|
||||
//
|
||||
// SERVER_ERROR = 500,
|
||||
// NOT_IMPLEMENTED = 501,
|
||||
// BAD_GATEWAY = 502,
|
||||
// SERVICE_UNAVAILABLE = 503,
|
||||
// HTTP_VERSION_NOT_SUPPORTED = 505,
|
||||
// BANDWIDTH_LIMIT_EXCEEDED = 509,
|
||||
// NOT_EXTENDED = 510
|
||||
// };
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -64,7 +64,8 @@ VppRequest::VppRequest(ConnectionInfo const& connectionInfo,
|
|||
: GeneralRequest(connectionInfo),
|
||||
_message(std::move(message)),
|
||||
_headers(nullptr),
|
||||
_messageId(messageId) {
|
||||
_messageId(messageId),
|
||||
_headerOptions(nullptr) {
|
||||
_protocol = "vpp";
|
||||
_contentType = ContentType::VPACK;
|
||||
_contentTypeResponse = ContentType::VPACK;
|
||||
|
|
|
@ -77,6 +77,8 @@ class VppRequest : public GeneralRequest {
|
|||
return arangodb::Endpoint::TransportType::VPP;
|
||||
};
|
||||
|
||||
void setHeaderOptions(VPackOptions* options) { _headerOptions = options; }
|
||||
|
||||
std::unordered_map<std::string, std::string> const& headers() const override;
|
||||
// get value from headers map. The key must be lowercase.
|
||||
std::string const& header(std::string const& key) const override;
|
||||
|
@ -102,6 +104,7 @@ class VppRequest : public GeneralRequest {
|
|||
std::unordered_map<std::string, std::vector<std::string>> _arrayValues;
|
||||
uint64_t _messageId;
|
||||
const std::unordered_map<std::string, std::string> _cookies; // TODO remove
|
||||
VPackOptions* _headerOptions;
|
||||
|
||||
void parseHeaderInformation();
|
||||
};
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Dumper.h>
|
||||
#include <velocypack/Options.h>
|
||||
#include <velocypack/AttributeTranslator.h>
|
||||
#include <velocypack/Buffer.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include "Basics/Exceptions.h"
|
||||
|
@ -38,13 +40,19 @@
|
|||
#include "Meta/conversion.h"
|
||||
#include "Rest/VppRequest.h"
|
||||
|
||||
#include "CommonDefines.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
|
||||
bool VppResponse::HIDE_PRODUCT_HEADER = false;
|
||||
|
||||
VppResponse::VppResponse(ResponseCode code, uint64_t id)
|
||||
: GeneralResponse(code), _header(nullptr), _payload(), _messageId(id) {
|
||||
: GeneralResponse(code),
|
||||
_header(nullptr),
|
||||
_payload(),
|
||||
_messageId(id),
|
||||
_headerOptions(nullptr) {
|
||||
_contentType = ContentType::VPACK;
|
||||
_connectionType = CONNECTION_KEEP_ALIVE;
|
||||
}
|
||||
|
@ -69,14 +77,20 @@ void VppResponse::setPayload(arangodb::velocypack::Slice const& slice,
|
|||
VPackMessageNoOwnBuffer VppResponse::prepareForNetwork() {
|
||||
// initalize builder with vpackbuffer. then we do not need to
|
||||
// steal the header and can avoid the shared pointer
|
||||
VPackBuilder builder;
|
||||
|
||||
// VPackBuffer<uint8_t> buffer;
|
||||
// VPackBuilder builder(buffer);
|
||||
VPackBuilder builder(_headerOptions);
|
||||
builder.openObject();
|
||||
builder.add("version", VPackValue(int(1)));
|
||||
builder.add("type", VPackValue(int(1))); // 2 == response
|
||||
builder.add("type", VPackValue(int(2))); // 2 == response
|
||||
builder.add(
|
||||
"responseCode",
|
||||
VPackValue(static_cast<int>(meta::underlyingValue(_responseCode))));
|
||||
builder.close();
|
||||
|
||||
// options.Defaults.attributeTranslator = nullptr;
|
||||
|
||||
_header = builder.steal();
|
||||
return VPackMessageNoOwnBuffer(VPackSlice(_header->data()),
|
||||
VPackSlice(_payload.data()), _messageId,
|
||||
|
|
|
@ -57,6 +57,8 @@ class VppResponse : public GeneralResponse {
|
|||
return arangodb::Endpoint::TransportType::VPP;
|
||||
};
|
||||
|
||||
void setHeaderOptions(VPackOptions* options) { _headerOptions = options; }
|
||||
|
||||
VPackMessageNoOwnBuffer prepareForNetwork();
|
||||
|
||||
private:
|
||||
|
@ -67,6 +69,7 @@ class VppResponse : public GeneralResponse {
|
|||
VPackBuffer<uint8_t> _payload;
|
||||
uint64_t _messageId;
|
||||
bool _generateBody; // this must be true if payload should be send
|
||||
VPackOptions* _headerOptions;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue