Exemplo n.º 1
0
class SerializationServiceV1:
    def __init__(
        self,
        config,
        version=1,
        global_partition_strategy=default_partition_strategy,
        output_buffer_size=DEFAULT_OUT_BUFFER_SIZE,
    ):
        self._version = version
        self._global_partition_strategy = global_partition_strategy
        self._output_buffer_size = output_buffer_size
        self._is_big_endian = config.is_big_endian
        self._active = True
        self._portable_context = PortableContext(self, config.portable_version)
        self.register_class_definitions(config.class_definitions,
                                        config.check_class_definition_errors)
        self._portable_serializer = PortableSerializer(
            self._portable_context, config.portable_factories)
        self._compact_stream_serializer = CompactStreamSerializer(
            config.compact_serializers)

        # merge configured factories with built in ones
        factories = self._get_builtin_identified_factories()
        factories.update(config.data_serializable_factories)
        self._data_serializer = IdentifiedDataSerializer(factories)

        # Register Global Serializer
        self._global_serializer = config.global_serializer(
        ) if config.global_serializer else None

        self._null_serializer = NoneSerializer()
        self._python_serializer = PythonObjectSerializer()

        self._registry = SerializerRegistry(
            config,
            self._portable_serializer,
            self._data_serializer,
            self._compact_stream_serializer,
            self._null_serializer,
            self._python_serializer,
            self._global_serializer,
        )

        self._register_constant_serializers()

        # Register Custom Serializers
        for _type, custom_serializer in config.custom_serializers.items():
            self._registry.safe_register_serializer(custom_serializer(), _type)

    def to_data(self, obj, partitioning_strategy=None):
        """Serialize the input object into byte array representation

        Args:
            obj: Input object
            partitioning_strategy (function): Function in the form of ``lambda key: partitioning_key``.

        Returns:
            hazelcast.serialization.data.Data: Data object
        """
        if obj is None:
            return None

        if isinstance(obj, Data):
            return obj

        out = _ObjectDataOutput(self._output_buffer_size, self,
                                self._is_big_endian)
        try:
            serializer = self._registry.serializer_for(obj)
            partitioning_hash = self._calculate_partitioning_hash(
                obj, partitioning_strategy)

            out.write_int_big_endian(partitioning_hash)
            out.write_int_big_endian(serializer.get_type_id())
            serializer.write(out, obj)
            return Data(out.to_byte_array())
        except:
            handle_exception(sys.exc_info()[1], sys.exc_info()[2])

    def to_object(self, data):
        """Deserialize input data

        Args:
            data (hazelcast.serialization.data.Data): Serialized input Data object

        Returns:
            any: Deserialized object
        """
        if not isinstance(data, Data):
            return data

        if data.data_size() == 0 and data.get_type() == CONSTANT_TYPE_NULL:
            return None

        inp = _ObjectDataInput(data.buffer, DATA_OFFSET, self,
                               self._is_big_endian)
        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:%s" % type_id)
                else:
                    raise HazelcastInstanceNotActiveError()
            return serializer.read(inp)
        except:
            handle_exception(sys.exc_info()[1], sys.exc_info()[2])

    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 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: %s" % type_id)
                else:
                    raise HazelcastInstanceNotActiveError()
            return serializer.read(inp)
        except:
            handle_exception(sys.exc_info()[1], sys.exc_info()[2])

    def _calculate_partitioning_hash(self, obj, partitioning_strategy):
        partitioning_hash = 0
        _ps = (partitioning_strategy if partitioning_strategy is not None else
               self._global_partition_strategy)
        pk = _ps(obj)
        if pk is not None and pk is not obj:
            partitioning_key = self.to_data(pk, empty_partitioning_strategy)
            partitioning_hash = partitioning_key.get_partition_hash()
        return partitioning_hash

    def destroy(self):
        self._active = False
        self._registry.destroy()

    @property
    def compact_stream_serializer(self) -> CompactStreamSerializer:
        return self._compact_stream_serializer

    @staticmethod
    def _get_builtin_identified_factories():
        return {
            ReliableTopicMessage.FACTORY_ID: {
                ReliableTopicMessage.CLASS_ID: ReliableTopicMessage,
            },
            CanonicalizingHashSet.FACTORY_ID: {
                CanonicalizingHashSet.CLASS_ID: CanonicalizingHashSet,
            },
            IdentifiedMapEntry.FACTORY_ID: {
                IdentifiedMapEntry.CLASS_ID: IdentifiedMapEntry,
            },
            IdentifiedAddress.FACTORY_ID: {
                IdentifiedAddress.CLASS_ID: IdentifiedAddress,
            },
        }

    def _register_constant_serializers(self):
        self._registry.register_constant_serializer(self._null_serializer,
                                                    type(None))
        self._registry.register_constant_serializer(self._data_serializer)
        self._registry.register_constant_serializer(self._portable_serializer)
        self._registry.register_constant_serializer(
            self._compact_stream_serializer)
        self._registry.register_constant_serializer(ByteSerializer())
        self._registry.register_constant_serializer(BooleanSerializer(), bool)
        self._registry.register_constant_serializer(CharSerializer())
        self._registry.register_constant_serializer(ShortSerializer())
        self._registry.register_constant_serializer(IntegerSerializer())
        self._registry.register_constant_serializer(LongSerializer())
        self._registry.register_constant_serializer(FloatSerializer())
        self._registry.register_constant_serializer(DoubleSerializer(), float)
        self._registry.register_constant_serializer(UuidSerializer(),
                                                    uuid.UUID)
        self._registry.register_constant_serializer(StringSerializer())
        # Arrays of primitives and String
        self._registry.register_constant_serializer(ByteArraySerializer(),
                                                    bytearray)
        self._registry.register_constant_serializer(BooleanArraySerializer())
        self._registry.register_constant_serializer(CharArraySerializer())
        self._registry.register_constant_serializer(ShortArraySerializer())
        self._registry.register_constant_serializer(IntegerArraySerializer())
        self._registry.register_constant_serializer(LongArraySerializer())
        self._registry.register_constant_serializer(FloatArraySerializer())
        self._registry.register_constant_serializer(DoubleArraySerializer())
        self._registry.register_constant_serializer(StringArraySerializer())
        # EXTENSIONS
        self._registry.register_constant_serializer(BigIntegerSerializer())
        self._registry.register_constant_serializer(BigDecimalSerializer(),
                                                    decimal.Decimal)
        self._registry.register_constant_serializer(JavaClassSerializer())
        self._registry.register_constant_serializer(ArraySerializer())
        self._registry.register_constant_serializer(ArrayListSerializer(),
                                                    list)
        self._registry.register_constant_serializer(LinkedListSerializer())
        self._registry.register_constant_serializer(LocalDateSerializer(),
                                                    datetime.date)
        self._registry.register_constant_serializer(LocalTimeSerializer(),
                                                    datetime.time)
        self._registry.register_constant_serializer(LocalDateTimeSerializer())
        self._registry.register_constant_serializer(OffsetDateTimeSerializer(),
                                                    datetime.datetime)
        self._registry.register_constant_serializer(
            HazelcastJsonValueSerializer(), HazelcastJsonValue)

        self._registry.safe_register_serializer(self._python_serializer)

    def register_class_definitions(self, class_definitions, check_error):
        factories = dict()
        for cd in class_definitions:
            factory_id = cd.factory_id
            class_defs = factories.get(factory_id, None)
            if class_defs is None:
                class_defs = dict()
                factories[factory_id] = class_defs

            class_id = cd.class_id
            if class_id in class_defs:
                raise HazelcastSerializationError(
                    "Duplicate registration found for class-id: %s" % class_id)
            class_defs[class_id] = cd

        for cd in class_definitions:
            self.register_class_definition(cd, factories, check_error)

    def register_class_definition(self, class_definition, factories,
                                  check_error):
        field_names = class_definition.get_field_names()
        for field_name in field_names:
            fd = class_definition.get_field(field_name)
            if fd.field_type == FieldType.PORTABLE or fd.field_type == FieldType.PORTABLE_ARRAY:
                factory_id = fd.factory_id
                class_id = fd.class_id
                class_defs = factories.get(factory_id, None)
                if class_defs is not None:
                    nested_cd = class_defs.get(class_id, None)
                    if nested_cd is not None:
                        self.register_class_definition(nested_cd, factories,
                                                       check_error)
                        self._portable_context.register_class_definition(
                            nested_cd)
                        continue

                if check_error:
                    raise HazelcastSerializationError(
                        "Could not find registered ClassDefinition for factory-id: %s, class-id: %s"
                        % (factory_id, class_id))

        self._portable_context.register_class_definition(class_definition)
Exemplo n.º 2
0
class SerializationServiceV1(BaseSerializationService):
    def __init__(
        self,
        config,
        version=1,
        global_partition_strategy=default_partition_strategy,
        output_buffer_size=DEFAULT_OUT_BUFFER_SIZE,
    ):
        super(SerializationServiceV1, self).__init__(
            version,
            global_partition_strategy,
            output_buffer_size,
            config.is_big_endian,
            config.default_int_type,
        )
        self._portable_context = PortableContext(self, config.portable_version)
        self.register_class_definitions(config.class_definitions,
                                        config.check_class_definition_errors)
        self._registry._portable_serializer = PortableSerializer(
            self._portable_context, config.portable_factories)

        # merge configured factories with built in ones
        factories = {}
        factories.update(config.data_serializable_factories)
        self._registry._data_serializer = IdentifiedDataSerializer(factories)
        self._register_constant_serializers()

        # Register Custom Serializers
        for _type, custom_serializer in six.iteritems(
                config.custom_serializers):
            self._registry.safe_register_serializer(custom_serializer(), _type)

        # Register Global Serializer
        global_serializer = config.global_serializer
        if global_serializer:
            self._registry._global_serializer = global_serializer()

    def _register_constant_serializers(self):
        self._registry.register_constant_serializer(
            self._registry._null_serializer, type(None))
        self._registry.register_constant_serializer(
            self._registry._data_serializer)
        self._registry.register_constant_serializer(
            self._registry._portable_serializer)
        self._registry.register_constant_serializer(ByteSerializer())
        self._registry.register_constant_serializer(BooleanSerializer(), bool)
        self._registry.register_constant_serializer(CharSerializer())
        self._registry.register_constant_serializer(ShortSerializer())
        self._registry.register_constant_serializer(IntegerSerializer())
        self._registry.register_constant_serializer(LongSerializer())
        self._registry.register_constant_serializer(FloatSerializer())
        self._registry.register_constant_serializer(DoubleSerializer(), float)
        self._registry.register_constant_serializer(UuidSerializer(),
                                                    uuid.UUID)
        self._registry.register_constant_serializer(StringSerializer())
        # Arrays of primitives and String
        self._registry.register_constant_serializer(ByteArraySerializer(),
                                                    bytearray)
        self._registry.register_constant_serializer(BooleanArraySerializer())
        self._registry.register_constant_serializer(CharArraySerializer())
        self._registry.register_constant_serializer(ShortArraySerializer())
        self._registry.register_constant_serializer(IntegerArraySerializer())
        self._registry.register_constant_serializer(LongArraySerializer())
        self._registry.register_constant_serializer(FloatArraySerializer())
        self._registry.register_constant_serializer(DoubleArraySerializer())
        self._registry.register_constant_serializer(StringArraySerializer())
        # EXTENSIONS
        self._registry.register_constant_serializer(DateTimeSerializer(),
                                                    datetime)
        self._registry.register_constant_serializer(BigIntegerSerializer())
        self._registry.register_constant_serializer(JavaClassSerializer())
        self._registry.register_constant_serializer(ArrayListSerializer(),
                                                    list)
        self._registry.register_constant_serializer(LinkedListSerializer())
        self._registry.register_constant_serializer(
            HazelcastJsonValueSerializer(), HazelcastJsonValue)

        self._registry.safe_register_serializer(
            self._registry._python_serializer)

    def register_class_definitions(self, class_definitions, check_error):
        factories = dict()
        for cd in class_definitions:
            factory_id = cd.factory_id
            class_defs = factories.get(factory_id, None)
            if class_defs is None:
                class_defs = dict()
                factories[factory_id] = class_defs

            class_id = cd.class_id
            if class_id in class_defs:
                raise HazelcastSerializationError(
                    "Duplicate registration found for class-id: %s" % class_id)
            class_defs[class_id] = cd

        for cd in class_definitions:
            self.register_class_definition(cd, factories, check_error)

    def register_class_definition(self, class_definition, factories,
                                  check_error):
        field_names = class_definition.get_field_names()
        for field_name in field_names:
            fd = class_definition.get_field(field_name)
            if fd.field_type == FieldType.PORTABLE or fd.field_type == FieldType.PORTABLE_ARRAY:
                factory_id = fd.factory_id
                class_id = fd.class_id
                class_defs = factories.get(factory_id, None)
                if class_defs is not None:
                    nested_cd = class_defs.get(class_id, None)
                    if nested_cd is not None:
                        self.register_class_definition(nested_cd, factories,
                                                       check_error)
                        self._portable_context.register_class_definition(
                            nested_cd)
                        continue

                if check_error:
                    raise HazelcastSerializationError(
                        "Could not find registered ClassDefinition for factory-id: %s, class-id: %s"
                        % (factory_id, class_id))

        self._portable_context.register_class_definition(class_definition)
Exemplo n.º 3
0
class SerializationServiceV1(BaseSerializationService):
    logger = logging.getLogger("SerializationService")

    def __init__(self, serialization_config, version=1, portable_version=0,
                 global_partition_strategy=default_partition_strategy,
                 output_buffer_size=DEFAULT_OUT_BUFFER_SIZE):
        super(SerializationServiceV1, self).__init__(version, global_partition_strategy, output_buffer_size,
                                                     serialization_config.is_big_endian,
                                                     serialization_config.default_integer_type)
        self._portable_context = PortableContext(self, portable_version)
        self.register_class_definitions(serialization_config.class_definitions, serialization_config.check_class_def_errors)
        self._registry._portable_serializer = PortableSerializer(self._portable_context, serialization_config.portable_factories)

        # merge configured factories with built in ones
        factories = {}
        factories.update(serialization_config.data_serializable_factories)
        self._registry._data_serializer = IdentifiedDataSerializer(factories)
        self._register_constant_serializers()

        # Register Custom Serializers
        for _type, custom_serializer in serialization_config.custom_serializers.iteritems():
            self._registry.safe_register_serializer(custom_serializer(), _type)

        # Register Global Serializer
        global_serializer = serialization_config.global_serializer
        if global_serializer:
            self._registry._global_serializer = global_serializer()

    def _register_constant_serializers(self):
        self._registry.register_constant_serializer(self._registry._null_serializer, type(None))
        self._registry.register_constant_serializer(self._registry._data_serializer)
        self._registry.register_constant_serializer(self._registry._portable_serializer)
        self._registry.register_constant_serializer(ByteSerializer())
        self._registry.register_constant_serializer(BooleanSerializer(), bool)
        self._registry.register_constant_serializer(CharSerializer())
        self._registry.register_constant_serializer(ShortSerializer())
        self._registry.register_constant_serializer(IntegerSerializer())
        self._registry.register_constant_serializer(LongSerializer())
        self._registry.register_constant_serializer(FloatSerializer())
        self._registry.register_constant_serializer(DoubleSerializer(), float)
        self._registry.register_constant_serializer(StringSerializer())
        # Arrays of primitives and String
        self._registry.register_constant_serializer(ByteArraySerializer())
        self._registry.register_constant_serializer(BooleanArraySerializer())
        self._registry.register_constant_serializer(CharArraySerializer())
        self._registry.register_constant_serializer(ShortArraySerializer())
        self._registry.register_constant_serializer(IntegerArraySerializer())
        self._registry.register_constant_serializer(LongArraySerializer())
        self._registry.register_constant_serializer(FloatArraySerializer())
        self._registry.register_constant_serializer(DoubleArraySerializer())
        self._registry.register_constant_serializer(StringArraySerializer())
        # EXTENSIONS
        self._registry.register_constant_serializer(DateTimeSerializer(), datetime)
        self._registry.register_constant_serializer(BigIntegerSerializer())
        self._registry.register_constant_serializer(BigDecimalSerializer())
        self._registry.register_constant_serializer(JavaClassSerializer())
        self._registry.register_constant_serializer(JavaEnumSerializer())
        self._registry.register_constant_serializer(ArrayListSerializer(), list)
        self._registry.register_constant_serializer(LinkedListSerializer())

        self._registry.safe_register_serializer(self._registry._python_serializer)

    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 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)