blob: 41d603deb073bd933d6c959fc22013d69a5f1851 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
try:
import ujson as json
except ImportError:
import json
from gremlin_python.structure.io import graphsonV2d0
from gremlin_python.structure.io import graphsonV3d0
__author__ = 'David M. Brown (davebshow@gmail.com)'
class Processor:
"""Base class for OpProcessor serialization system."""
def __init__(self, writer):
self._graphson_writer = writer
def get_op_args(self, op, args):
op_method = getattr(self, op, None)
if not op_method:
raise Exception("Processor does not support op: {}".format(op))
return op_method(args)
class Standard(Processor):
def authentication(self, args):
return args
def eval(self, args):
return args
class Session(Processor):
def authentication(self, args):
return args
def eval(self, args):
return args
def close(self, args):
return args
class Traversal(Processor):
def authentication(self, args):
return args
def bytecode(self, args):
gremlin = args['gremlin']
args['gremlin'] = self._graphson_writer.toDict(gremlin)
aliases = args.get('aliases', '')
if not aliases:
aliases = {'g': 'g'}
args['aliases'] = aliases
return args
def close(self, args):
return self.keys(args)
def gather(self, args):
side_effect = args['sideEffect']
args['sideEffect'] = {'@type': 'g:UUID', '@value': side_effect}
aliases = args.get('aliases', '')
if not aliases:
aliases = {'g': 'g'}
args['aliases'] = aliases
return args
def keys(self, args):
side_effect = args['sideEffect']
args['sideEffect'] = {'@type': 'g:UUID', '@value': side_effect}
return args
class GraphSONMessageSerializer(object):
"""
Message serializer for GraphSON. Allow users to pass custom reader,
writer, and version kwargs for custom serialization. Otherwise,
use current GraphSON version as default.
"""
# KEEP TRACK OF CURRENT DEFAULTS
DEFAULT_READER_CLASS = graphsonV3d0.GraphSONReader
DEFAULT_WRITER_CLASS = graphsonV3d0.GraphSONWriter
DEFAULT_VERSION = b"application/vnd.gremlin-v3.0+json"
def __init__(self, reader=None, writer=None, version=None):
if not version:
version = self.DEFAULT_VERSION
self._version = version
if not reader:
reader = self.DEFAULT_READER_CLASS()
self._graphson_reader = reader
if not writer:
writer = self.DEFAULT_WRITER_CLASS()
self.standard = Standard(writer)
self.traversal = Traversal(writer)
self.session = Session(writer)
@property
def version(self):
"""Read only property"""
return self._version
def get_processor(self, processor):
processor = getattr(self, processor, None)
if not processor:
raise Exception("Unknown processor")
return processor
def serialize_message(self, request_id, request_message):
processor = request_message.processor
op = request_message.op
args = request_message.args
if not processor:
processor_obj = self.get_processor('standard')
else:
processor_obj = self.get_processor(processor)
args = processor_obj.get_op_args(op, args)
message = self.build_message(request_id, processor, op, args)
return message
def build_message(self, request_id, processor, op, args):
message = {
'requestId': {'@type': 'g:UUID', '@value': request_id},
'processor': processor,
'op': op,
'args': args
}
return self.finalize_message(message, b"\x21", self.version)
def finalize_message(self, message, mime_len, mime_type):
message = json.dumps(message)
message = b''.join([mime_len, mime_type, message.encode('utf-8')])
return message
def deserialize_message(self, message):
return self._graphson_reader.toObject(message)
class GraphSONSerializersV2d0(GraphSONMessageSerializer):
"""Message serializer for GraphSON 2.0"""
def __init__(self):
reader = graphsonV2d0.GraphSONReader()
writer = graphsonV2d0.GraphSONWriter()
version = b"application/vnd.gremlin-v2.0+json"
super(GraphSONSerializersV2d0, self).__init__(reader, writer, version)
class GraphSONSerializersV3d0(GraphSONMessageSerializer):
"""Message serializer for GraphSON 3.0"""
def __init__(self):
reader = graphsonV3d0.GraphSONReader()
writer = graphsonV3d0.GraphSONWriter()
version = b"application/vnd.gremlin-v3.0+json"
super(GraphSONSerializersV3d0, self).__init__(reader, writer, version)