def create_new_portable_instance(self, factory_id, class_id): try: portable_factory = self._portable_factories[factory_id] except KeyError: raise HazelcastSerializationError("Could not find portable_factory for factory-id: {}".format(factory_id)) portable = portable_factory[class_id] if portable is None: raise HazelcastSerializationError("Could not create Portable for class-id: {}".format(class_id)) return portable()
def _check_portable_attributes(field_def, portable): if field_def.factory_id != portable.get_factory_id(): raise HazelcastSerializationError( "Wrong Portable type! Generic portable types are not supported! " "Expected factory-id: {0}, Actual factory-id: {1}".format( field_def.factory_id, portable.get_factory_id())) if field_def.class_id != portable.get_class_id(): raise HazelcastSerializationError( "Wrong Portable type! Generic portable types are not supported! " "Expected class-id: {0}, Actual class-id: {1}".format( field_def.class_id, portable.get_class_id()))
def _read_position(self, field_name, field_type): if self._raw: raise HazelcastSerializationError( "Cannot read Portable fields after get_raw_data_input() is called!" ) fd = self._class_def.get_field(field_name) if fd is None: return self._read_nested_position(field_name, field_type) if fd.field_type != field_type: raise HazelcastSerializationError("Not a '{}' field: {}".format( field_type, field_name)) return self._read_position_by_field_def(fd)
def to_object(self, data): """ Deserialize input data :param data: serialized input Data object :return: Deserialized object """ if not isinstance(data, Data): return data if is_null_data(data): return None inp = self._create_data_input(data) try: type_id = data.get_type() serializer = self._registry.serializer_by_type_id(type_id) if serializer is None: if self._active: raise HazelcastSerializationError( "Missing Serializer for type-id:{}".format(type_id)) else: raise HazelcastInstanceNotActiveError() return serializer.read(inp) except Exception as e: handle_exception(e) finally: pass
def read_portable_array(self, field_name): current_pos = self._in.position() try: fd = self._class_def.get_field(field_name) if fd is None: raise self._create_unknown_field_exception(field_name) if fd.field_type != FieldType.PORTABLE_ARRAY: raise HazelcastSerializationError( "Not a portable array field: {}".format(field_name)) pos = self._read_position_by_field_def(fd) self._in.set_position(pos) length = self._in.read_int() factory_id = self._in.read_int() class_id = self._in.read_int() if length == bits.NULL_ARRAY_LENGTH: return None _check_factory_and_class(fd, factory_id, class_id) portables = [None] * length if length > 0: offset = self._in.position() for i in xrange(0, length): start = self._in.read_int(offset + i * bits.INT_SIZE_IN_BYTES) self._in.set_position(start) portables[i] = self._portable_serializer.read_internal( self._in, factory_id, class_id) return portables finally: self._in.set_position(current_pos)
def _read_nested_position(self, field_name, field_type): field_names = field_name.split(".") if len(field_names) > 1: fd = None _reader = self for i in xrange(0, len(field_names)): fd = _reader._class_def.get_field(field_names[i]) if fd is None: break if i == len(field_names) - 1: break pos = _reader.read_position(fd) self._in.set_position(pos) is_none = self._in.read_boolean() if is_none: raise ValueError("Parent field is null: ".format( field_names[i])) _reader = self._portable_serializer.create_reader(self._in) if fd is None: raise self._create_unknown_field_exception(field_name) if fd.field_type != field_type: raise HazelcastSerializationError( "Not a '{}' field: {}".format(field_type, field_name)) return _reader.read_position(fd) raise self._create_unknown_field_exception(field_name)
def read_portable(self, field_name): cur_pos = self._in.position() try: fd = self._class_def.get_field(field_name) if fd is None: raise self._create_unknown_field_exception(field_name) if fd.field_type != FieldType.PORTABLE: raise HazelcastSerializationError( "Not a Portable field: {}".format(field_name)) pos = self._read_position_by_field_def(fd) self._in.set_position(pos) is_none = self._in.read_boolean() factory_id = self._in.read_int() class_id = self._in.read_int() _check_factory_and_class(fd, factory_id, class_id) if is_none: return None return self._portable_serializer.read_internal( self._in, factory_id, class_id) finally: self._in.set_position(cur_pos)
def write_null_portable(self, field_name, factory_id, class_id): nested_class_def = self.portable_context.lookup_class_definition( factory_id, class_id, self.portable_context.portable_version) if nested_class_def is None: raise HazelcastSerializationError( "Cannot write None portable without explicitly registering class definition!" ) self._builder.add_portable_field(field_name, nested_class_def)
def register_class_definitions(self, class_definitions, check_error): class_defs = dict() for cd in class_definitions: if cd in class_defs: raise HazelcastSerializationError("Duplicate registration found for class-id:{}".format(cd.class_id)) class_defs[cd.class_id] = cd for cd in class_definitions: self.register_class_definition(cd, class_defs, check_error)
def handle_exception(e, traceback): if isinstance(e, MemoryError): # TODO print("OUT OF MEMORY") raise e, None, traceback elif isinstance(e, HazelcastSerializationError): raise e, None, traceback else: raise HazelcastSerializationError(e.message), None, traceback
def write_object(self, out, obj): if isinstance(obj, Data): raise HazelcastSerializationError("Cannot write a Data instance! Use write_data(out, data) instead.") try: serializer = self._registry.serializer_for(obj) out.write_int(serializer.get_type_id()) serializer.write(out, obj) except: handle_exception(sys.exc_info()[1], sys.exc_info()[2])
def _set_position(self, field_name, field_type): if self._raw: raise HazelcastSerializationError( "Cannot write Portable fields after get_raw_data_output() is called!" ) fd = self._class_def.get_field(field_name) if fd is None: raise HazelcastSerializationError( "Invalid field name:'{0}' for ClassDefinition(id:{1} , version:{2} )" .format(field_name, self._class_def.class_id, self._class_def.version)) if field_name not in self._writen_fields: self._write_field_def(fd.index, field_name, field_type) self._writen_fields.add(field_name) else: raise HazelcastSerializationError( "Field '{0}' has already been written!".format(field_name)) return fd
def handle_exception(e, traceback): if isinstance(e, MemoryError): # TODO six.print_("OUT OF MEMORY") six.reraise(MemoryError, e, traceback) elif isinstance(e, HazelcastSerializationError): six.reraise(HazelcastSerializationError, e, traceback) else: six.reraise(HazelcastSerializationError, HazelcastSerializationError(e.args[0]), traceback)
def handle_exception(e): traceback.print_exc(file=sys.stderr) if isinstance(e, MemoryError): # TODO print("OUT OF MEMORY") raise e elif isinstance(e, HazelcastSerializationError): raise e else: raise HazelcastSerializationError(e.message)
def read_object(self, inp): try: type_id = inp.read_int() serializer = self._registry.serializer_by_type_id(type_id) if serializer is None: if self._active: raise HazelcastSerializationError("Missing Serializer for type-id:{}".format(type_id)) else: raise HazelcastInstanceNotActiveError() return serializer.read(inp) except: handle_exception(sys.exc_info()[1], sys.exc_info()[2])
def register_class_definition(self, cd, class_defs, check_error): field_names = cd.get_field_names() for field_name in field_names: fd = cd.get_field(field_name) if fd.field_type == FieldType.PORTABLE or fd.field_type == FieldType.PORTABLE_ARRAY: nested_cd = class_defs.get(fd.class_id, None) if nested_cd is not None: self.register_class_definition(nested_cd, class_defs, check_error) self._portable_context.register_class_definition(nested_cd) elif check_error: raise HazelcastSerializationError( "Could not find registered ClassDefinition for class-id:{}".format(fd.class_id)) self._portable_context.register_class_definition(cd)
def register(self, class_def): with self._lock: if class_def is None: return None if class_def.factory_id != self._factory_id: raise HazelcastSerializationError( "Invalid factory-id! {} -> {}".format( self._factory_id, class_def)) if isinstance(class_def, ClassDefinition): class_def.set_version_if_not_set(self._portable_version) combined_key = (class_def.class_id, class_def.version) if combined_key not in self._versioned_definitions: self._versioned_definitions[combined_key] = class_def return class_def current_class_def = self._versioned_definitions[combined_key] if isinstance(current_class_def, ClassDefinition): if current_class_def != class_def: raise HazelcastSerializationError( "Incompatible class-definitions with same class-id: {} vs {}" .format(class_def, current_class_def)) return current_class_def self._versioned_definitions[combined_key] = class_def return class_def
def write_portable(self, field_name, portable): if portable is None: raise HazelcastSerializationError( "Cannot write None portable without explicitly registering class definition!" ) version = util.get_portable_version( portable, self.portable_context.portable_version) factory_id = portable.get_factory_id() class_id = portable.get_class_id() nested_builder = ClassDefinitionBuilder(factory_id, class_id, version) nested_class_def = self._create_nested_class_def( portable, nested_builder) self._builder.add_portable_field(field_name, nested_class_def)
def __init__(self, portable_serializer, data_input, class_def): self._portable_serializer = portable_serializer self._in = data_input self._class_def = class_def try: # final position after portable is read self._final_pos = data_input.read_int() # field count field_count = data_input.read_int() except Exception: raise HazelcastSerializationError() if field_count != class_def.get_field_count(): raise ValueError( "Field count({}) in stream does not match! {}".format( field_count, class_def)) self._offset = data_input.position() self._raw = False
def write_portable_array(self, field_name, values): if values is None or len(values) == 0: raise HazelcastSerializationError( "Cannot write None portable without explicitly registering class definition!" ) portable = values[0] _class_id = portable.get_class_id() for i in xrange(1, len(values)): if values[i].get_class_id() != _class_id: raise ValueError( "Detected different class-ids in portable array!") version = util.get_portable_version( portable, self.portable_context.portable_version) nested_builder = ClassDefinitionBuilder(portable.get_factory_id(), portable.get_class_id(), version) nested_class_def = self._create_nested_class_def( portable, nested_builder) self._builder.add_portable_array_field(field_name, nested_class_def)
def serializer_for(self, obj): """ Searches for a serializer for the provided object Serializers will be searched in this order; 1-NULL serializer 2-Default serializers, like primitives, arrays, string and some default types 3-Custom registered types by user 4-Global serializer if registered by user 4-pickle serialization as a fallback :param obj: input object :return: Serializer """ # 1-NULL serializer if obj is None: return self._null_serializer obj_type = type(obj) # 2-Default serializers, Dataserializable, Portable, primitives, arrays, String and some helper types(BigInteger etc) serializer = self.lookup_default_serializer(obj_type, obj) # 3-Custom registered types by user if serializer is None: serializer = self.lookup_custom_serializer(obj_type) # 5-Global serializer if registered by user if serializer is None: serializer = self.lookup_global_serializer(obj_type) # 4 Internal serializer if serializer is None: serializer = self.lookup_python_serializer(obj_type) if serializer is None: if self._active: raise HazelcastSerializationError( "There is no suitable serializer for:" + str(obj_type)) else: raise HazelcastInstanceNotActiveError() return serializer
def _create_unknown_field_exception(self, field_name): return HazelcastSerializationError( "Unknown field name: '{}' for ClassDefinition[ id: {}, version: {} ]" .format(field_name, self._class_def.class_id, self._class_def.version))
def _check(self): if self._done: raise HazelcastSerializationError("ClassDefinition is already built for {}".format(self.class_id))