Commit 565760ce authored by Giorgio Azzinnaro's avatar Giorgio Azzinnaro

testing packing and unpacking (python client)

`Db` gRPC service was improved to allow more flexibility,
`google.protobuf.Any` is used for packing/unpacking
parent 4bb73473
......@@ -7,24 +7,31 @@ option csharp_namespace = "ProdisDB.Protobuf";
option java_package = "com.prodisdb.protobuf";
option objc_class_prefix = "PDB";
message Empty {}
import "google/protobuf/any.proto";
message Serializable {
string type = 1;
bytes blob = 2;
service Db {
rpc Get (GetReq) returns (GetResp);
rpc Put (PutReq) returns (PutResp);
rpc Delete (DelReq) returns (DelResp);
}
message PrimaryKey {
string type = 1;
bytes uid = 2;
message GetReq {
}
service Db {
rpc Get (PrimaryKey) returns (Serializable);
message GetResp {
}
rpc Create (Serializable) returns (Empty);
message PutReq {
google.protobuf.Any serializable = 1;
}
message PutResp {
}
rpc Delete (PrimaryKey) returns (Empty);
message DelReq {
}
rpc Update (Serializable) returns (Empty);
message DelResp {
}
......@@ -18,34 +18,33 @@ prodisdb::server::Parser::Parser()
pool->FindFileByName("prodisdb/protobuf/options.proto");
pool->FindFileByName("test.proto");
}
prodisdb::server::Parser::~Parser()
{
}
void prodisdb::server::Parser::ParseMessage(const protobuf::Serializable& message)
void prodisdb::server::Parser::ParseMessage(const Any& serializable)
{
const Descriptor* definition = pool->FindMessageTypeByName(message.type());
std::string type = serializable.type_url();
const Descriptor* definition = pool->FindMessageTypeByName(type.substr(type.rfind('/')+1, string::npos));
const FieldDescriptor* fd;
// TODO Should check for multiple keys (might be supported later), for now throw error
for (int idx = 0; idx < definition->field_count(); idx++) {
fd = definition->field(idx);
std::cout
<< fd->full_name()
<< " is key: "
<< fd->options().GetExtension(prodisdb::protobuf::options).key()
<< std::endl;
if (fd->options().GetExtension(prodisdb::protobuf::options).key()) {
std::cout << fd->full_name() << " is key" << std::endl;
break;
}
}
std::cout << message.type() << std::endl;
Message* container = messageFactory.GetPrototype(definition)->New();
serializable.UnpackTo(container);
std::cout << container->GetReflection()->GetInt32(*container, fd) << std::endl;
}
prodisdb::server::Parser::ErrorCollector::ErrorCollector()
......
......@@ -5,6 +5,7 @@
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/dynamic_message.h>
#include <prodisdb/protobuf/db.pb.h>
#include <prodisdb/protobuf/options.pb.h>
......@@ -20,7 +21,7 @@ public:
Parser();
~Parser();
void ParseMessage(const protobuf::Serializable& message);
void ParseMessage(const Any& serializable);
private:
io::ZeroCopyInputStream* inputStream;
......@@ -29,6 +30,8 @@ private:
compiler::SourceTreeDescriptorDatabase* descriptorDb;
DescriptorPool* pool;
DynamicMessageFactory messageFactory;
class ErrorCollector : public compiler::MultiFileErrorCollector {
public:
ErrorCollector();
......
......@@ -30,19 +30,17 @@ void prodisdb::server::Server::HandleRpcs()
server->Wait();
}
grpc::Status prodisdb::server::Server::DbServiceImpl::Get(grpc::ServerContext* context, const prodisdb::protobuf::PrimaryKey* request, prodisdb::protobuf::Serializable* response)
grpc::Status prodisdb::server::Server::DbServiceImpl::Get(grpc::ServerContext* context, const prodisdb::protobuf::GetReq* request, prodisdb::protobuf::GetResp* response)
{
}
grpc::Status prodisdb::server::Server::DbServiceImpl::Create(grpc::ServerContext* context, const prodisdb::protobuf::Serializable* request, prodisdb::protobuf::Empty* response)
{
parser.ParseMessage(*request);
}
grpc::Status prodisdb::server::Server::DbServiceImpl::Delete(::grpc::ServerContext* context, const prodisdb::protobuf::PrimaryKey* request, prodisdb::protobuf::Empty* response)
grpc::Status prodisdb::server::Server::DbServiceImpl::Put(grpc::ServerContext* context, const prodisdb::protobuf::PutReq* request, prodisdb::protobuf::PutResp* response)
{
parser.ParseMessage(request->serializable());
return grpc::Status::OK;
}
grpc::Status prodisdb::server::Server::DbServiceImpl::Update(grpc::ServerContext* context, const prodisdb::protobuf::Serializable* request, prodisdb::protobuf::Empty* response)
grpc::Status prodisdb::server::Server::DbServiceImpl::Delete(grpc::ServerContext* context, const prodisdb::protobuf::DelReq* request, prodisdb::protobuf::DelResp* response)
{
}
......@@ -9,10 +9,6 @@
#include <prodisdb/protobuf/db.pb.h>
#include <prodisdb/protobuf/db.grpc.pb.h>
using prodisdb::protobuf::Empty;
using prodisdb::protobuf::Serializable;
using prodisdb::protobuf::PrimaryKey;
using prodisdb::protobuf::Db;
namespace prodisdb {
......@@ -33,14 +29,12 @@ private:
class DbServiceImpl : public Db::Service {
public:
grpc::Status Get(grpc::ServerContext* context, const prodisdb::protobuf::PrimaryKey* request, prodisdb::protobuf::Serializable* response) override;
grpc::Status Get(grpc::ServerContext* context, const prodisdb::protobuf::GetReq* request, prodisdb::protobuf::GetResp* response) override;
grpc::Status Create(grpc::ServerContext* context, const prodisdb::protobuf::Serializable* request, prodisdb::protobuf::Empty* response) override;
grpc::Status Put(grpc::ServerContext* context, const prodisdb::protobuf::PutReq* request, prodisdb::protobuf::PutResp* response) override;
grpc::Status Delete(::grpc::ServerContext* context, const prodisdb::protobuf::PrimaryKey* request, prodisdb::protobuf::Empty* response) override;
grpc::Status Delete(grpc::ServerContext* context, const prodisdb::protobuf::DelReq* request, prodisdb::protobuf::DelResp* response) override;
grpc::Status Update(grpc::ServerContext* context, const prodisdb::protobuf::Serializable* request, prodisdb::protobuf::Empty* response) override;
private:
Parser parser;
};
......
# Created by https://www.gitignore.io/api/python,virtualenv
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
### VirtualEnv ###
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
pip-selfcheck.json
# End of https://www.gitignore.io/api/python,virtualenv
syntax = "proto3";
package prodisdb.protobuf;
option go_package = "gitlab.com/prodisdb/protobuf/db";
option csharp_namespace = "ProdisDB.Protobuf";
option java_package = "com.prodisdb.protobuf";
option objc_class_prefix = "PDB";
import "google/protobuf/any.proto";
service Db {
rpc Get (GetReq) returns (GetResp);
rpc Put (PutReq) returns (PutResp);
rpc Delete (DelReq) returns (DelResp);
}
message GetReq {
}
message GetResp {
}
message PutReq {
google.protobuf.Any serializable = 1;
}
message PutResp {
}
message DelReq {
}
message DelResp {
}
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: prodisdb/protobuf/db.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
DESCRIPTOR = _descriptor.FileDescriptor(
name='prodisdb/protobuf/db.proto',
package='prodisdb.protobuf',
syntax='proto3',
serialized_pb=_b('\n\x1aprodisdb/protobuf/db.proto\x12\x11prodisdb.protobuf\x1a\x19google/protobuf/any.proto\"\x08\n\x06GetReq\"\t\n\x07GetResp\"4\n\x06PutReq\x12*\n\x0cserializable\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\"\t\n\x07PutResp\"\x08\n\x06\x44\x65lReq\"\t\n\x07\x44\x65lResp2\xc1\x01\n\x02\x44\x62\x12<\n\x03Get\x12\x19.prodisdb.protobuf.GetReq\x1a\x1a.prodisdb.protobuf.GetResp\x12<\n\x03Put\x12\x19.prodisdb.protobuf.PutReq\x1a\x1a.prodisdb.protobuf.PutResp\x12?\n\x06\x44\x65lete\x12\x19.prodisdb.protobuf.DelReq\x1a\x1a.prodisdb.protobuf.DelRespBR\n\x15\x63om.prodisdb.protobufZ\x1fgitlab.com/prodisdb/protobuf/db\xa2\x02\x03PDB\xaa\x02\x11ProdisDB.Protobufb\x06proto3')
,
dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,])
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
_GETREQ = _descriptor.Descriptor(
name='GetReq',
full_name='prodisdb.protobuf.GetReq',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=76,
serialized_end=84,
)
_GETRESP = _descriptor.Descriptor(
name='GetResp',
full_name='prodisdb.protobuf.GetResp',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=86,
serialized_end=95,
)
_PUTREQ = _descriptor.Descriptor(
name='PutReq',
full_name='prodisdb.protobuf.PutReq',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='serializable', full_name='prodisdb.protobuf.PutReq.serializable', index=0,
number=1, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=97,
serialized_end=149,
)
_PUTRESP = _descriptor.Descriptor(
name='PutResp',
full_name='prodisdb.protobuf.PutResp',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=151,
serialized_end=160,
)
_DELREQ = _descriptor.Descriptor(
name='DelReq',
full_name='prodisdb.protobuf.DelReq',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=162,
serialized_end=170,
)
_DELRESP = _descriptor.Descriptor(
name='DelResp',
full_name='prodisdb.protobuf.DelResp',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=172,
serialized_end=181,
)
_PUTREQ.fields_by_name['serializable'].message_type = google_dot_protobuf_dot_any__pb2._ANY
DESCRIPTOR.message_types_by_name['GetReq'] = _GETREQ
DESCRIPTOR.message_types_by_name['GetResp'] = _GETRESP
DESCRIPTOR.message_types_by_name['PutReq'] = _PUTREQ
DESCRIPTOR.message_types_by_name['PutResp'] = _PUTRESP
DESCRIPTOR.message_types_by_name['DelReq'] = _DELREQ
DESCRIPTOR.message_types_by_name['DelResp'] = _DELRESP
GetReq = _reflection.GeneratedProtocolMessageType('GetReq', (_message.Message,), dict(
DESCRIPTOR = _GETREQ,
__module__ = 'prodisdb.protobuf.db_pb2'
# @@protoc_insertion_point(class_scope:prodisdb.protobuf.GetReq)
))
_sym_db.RegisterMessage(GetReq)
GetResp = _reflection.GeneratedProtocolMessageType('GetResp', (_message.Message,), dict(
DESCRIPTOR = _GETRESP,
__module__ = 'prodisdb.protobuf.db_pb2'
# @@protoc_insertion_point(class_scope:prodisdb.protobuf.GetResp)
))
_sym_db.RegisterMessage(GetResp)
PutReq = _reflection.GeneratedProtocolMessageType('PutReq', (_message.Message,), dict(
DESCRIPTOR = _PUTREQ,
__module__ = 'prodisdb.protobuf.db_pb2'
# @@protoc_insertion_point(class_scope:prodisdb.protobuf.PutReq)
))
_sym_db.RegisterMessage(PutReq)
PutResp = _reflection.GeneratedProtocolMessageType('PutResp', (_message.Message,), dict(
DESCRIPTOR = _PUTRESP,
__module__ = 'prodisdb.protobuf.db_pb2'
# @@protoc_insertion_point(class_scope:prodisdb.protobuf.PutResp)
))
_sym_db.RegisterMessage(PutResp)
DelReq = _reflection.GeneratedProtocolMessageType('DelReq', (_message.Message,), dict(
DESCRIPTOR = _DELREQ,
__module__ = 'prodisdb.protobuf.db_pb2'
# @@protoc_insertion_point(class_scope:prodisdb.protobuf.DelReq)
))
_sym_db.RegisterMessage(DelReq)
DelResp = _reflection.GeneratedProtocolMessageType('DelResp', (_message.Message,), dict(
DESCRIPTOR = _DELRESP,
__module__ = 'prodisdb.protobuf.db_pb2'
# @@protoc_insertion_point(class_scope:prodisdb.protobuf.DelResp)
))
_sym_db.RegisterMessage(DelResp)
DESCRIPTOR.has_options = True
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\025com.prodisdb.protobufZ\037gitlab.com/prodisdb/protobuf/db\242\002\003PDB\252\002\021ProdisDB.Protobuf'))
try:
# THESE ELEMENTS WILL BE DEPRECATED.
# Please use the generated *_pb2_grpc.py files instead.
import grpc
from grpc.beta import implementations as beta_implementations
from grpc.beta import interfaces as beta_interfaces
from grpc.framework.common import cardinality
from grpc.framework.interfaces.face import utilities as face_utilities
class DbStub(object):
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.Get = channel.unary_unary(
'/prodisdb.protobuf.Db/Get',
request_serializer=GetReq.SerializeToString,
response_deserializer=GetResp.FromString,
)
self.Put = channel.unary_unary(
'/prodisdb.protobuf.Db/Put',
request_serializer=PutReq.SerializeToString,
response_deserializer=PutResp.FromString,
)
self.Delete = channel.unary_unary(
'/prodisdb.protobuf.Db/Delete',
request_serializer=DelReq.SerializeToString,
response_deserializer=DelResp.FromString,
)
class DbServicer(object):
def Get(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Put(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Delete(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_DbServicer_to_server(servicer, server):
rpc_method_handlers = {
'Get': grpc.unary_unary_rpc_method_handler(
servicer.Get,
request_deserializer=GetReq.FromString,
response_serializer=GetResp.SerializeToString,
),
'Put': grpc.unary_unary_rpc_method_handler(
servicer.Put,
request_deserializer=PutReq.FromString,
response_serializer=PutResp.SerializeToString,
),
'Delete': grpc.unary_unary_rpc_method_handler(
servicer.Delete,
request_deserializer=DelReq.FromString,
response_serializer=DelResp.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'prodisdb.protobuf.Db', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
class BetaDbServicer(object):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This class was generated
only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
def Get(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def Put(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def Delete(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
class BetaDbStub(object):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This class was generated
only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
def Get(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
Get.future = None
def Put(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
Put.future = None
def Delete(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
Delete.future = None
def beta_create_Db_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This function was
generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
request_deserializers = {
('prodisdb.protobuf.Db', 'Delete'): DelReq.FromString,
('prodisdb.protobuf.Db', 'Get'): GetReq.FromString,
('prodisdb.protobuf.Db', 'Put'): PutReq.FromString,
}
response_serializers = {
('prodisdb.protobuf.Db', 'Delete'): DelResp.SerializeToString,
('prodisdb.protobuf.Db', 'Get'): GetResp.SerializeToString,
('prodisdb.protobuf.Db', 'Put'): PutResp.SerializeToString,
}
method_implementations = {
('prodisdb.protobuf.Db', 'Delete'): face_utilities.unary_unary_inline(servicer.Delete),
('prodisdb.protobuf.Db', 'Get'): face_utilities.unary_unary_inline(servicer.Get),
('prodisdb.protobuf.Db', 'Put'): face_utilities.unary_unary_inline(servicer.Put),
}
server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
return beta_implementations.server(method_implementations, options=server_options)
def beta_create_Db_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This function was
generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
request_serializers = {
('prodisdb.protobuf.Db', 'Delete'): DelReq.SerializeToString,
('prodisdb.protobuf.Db', 'Get'): GetReq.SerializeToString,
('prodisdb.protobuf.Db', 'Put'): PutReq.SerializeToString,
}
response_deserializers = {
('prodisdb.protobuf.Db', 'Delete'): DelResp.FromString,
('prodisdb.protobuf.Db', 'Get'): GetResp.FromString,
('prodisdb.protobuf.Db', 'Put'): PutResp.FromString,
}
cardinalities = {
'Delete': cardinality.Cardinality.UNARY_UNARY,
'Get': cardinality.Cardinality.UNARY_UNARY,
'Put': cardinality.Cardinality.UNARY_UNARY,
}
stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
return beta_implementations.dynamic_stub(channel, 'prodisdb.protobuf.Db', cardinalities, options=stub_options)
except ImportError:
pass