From 1f79b9ab66c518c2955578b3d44c260234be586b Mon Sep 17 00:00:00 2001 From: Zheng Feng Date: Tue, 5 Nov 2024 11:09:14 +0800 Subject: [PATCH 1/3] Fix #9 to add config to register classes --- .../fury/deployment/FuryProcessor.java | 14 ++++- .../ROOT/pages/includes/quarkus-fury.adoc | 56 +++++++++++++++++++ .../includes/quarkus-fury_quarkus.fury.adoc | 56 +++++++++++++++++++ .../main/java/io/quarkiverse/fury/it/Foo.java | 3 - .../java/io/quarkiverse/fury/it/Struct.java | 3 - .../src/main/resources/application.properties | 2 + .../quarkiverse/fury/FuryBuildTimeConfig.java | 17 ++++++ .../io/quarkiverse/fury/FuryRecorder.java | 38 +++++++++++-- .../fury/FuryRegisterClassConfig.java | 24 ++++++++ 9 files changed, 201 insertions(+), 12 deletions(-) create mode 100644 runtime/src/main/java/io/quarkiverse/fury/FuryRegisterClassConfig.java diff --git a/deployment/src/main/java/io/quarkiverse/fury/deployment/FuryProcessor.java b/deployment/src/main/java/io/quarkiverse/fury/deployment/FuryProcessor.java index 45a1c09..fde2542 100644 --- a/deployment/src/main/java/io/quarkiverse/fury/deployment/FuryProcessor.java +++ b/deployment/src/main/java/io/quarkiverse/fury/deployment/FuryProcessor.java @@ -1,6 +1,7 @@ package io.quarkiverse.fury.deployment; import java.util.List; +import java.util.Optional; import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.DotName; @@ -46,11 +47,22 @@ void unremovableBeans( @BuildStep @Record(ExecutionTime.STATIC_INIT) - public void registerClasses( + public void registerClasses(FuryBuildTimeConfig configs, FuryBuildItem fury, List classes, FuryRecorder recorder) { for (FurySerializerBuildItem item : classes) { recorder.registerClass(fury.getFury(), item.getClazz(), item.getClassId(), item.getSerializer()); } + + if (configs.registerClassNames().isPresent()) { + for (String name : configs.registerClassNames().get().split(",")) { + recorder.registerClassByName(fury.getFury(), name, -1, Optional.empty()); + } + } + + for (var config : configs.registerClasses().entrySet()) { + recorder.registerClassByName(fury.getFury(), config.getKey(), config.getValue().classId(), + config.getValue().serializer()); + } } @BuildStep diff --git a/docs/modules/ROOT/pages/includes/quarkus-fury.adoc b/docs/modules/ROOT/pages/includes/quarkus-fury.adoc index c701c23..605b8fe 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-fury.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-fury.adoc @@ -41,5 +41,61 @@ endif::add-copy-button-to-env-var[] |boolean |`true` +h|[[quarkus-fury_section_quarkus-fury-register-classes]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-classes[Configurations]## +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-configuration-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-configuration-name-class-id[`quarkus.fury.register-classes."configuration-name".class-id`]## + +[.description] +-- +Class id must be greater or equal to 256, and it must be different between classes. The default is -1. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__CLASS_ID+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__CLASS_ID+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`-1` + +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-configuration-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-configuration-name-serializer[`quarkus.fury.register-classes."configuration-name".serializer`]## + +[.description] +-- +Specify a customized serializer for current class. This should be empty to let Fury create serializer for current class. But if users want to customize serialization for this class, one can provide serializer here. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__SERIALIZER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__SERIALIZER+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + + +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-names]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-names[`quarkus.fury.register-class-names`]## + +[.description] +-- +Names of classes to register. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + |=== diff --git a/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc b/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc index c701c23..605b8fe 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc @@ -41,5 +41,61 @@ endif::add-copy-button-to-env-var[] |boolean |`true` +h|[[quarkus-fury_section_quarkus-fury-register-classes]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-classes[Configurations]## +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-configuration-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-configuration-name-class-id[`quarkus.fury.register-classes."configuration-name".class-id`]## + +[.description] +-- +Class id must be greater or equal to 256, and it must be different between classes. The default is -1. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__CLASS_ID+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__CLASS_ID+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`-1` + +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-configuration-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-configuration-name-serializer[`quarkus.fury.register-classes."configuration-name".serializer`]## + +[.description] +-- +Specify a customized serializer for current class. This should be empty to let Fury create serializer for current class. But if users want to customize serialization for this class, one can provide serializer here. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__SERIALIZER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__SERIALIZER+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + + +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-names]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-names[`quarkus.fury.register-class-names`]## + +[.description] +-- +Names of classes to register. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + |=== diff --git a/integration-tests/src/main/java/io/quarkiverse/fury/it/Foo.java b/integration-tests/src/main/java/io/quarkiverse/fury/it/Foo.java index d740be5..8e4f399 100644 --- a/integration-tests/src/main/java/io/quarkiverse/fury/it/Foo.java +++ b/integration-tests/src/main/java/io/quarkiverse/fury/it/Foo.java @@ -22,8 +22,5 @@ import java.util.List; import java.util.Map; -import io.quarkiverse.fury.FurySerialization; - -@FurySerialization(classId = 300) public record Foo(int f1, String f2, List f3, Map f4) { } diff --git a/integration-tests/src/main/java/io/quarkiverse/fury/it/Struct.java b/integration-tests/src/main/java/io/quarkiverse/fury/it/Struct.java index 7eaba53..4bc0941 100644 --- a/integration-tests/src/main/java/io/quarkiverse/fury/it/Struct.java +++ b/integration-tests/src/main/java/io/quarkiverse/fury/it/Struct.java @@ -22,9 +22,6 @@ import java.io.Serializable; import java.util.Objects; -import io.quarkiverse.fury.FurySerialization; - -@FurySerialization public class Struct implements Serializable { public int f1; public long f2; diff --git a/integration-tests/src/main/resources/application.properties b/integration-tests/src/main/resources/application.properties index e69de29..7b2f1cf 100644 --- a/integration-tests/src/main/resources/application.properties +++ b/integration-tests/src/main/resources/application.properties @@ -0,0 +1,2 @@ +quarkus.fury.register-class-names=io.quarkiverse.fury.it.Struct +quarkus.fury.register-classes."io.quarkiverse.fury.it.Foo".class-id=300 \ No newline at end of file diff --git a/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java b/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java index 563c85b..65a4558 100644 --- a/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java +++ b/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java @@ -1,5 +1,10 @@ package io.quarkiverse.fury; +import java.util.Map; +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigDocMapKey; +import io.quarkus.runtime.annotations.ConfigDocSection; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; import io.smallrye.config.ConfigMapping; @@ -15,4 +20,16 @@ public interface FuryBuildTimeConfig { /** Whether to use thread safe fury. The default is true. */ @WithDefault("true") boolean threadSafe(); + + /** + * Configurations + */ + @ConfigDocSection + @ConfigDocMapKey("configuration-name") + Map registerClasses(); + + /** + * Names of classes to register. + */ + Optional registerClassNames(); } diff --git a/runtime/src/main/java/io/quarkiverse/fury/FuryRecorder.java b/runtime/src/main/java/io/quarkiverse/fury/FuryRecorder.java index 8218453..5198cc9 100644 --- a/runtime/src/main/java/io/quarkiverse/fury/FuryRecorder.java +++ b/runtime/src/main/java/io/quarkiverse/fury/FuryRecorder.java @@ -1,5 +1,7 @@ package io.quarkiverse.fury; +import java.util.Optional; + import org.apache.fury.BaseFury; import org.apache.fury.Fury; import org.apache.fury.ThreadSafeFury; @@ -7,6 +9,7 @@ import org.apache.fury.resolver.ClassResolver; import org.apache.fury.serializer.Serializer; import org.apache.fury.util.Preconditions; +import org.jboss.logging.Logger; import io.quarkus.arc.runtime.BeanContainer; import io.quarkus.runtime.RuntimeValue; @@ -14,6 +17,8 @@ @Recorder public class FuryRecorder { + private static final Logger LOG = Logger.getLogger(FuryRecorder.class); + public RuntimeValue createFury( final FuryBuildTimeConfig config, final BeanContainer beanContainer) { // create the Fury instance from the config @@ -26,6 +31,25 @@ public RuntimeValue createFury( return new RuntimeValue<>(fury); } + public void registerClassByName(final RuntimeValue furyValue, final String className, final int classId, + final Optional serializerClassName) { + try { + Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className); + Class serializer = null; + if (serializerClassName.isPresent()) { + serializer = (Class) Thread.currentThread().getContextClassLoader() + .loadClass(serializerClassName.get()); + } + registerClass(furyValue, clazz, classId, serializer); + } catch (ClassNotFoundException e) { + LOG.warn("can not find register class: " + className + + (serializerClassName.isPresent() + ? " with serializer: " + serializerClassName.get() + : "")); + throw new RuntimeException(e); + } + } + public void registerClass( final RuntimeValue furyValue, final Class clazz, final int classId, Class serializer) { @@ -40,13 +64,17 @@ public void registerClass( if (fury instanceof ThreadSafeFury) { ThreadSafeFury threadSafeFury = (ThreadSafeFury) fury; registeredClass = (threadSafeFury).execute(f -> f.getClassResolver().getRegisteredClass((short) classId)); - // Generate serializer bytecode. - threadSafeFury.execute(f -> f.getClassResolver().getSerializerClass(clazz)); + if (serializer == null) { + // Generate serializer bytecode. + threadSafeFury.execute(f -> f.getClassResolver().getSerializerClass(clazz)); + } } else { ClassResolver classResolver = ((Fury) fury).getClassResolver(); registeredClass = classResolver.getRegisteredClass((short) classId); - // Generate serializer bytecode. - classResolver.getSerializerClass(clazz); + if (serializer == null) { + // Generate serializer bytecode. + classResolver.getSerializerClass(clazz); + } } Preconditions.checkArgument( registeredClass == null, @@ -56,7 +84,7 @@ public void registerClass( fury.register(clazz, (short) classId); } else { // Generate serializer bytecode. - fury.register(clazz, true); + fury.register(clazz, serializer == null); } if (serializer != null) { fury.registerSerializer(clazz, serializer); diff --git a/runtime/src/main/java/io/quarkiverse/fury/FuryRegisterClassConfig.java b/runtime/src/main/java/io/quarkiverse/fury/FuryRegisterClassConfig.java new file mode 100644 index 0000000..1c9d9f4 --- /dev/null +++ b/runtime/src/main/java/io/quarkiverse/fury/FuryRegisterClassConfig.java @@ -0,0 +1,24 @@ +package io.quarkiverse.fury; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.smallrye.config.WithDefault; + +@ConfigGroup +public interface FuryRegisterClassConfig { + /** + * Class id must be greater or equal to 256, and it must be different between classes. + * The default is -1. + */ + @WithDefault("-1") + Integer classId(); + + /** + * Specify a customized serializer for current class. + * This should be empty to let Fury create serializer for current class. But if + * users want to customize serialization for this class, one can provide serializer here. + */ + Optional serializer(); + +} From d46b86f4a0a6f9aeacbd73ce7cc5632c55fdee9f Mon Sep 17 00:00:00 2001 From: Zheng Feng Date: Tue, 5 Nov 2024 15:57:47 +0800 Subject: [PATCH 2/3] improve docs --- .../ROOT/pages/includes/quarkus-fury.adoc | 42 +++++++++---------- .../includes/quarkus-fury_quarkus.fury.adoc | 42 +++++++++---------- .../quarkiverse/fury/FuryBuildTimeConfig.java | 13 +++--- 3 files changed, 49 insertions(+), 48 deletions(-) diff --git a/docs/modules/ROOT/pages/includes/quarkus-fury.adoc b/docs/modules/ROOT/pages/includes/quarkus-fury.adoc index 605b8fe..7b2c371 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-fury.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-fury.adoc @@ -41,61 +41,61 @@ endif::add-copy-button-to-env-var[] |boolean |`true` -h|[[quarkus-fury_section_quarkus-fury-register-classes]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-classes[Configurations]## -h|Type -h|Default - -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-configuration-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-configuration-name-class-id[`quarkus.fury.register-classes."configuration-name".class-id`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-names]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-names[`quarkus.fury.register-class-names`]## [.description] -- -Class id must be greater or equal to 256, and it must be different between classes. The default is -1. +Names of classes to register which no need to be with class-id or customize serializer. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__CLASS_ID+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__CLASS_ID+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++` endif::add-copy-button-to-env-var[] -- -|int -|`-1` +|string +| + +h|[[quarkus-fury_section_quarkus-fury-register-classes]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-classes[Configurations of register classes]## +h|Type +h|Default -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-configuration-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-configuration-name-serializer[`quarkus.fury.register-classes."configuration-name".serializer`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-register-class-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-register-class-name-class-id[`quarkus.fury.register-classes."register-class-name".class-id`]## [.description] -- -Specify a customized serializer for current class. This should be empty to let Fury create serializer for current class. But if users want to customize serialization for this class, one can provide serializer here. +Class id must be greater or equal to 256, and it must be different between classes. The default is -1. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__SERIALIZER+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__CLASS_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__SERIALIZER+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__CLASS_ID+++` endif::add-copy-button-to-env-var[] -- -|string -| - +|int +|`-1` -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-names]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-names[`quarkus.fury.register-class-names`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-register-class-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-register-class-name-serializer[`quarkus.fury.register-classes."register-class-name".serializer`]## [.description] -- -Names of classes to register. +Specify a customized serializer for current class. This should be empty to let Fury create serializer for current class. But if users want to customize serialization for this class, one can provide serializer here. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__SERIALIZER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__SERIALIZER+++` endif::add-copy-button-to-env-var[] -- |string | + |=== diff --git a/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc b/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc index 605b8fe..7b2c371 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc @@ -41,61 +41,61 @@ endif::add-copy-button-to-env-var[] |boolean |`true` -h|[[quarkus-fury_section_quarkus-fury-register-classes]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-classes[Configurations]## -h|Type -h|Default - -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-configuration-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-configuration-name-class-id[`quarkus.fury.register-classes."configuration-name".class-id`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-names]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-names[`quarkus.fury.register-class-names`]## [.description] -- -Class id must be greater or equal to 256, and it must be different between classes. The default is -1. +Names of classes to register which no need to be with class-id or customize serializer. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__CLASS_ID+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__CLASS_ID+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++` endif::add-copy-button-to-env-var[] -- -|int -|`-1` +|string +| + +h|[[quarkus-fury_section_quarkus-fury-register-classes]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-classes[Configurations of register classes]## +h|Type +h|Default -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-configuration-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-configuration-name-serializer[`quarkus.fury.register-classes."configuration-name".serializer`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-register-class-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-register-class-name-class-id[`quarkus.fury.register-classes."register-class-name".class-id`]## [.description] -- -Specify a customized serializer for current class. This should be empty to let Fury create serializer for current class. But if users want to customize serialization for this class, one can provide serializer here. +Class id must be greater or equal to 256, and it must be different between classes. The default is -1. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__SERIALIZER+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__CLASS_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__CONFIGURATION_NAME__SERIALIZER+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__CLASS_ID+++` endif::add-copy-button-to-env-var[] -- -|string -| - +|int +|`-1` -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-names]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-names[`quarkus.fury.register-class-names`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-register-class-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-register-class-name-serializer[`quarkus.fury.register-classes."register-class-name".serializer`]## [.description] -- -Names of classes to register. +Specify a customized serializer for current class. This should be empty to let Fury create serializer for current class. But if users want to customize serialization for this class, one can provide serializer here. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__SERIALIZER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS_NAMES+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__SERIALIZER+++` endif::add-copy-button-to-env-var[] -- |string | + |=== diff --git a/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java b/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java index 65a4558..d900951 100644 --- a/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java +++ b/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java @@ -22,14 +22,15 @@ public interface FuryBuildTimeConfig { boolean threadSafe(); /** - * Configurations + * Names of classes to register which no need to be with class-id or customize serializer. */ - @ConfigDocSection - @ConfigDocMapKey("configuration-name") - Map registerClasses(); + Optional registerClassNames(); /** - * Names of classes to register. + * Configurations of register classes */ - Optional registerClassNames(); + @ConfigDocSection + @ConfigDocMapKey("register-class-name") + Map registerClasses(); + } From 8e42123bcc138db13cec0de45bb45d75662fb1f6 Mon Sep 17 00:00:00 2001 From: Zheng Feng Date: Tue, 5 Nov 2024 19:47:14 +0800 Subject: [PATCH 3/3] change to use register-class and add a test --- .../fury/deployment/FuryProcessor.java | 2 +- .../ROOT/pages/includes/quarkus-fury.adoc | 16 +++--- .../includes/quarkus-fury_quarkus.fury.adoc | 16 +++--- .../io/quarkiverse/fury/it/FooSerializer.java | 53 +++++++++++++++++++ .../io/quarkiverse/fury/it/FuryResources.java | 7 +++ .../src/main/resources/application.properties | 4 +- .../quarkiverse/fury/FuryBuildTimeConfig.java | 5 +- 7 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 integration-tests/src/main/java/io/quarkiverse/fury/it/FooSerializer.java diff --git a/deployment/src/main/java/io/quarkiverse/fury/deployment/FuryProcessor.java b/deployment/src/main/java/io/quarkiverse/fury/deployment/FuryProcessor.java index fde2542..f1c262e 100644 --- a/deployment/src/main/java/io/quarkiverse/fury/deployment/FuryProcessor.java +++ b/deployment/src/main/java/io/quarkiverse/fury/deployment/FuryProcessor.java @@ -59,7 +59,7 @@ public void registerClasses(FuryBuildTimeConfig configs, } } - for (var config : configs.registerClasses().entrySet()) { + for (var config : configs.registerClass().entrySet()) { recorder.registerClassByName(fury.getFury(), config.getKey(), config.getValue().classId(), config.getValue().serializer()); } diff --git a/docs/modules/ROOT/pages/includes/quarkus-fury.adoc b/docs/modules/ROOT/pages/includes/quarkus-fury.adoc index 7b2c371..05d2c05 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-fury.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-fury.adoc @@ -45,7 +45,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-clas [.description] -- -Names of classes to register which no need to be with class-id or customize serializer. +Names of classes to register which no need to be with class-id or customize serializer. It has to be separated by comma. ifdef::add-copy-button-to-env-var[] @@ -58,11 +58,11 @@ endif::add-copy-button-to-env-var[] |string | -h|[[quarkus-fury_section_quarkus-fury-register-classes]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-classes[Configurations of register classes]## +h|[[quarkus-fury_section_quarkus-fury-register-class]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-class[Configurations of register class]## h|Type h|Default -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-register-class-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-register-class-name-class-id[`quarkus.fury.register-classes."register-class-name".class-id`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-register-class-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-register-class-name-class-id[`quarkus.fury.register-class."register-class-name".class-id`]## [.description] -- @@ -70,16 +70,16 @@ Class id must be greater or equal to 256, and it must be different between class ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__CLASS_ID+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS__REGISTER_CLASS_NAME__CLASS_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__CLASS_ID+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS__REGISTER_CLASS_NAME__CLASS_ID+++` endif::add-copy-button-to-env-var[] -- |int |`-1` -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-register-class-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-register-class-name-serializer[`quarkus.fury.register-classes."register-class-name".serializer`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-register-class-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-register-class-name-serializer[`quarkus.fury.register-class."register-class-name".serializer`]## [.description] -- @@ -87,10 +87,10 @@ Specify a customized serializer for current class. This should be empty to let F ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__SERIALIZER+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS__REGISTER_CLASS_NAME__SERIALIZER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__SERIALIZER+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS__REGISTER_CLASS_NAME__SERIALIZER+++` endif::add-copy-button-to-env-var[] -- |string diff --git a/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc b/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc index 7b2c371..05d2c05 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-fury_quarkus.fury.adoc @@ -45,7 +45,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-clas [.description] -- -Names of classes to register which no need to be with class-id or customize serializer. +Names of classes to register which no need to be with class-id or customize serializer. It has to be separated by comma. ifdef::add-copy-button-to-env-var[] @@ -58,11 +58,11 @@ endif::add-copy-button-to-env-var[] |string | -h|[[quarkus-fury_section_quarkus-fury-register-classes]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-classes[Configurations of register classes]## +h|[[quarkus-fury_section_quarkus-fury-register-class]] [.section-name.section-level0]##link:#quarkus-fury_section_quarkus-fury-register-class[Configurations of register class]## h|Type h|Default -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-register-class-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-register-class-name-class-id[`quarkus.fury.register-classes."register-class-name".class-id`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-register-class-name-class-id]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-register-class-name-class-id[`quarkus.fury.register-class."register-class-name".class-id`]## [.description] -- @@ -70,16 +70,16 @@ Class id must be greater or equal to 256, and it must be different between class ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__CLASS_ID+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS__REGISTER_CLASS_NAME__CLASS_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__CLASS_ID+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS__REGISTER_CLASS_NAME__CLASS_ID+++` endif::add-copy-button-to-env-var[] -- |int |`-1` -a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-classes-register-class-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-classes-register-class-name-serializer[`quarkus.fury.register-classes."register-class-name".serializer`]## +a|icon:lock[title=Fixed at build time] [[quarkus-fury_quarkus-fury-register-class-register-class-name-serializer]] [.property-path]##link:#quarkus-fury_quarkus-fury-register-class-register-class-name-serializer[`quarkus.fury.register-class."register-class-name".serializer`]## [.description] -- @@ -87,10 +87,10 @@ Specify a customized serializer for current class. This should be empty to let F ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__SERIALIZER+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_FURY_REGISTER_CLASS__REGISTER_CLASS_NAME__SERIALIZER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_FURY_REGISTER_CLASSES__REGISTER_CLASS_NAME__SERIALIZER+++` +Environment variable: `+++QUARKUS_FURY_REGISTER_CLASS__REGISTER_CLASS_NAME__SERIALIZER+++` endif::add-copy-button-to-env-var[] -- |string diff --git a/integration-tests/src/main/java/io/quarkiverse/fury/it/FooSerializer.java b/integration-tests/src/main/java/io/quarkiverse/fury/it/FooSerializer.java new file mode 100644 index 0000000..ed8a023 --- /dev/null +++ b/integration-tests/src/main/java/io/quarkiverse/fury/it/FooSerializer.java @@ -0,0 +1,53 @@ +package io.quarkiverse.fury.it; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.fury.Fury; +import org.apache.fury.memory.MemoryBuffer; +import org.apache.fury.serializer.Serializer; + +public class FooSerializer extends Serializer { + public FooSerializer(Fury fury, Class type) { + super(fury, type); + } + + @Override + public void write(MemoryBuffer buffer, Foo value) { + buffer.writeVarInt32(value.f1()); + fury.writeJavaString(buffer, value.f2()); + + buffer.writeInt32(value.f3().size()); + for (String v : value.f3()) { + fury.writeJavaString(buffer, v); + } + + buffer.writeInt32(value.f4().size()); + for (var entry : value.f4().entrySet()) { + fury.writeJavaString(buffer, entry.getKey()); + buffer.writeInt64(entry.getValue()); + } + } + + @Override + public Foo read(MemoryBuffer buffer) { + int f1 = buffer.readVarInt32(); + String f2 = fury.readJavaString(buffer); + List f3 = new ArrayList<>(); + Map f4 = new HashMap<>(); + + int size = buffer.readInt32(); + for (int i = 0; i < size; i++) { + f3.add(fury.readJavaString(buffer)); + } + + size = buffer.readInt32(); + for (int i = 0; i < size; i++) { + f4.put(fury.readJavaString(buffer), buffer.readInt64()); + } + + return new Foo(f1, f2, f3, f4); + } +} diff --git a/integration-tests/src/main/java/io/quarkiverse/fury/it/FuryResources.java b/integration-tests/src/main/java/io/quarkiverse/fury/it/FuryResources.java index 963edc9..99889bd 100644 --- a/integration-tests/src/main/java/io/quarkiverse/fury/it/FuryResources.java +++ b/integration-tests/src/main/java/io/quarkiverse/fury/it/FuryResources.java @@ -25,6 +25,13 @@ public class FuryResources { public Boolean testSerializeFooRecord() { Foo foo1 = new Foo(10, "abc", List.of("str1", "str2"), Map.of("k1", 10L, "k2", 20L)); Foo foo2 = (Foo) fury.deserialize(fury.serialize(foo1)); + Serializer serializer; + if (fury instanceof ThreadSafeFury) { + serializer = ((ThreadSafeFury) fury).execute(f -> f.getClassResolver().getSerializer(Foo.class)); + } else { + serializer = ((Fury) fury).getClassResolver().getSerializer(Foo.class); + } + Preconditions.checkArgument(serializer instanceof FooSerializer, serializer); return foo1.equals(foo2); } diff --git a/integration-tests/src/main/resources/application.properties b/integration-tests/src/main/resources/application.properties index 7b2f1cf..0195b97 100644 --- a/integration-tests/src/main/resources/application.properties +++ b/integration-tests/src/main/resources/application.properties @@ -1,2 +1,4 @@ quarkus.fury.register-class-names=io.quarkiverse.fury.it.Struct -quarkus.fury.register-classes."io.quarkiverse.fury.it.Foo".class-id=300 \ No newline at end of file + +quarkus.fury.register-class."io.quarkiverse.fury.it.Foo".class-id=300 +quarkus.fury.register-class."io.quarkiverse.fury.it.Foo".serializer=io.quarkiverse.fury.it.FooSerializer diff --git a/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java b/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java index d900951..bf01151 100644 --- a/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java +++ b/runtime/src/main/java/io/quarkiverse/fury/FuryBuildTimeConfig.java @@ -23,14 +23,15 @@ public interface FuryBuildTimeConfig { /** * Names of classes to register which no need to be with class-id or customize serializer. + * It has to be separated by comma. */ Optional registerClassNames(); /** - * Configurations of register classes + * Configurations of register class */ @ConfigDocSection @ConfigDocMapKey("register-class-name") - Map registerClasses(); + Map registerClass(); }