Search in sources :

Example 1 with PolymorphicConfig

use of org.apache.ignite.configuration.annotation.PolymorphicConfig in project ignite-3 by apache.

the class ConfigurationAsmGenerator method compileRootSchema.

/**
 * Generates, defines, loads and initializes all dynamic classes required for the given configuration schema.
 *
 * @param rootSchemaClass             Class of the root configuration schema.
 * @param internalSchemaExtensions    Internal extensions ({@link InternalConfiguration}) of configuration schemas ({@link
 *                                    ConfigurationRoot} and {@link Config}). Mapping: original schema -> extensions.
 * @param polymorphicSchemaExtensions Polymorphic extensions ({@link PolymorphicConfigInstance}) of configuration schemas ({@link
 *                                    PolymorphicConfig}). Mapping: original schema -> extensions.
 */
public synchronized void compileRootSchema(Class<?> rootSchemaClass, Map<Class<?>, Set<Class<?>>> internalSchemaExtensions, Map<Class<?>, Set<Class<?>>> polymorphicSchemaExtensions) {
    if (schemasInfo.containsKey(rootSchemaClass)) {
        // Already compiled.
        return;
    }
    Queue<Class<?>> compileQueue = new ArrayDeque<>();
    compileQueue.add(rootSchemaClass);
    schemasInfo.put(rootSchemaClass, new SchemaClassesInfo(rootSchemaClass));
    Set<Class<?>> schemas = new HashSet<>();
    List<ClassDefinition> classDefs = new ArrayList<>();
    while (!compileQueue.isEmpty()) {
        Class<?> schemaClass = compileQueue.poll();
        assert schemaClass.isAnnotationPresent(ConfigurationRoot.class) || schemaClass.isAnnotationPresent(Config.class) || isPolymorphicConfig(schemaClass) : schemaClass + " is not properly annotated";
        assert schemasInfo.containsKey(schemaClass) : schemaClass;
        Set<Class<?>> internalExtensions = internalSchemaExtensions.getOrDefault(schemaClass, Set.of());
        Set<Class<?>> polymorphicExtensions = polymorphicSchemaExtensions.getOrDefault(schemaClass, Set.of());
        assert internalExtensions.isEmpty() || polymorphicExtensions.isEmpty() : "Internal and polymorphic extensions are not allowed at the same time: " + schemaClass;
        if (isPolymorphicConfig(schemaClass) && polymorphicExtensions.isEmpty()) {
            throw new IllegalArgumentException(schemaClass + " is polymorphic but polymorphic extensions are absent");
        }
        List<Field> schemaFields = schemaFields(schemaClass);
        Collection<Field> internalExtensionsFields = extensionsFields(internalExtensions, true);
        Collection<Field> polymorphicExtensionsFields = extensionsFields(polymorphicExtensions, false);
        Field internalIdField = internalIdField(schemaClass, internalExtensions);
        for (Field schemaField : concat(schemaFields, internalExtensionsFields, polymorphicExtensionsFields)) {
            if (isConfigValue(schemaField) || isNamedConfigValue(schemaField)) {
                Class<?> subSchemaClass = schemaField.getType();
                if (!schemasInfo.containsKey(subSchemaClass)) {
                    compileQueue.offer(subSchemaClass);
                    schemasInfo.put(subSchemaClass, new SchemaClassesInfo(subSchemaClass));
                }
            }
        }
        for (Class<?> polymorphicExtension : polymorphicExtensions) {
            schemasInfo.put(polymorphicExtension, new SchemaClassesInfo(polymorphicExtension));
        }
        schemas.add(schemaClass);
        ClassDefinition innerNodeClassDef = createNodeClass(schemaClass, internalExtensions, polymorphicExtensions, schemaFields, internalExtensionsFields, polymorphicExtensionsFields, internalIdField);
        classDefs.add(innerNodeClassDef);
        ClassDefinition cfgImplClassDef = createCfgImplClass(schemaClass, internalExtensions, polymorphicExtensions, schemaFields, internalExtensionsFields, polymorphicExtensionsFields, internalIdField);
        classDefs.add(cfgImplClassDef);
        for (Class<?> polymorphicExtension : polymorphicExtensions) {
            // Only the fields of a specific instance of a polymorphic configuration.
            Collection<Field> polymorphicFields = polymorphicExtensionsFields.stream().filter(f -> f.getDeclaringClass() == polymorphicExtension).collect(toList());
            classDefs.add(createPolymorphicExtensionNodeClass(schemaClass, polymorphicExtension, innerNodeClassDef, schemaFields, polymorphicFields, internalIdField));
            classDefs.add(createPolymorphicExtensionCfgImplClass(schemaClass, polymorphicExtension, cfgImplClassDef, schemaFields, polymorphicFields, internalIdField));
        }
        ClassDefinition directProxyClassDef = new DirectProxyAsmGenerator(this, schemaClass, internalExtensions, schemaFields, internalExtensionsFields, internalIdField).generate();
        classDefs.add(directProxyClassDef);
    }
    Map<String, Class<?>> definedClasses = generator.defineClasses(classDefs);
    for (Class<?> schemaClass : schemas) {
        SchemaClassesInfo info = schemasInfo.get(schemaClass);
        info.nodeClass = (Class<? extends InnerNode>) definedClasses.get(info.nodeClassName);
        info.cfgImplClass = (Class<? extends DynamicConfiguration<?, ?>>) definedClasses.get(info.cfgImplClassName);
    }
}
Also used : PolymorphicId(org.apache.ignite.configuration.annotation.PolymorphicId) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression) Arrays(java.util.Arrays) DirectPropertyProxy(org.apache.ignite.internal.configuration.direct.DirectPropertyProxy) BytecodeExpressions.isNotNull(com.facebook.presto.bytecode.expression.BytecodeExpressions.isNotNull) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) ConfigurationUtil.isPolymorphicConfigInstance(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isPolymorphicConfigInstance) NamedConfigValue(org.apache.ignite.configuration.annotation.NamedConfigValue) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) DirectProxyAsmGenerator.newDirectProxyLambda(org.apache.ignite.internal.configuration.asm.DirectProxyAsmGenerator.newDirectProxyLambda) NamedConfigurationTree(org.apache.ignite.configuration.NamedConfigurationTree) IfStatement(com.facebook.presto.bytecode.control.IfStatement) DynamicConfigurationChanger(org.apache.ignite.internal.configuration.DynamicConfigurationChanger) Variable(com.facebook.presto.bytecode.Variable) DynamicConfiguration(org.apache.ignite.internal.configuration.DynamicConfiguration) Type.getType(org.objectweb.asm.Type.getType) Set(java.util.Set) BytecodeExpressions.constantBoolean(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantBoolean) ConfigurationUtil.isConfigValue(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isConfigValue) Serializable(java.io.Serializable) ConfigurationUtil.isPolymorphicId(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isPolymorphicId) FINAL(com.facebook.presto.bytecode.Access.FINAL) Stream(java.util.stream.Stream) Config(org.apache.ignite.configuration.annotation.Config) ConfigurationSource(org.apache.ignite.internal.configuration.tree.ConfigurationSource) ConfigurationUtil(org.apache.ignite.internal.configuration.util.ConfigurationUtil) BytecodeExpressions.invokeStatic(com.facebook.presto.bytecode.expression.BytecodeExpressions.invokeStatic) MethodHandle(java.lang.invoke.MethodHandle) CollectionUtils.concat(org.apache.ignite.internal.util.CollectionUtils.concat) SYNTHETIC(com.facebook.presto.bytecode.Access.SYNTHETIC) NamedListNode(org.apache.ignite.internal.configuration.tree.NamedListNode) Constructor(java.lang.reflect.Constructor) Supplier(java.util.function.Supplier) ConfigurationTree(org.apache.ignite.configuration.ConfigurationTree) InnerNode(org.apache.ignite.internal.configuration.tree.InnerNode) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Lookup(java.lang.invoke.MethodHandles.Lookup) PolymorphicConfig(org.apache.ignite.configuration.annotation.PolymorphicConfig) H_NEWINVOKESPECIAL(org.objectweb.asm.Opcodes.H_NEWINVOKESPECIAL) BytecodeExpressions.constantNull(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantNull) BytecodeExpressions.set(com.facebook.presto.bytecode.expression.BytecodeExpressions.set) Opcodes(org.objectweb.asm.Opcodes) SchemaClassesInfo.viewClassName(org.apache.ignite.internal.configuration.asm.SchemaClassesInfo.viewClassName) ConfigurationUtil.polymorphicInstanceId(org.apache.ignite.internal.configuration.util.ConfigurationUtil.polymorphicInstanceId) NamedListView(org.apache.ignite.configuration.NamedListView) Field(java.lang.reflect.Field) BytecodeExpressions.constantString(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantString) Handle(org.objectweb.asm.Handle) Type.getMethodDescriptor(org.objectweb.asm.Type.getMethodDescriptor) BytecodeExpressions.isNull(com.facebook.presto.bytecode.expression.BytecodeExpressions.isNull) EnumSet.of(java.util.EnumSet.of) ArrayDeque(java.util.ArrayDeque) ConfigurationUtil.isInternalId(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isInternalId) ParameterizedType(com.facebook.presto.bytecode.ParameterizedType) ArrayUtils.nullOrEmpty(org.apache.ignite.internal.util.ArrayUtils.nullOrEmpty) BytecodeExpressions.newArray(com.facebook.presto.bytecode.expression.BytecodeExpressions.newArray) LambdaMetafactory(java.lang.invoke.LambdaMetafactory) BiFunction(java.util.function.BiFunction) ConstructableTreeNode(org.apache.ignite.internal.configuration.tree.ConstructableTreeNode) BytecodeExpressions.invokeDynamic(com.facebook.presto.bytecode.expression.BytecodeExpressions.invokeDynamic) Type(org.objectweb.asm.Type) Collections.singleton(java.util.Collections.singleton) Collectors.toMap(java.util.stream.Collectors.toMap) ParameterizedType.type(com.facebook.presto.bytecode.ParameterizedType.type) ParameterizedType.typeFromJavaClassName(com.facebook.presto.bytecode.ParameterizedType.typeFromJavaClassName) ConfigurationUtil.isInjectedName(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isInjectedName) ConfigurationNode(org.apache.ignite.internal.configuration.ConfigurationNode) Method(java.lang.reflect.Method) ConfigurationProperty(org.apache.ignite.configuration.ConfigurationProperty) Name(org.apache.ignite.configuration.annotation.Name) Collections.emptyList(java.util.Collections.emptyList) Collection(java.util.Collection) NamedListConfiguration(org.apache.ignite.internal.configuration.NamedListConfiguration) TypeUtils(org.apache.ignite.internal.configuration.TypeUtils) UUID(java.util.UUID) RootKey(org.apache.ignite.configuration.RootKey) SchemaClassesInfo.nodeClassName(org.apache.ignite.internal.configuration.asm.SchemaClassesInfo.nodeClassName) SchemaClassesInfo.configurationClassName(org.apache.ignite.internal.configuration.asm.SchemaClassesInfo.configurationClassName) Objects(java.util.Objects) Nullable(org.jetbrains.annotations.Nullable) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) List(java.util.List) Type.getMethodType(org.objectweb.asm.Type.getMethodType) Function.identity(java.util.function.Function.identity) Queue(java.util.Queue) NotNull(org.jetbrains.annotations.NotNull) Parameter.arg(com.facebook.presto.bytecode.Parameter.arg) ConfigurationUtil.schemaFields(org.apache.ignite.internal.configuration.util.ConfigurationUtil.schemaFields) DynamicProperty(org.apache.ignite.internal.configuration.DynamicProperty) BytecodeExpressions.constantInt(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantInt) ConfigurationVisitor(org.apache.ignite.internal.configuration.tree.ConfigurationVisitor) PRIVATE(com.facebook.presto.bytecode.Access.PRIVATE) ConfigurationUtil.containsNameAnnotation(org.apache.ignite.internal.configuration.util.ConfigurationUtil.containsNameAnnotation) HashMap(java.util.HashMap) ConfigurationUtil.isNamedConfigValue(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isNamedConfigValue) BytecodeExpressions.not(com.facebook.presto.bytecode.expression.BytecodeExpressions.not) Function(java.util.function.Function) HashSet(java.util.HashSet) Collectors.toCollection(java.util.stream.Collectors.toCollection) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) NoSuchElementException(java.util.NoSuchElementException) BytecodeExpressions.constantClass(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantClass) ConfigurationUtil.extensionsFields(org.apache.ignite.internal.configuration.util.ConfigurationUtil.extensionsFields) MethodType.methodType(java.lang.invoke.MethodType.methodType) PUBLIC(com.facebook.presto.bytecode.Access.PUBLIC) BytecodeExpressions.inlineIf(com.facebook.presto.bytecode.expression.BytecodeExpressions.inlineIf) ConfigurationRoot(org.apache.ignite.configuration.annotation.ConfigurationRoot) CollectionUtils.union(org.apache.ignite.internal.util.CollectionUtils.union) SchemaClassesInfo.changeClassName(org.apache.ignite.internal.configuration.asm.SchemaClassesInfo.changeClassName) ClassGenerator(com.facebook.presto.bytecode.ClassGenerator) BytecodeExpressions.newInstance(com.facebook.presto.bytecode.expression.BytecodeExpressions.newInstance) ConfigurationUtil.isPolymorphicConfig(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isPolymorphicConfig) ConfigurationValue(org.apache.ignite.configuration.ConfigurationValue) Consumer(java.util.function.Consumer) Collectors.toList(java.util.stream.Collectors.toList) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) STATIC(com.facebook.presto.bytecode.Access.STATIC) MethodType(java.lang.invoke.MethodType) InjectedName(org.apache.ignite.configuration.annotation.InjectedName) ConfigurationUtil.isValue(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isValue) PolymorphicConfigInstance(org.apache.ignite.configuration.annotation.PolymorphicConfigInstance) FieldDefinition(com.facebook.presto.bytecode.FieldDefinition) BRIDGE(com.facebook.presto.bytecode.Access.BRIDGE) ConfigurationUtil.hasDefault(org.apache.ignite.internal.configuration.util.ConfigurationUtil.hasDefault) Collections(java.util.Collections) ConfigurationTreeWrapper(org.apache.ignite.internal.configuration.ConfigurationTreeWrapper) ConfigurationWrongPolymorphicTypeIdException(org.apache.ignite.configuration.ConfigurationWrongPolymorphicTypeIdException) InternalConfiguration(org.apache.ignite.configuration.annotation.InternalConfiguration) ArrayList(java.util.ArrayList) BytecodeExpressions.constantString(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantString) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) ArrayDeque(java.util.ArrayDeque) Field(java.lang.reflect.Field) BytecodeExpressions.constantClass(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantClass) HashSet(java.util.HashSet)

Example 2 with PolymorphicConfig

use of org.apache.ignite.configuration.annotation.PolymorphicConfig in project ignite-3 by apache.

the class ConfigurationUtil method collectSchemas.

/**
 * Collect all configuration schemas with {@link ConfigurationRoot}, {@link Config} or {@link PolymorphicConfig} including all sub
 * configuration schemas for fields with {@link ConfigValue} or {@link NamedConfigValue}.
 *
 * @param schemaClasses Configuration schemas (starting points) with {@link ConfigurationRoot}, {@link Config} or {@link
 *                      PolymorphicConfig}.
 * @return All configuration schemas with {@link ConfigurationRoot}, {@link Config}, or {@link PolymorphicConfig}.
 * @throws IllegalArgumentException If the configuration schemas does not contain {@link ConfigurationRoot}, {@link Config} or {@link
 *                                  PolymorphicConfig}.
 */
public static Set<Class<?>> collectSchemas(Collection<Class<?>> schemaClasses) {
    if (schemaClasses.isEmpty()) {
        return Set.of();
    }
    Set<Class<?>> res = new HashSet<>();
    Queue<Class<?>> queue = new ArrayDeque<>(Set.copyOf(schemaClasses));
    while (!queue.isEmpty()) {
        Class<?> cls = queue.poll();
        if (!cls.isAnnotationPresent(ConfigurationRoot.class) && !cls.isAnnotationPresent(Config.class) && !cls.isAnnotationPresent(InternalConfiguration.class) && !cls.isAnnotationPresent(PolymorphicConfig.class) && !cls.isAnnotationPresent(PolymorphicConfigInstance.class)) {
            throw new IllegalArgumentException(String.format("Configuration schema must contain one of @%s, @%s, @%s, @%s, @%s: %s", ConfigurationRoot.class.getSimpleName(), Config.class.getSimpleName(), InternalConfiguration.class.getSimpleName(), PolymorphicConfig.class.getSimpleName(), PolymorphicConfigInstance.class.getSimpleName(), cls.getName()));
        } else {
            res.add(cls);
            for (Field f : cls.getDeclaredFields()) {
                if ((f.isAnnotationPresent(ConfigValue.class) || f.isAnnotationPresent(NamedConfigValue.class)) && !res.contains(f.getType())) {
                    queue.add(f.getType());
                }
            }
        }
    }
    return res;
}
Also used : PolymorphicConfig(org.apache.ignite.configuration.annotation.PolymorphicConfig) NamedConfigValue(org.apache.ignite.configuration.annotation.NamedConfigValue) ConfigValue(org.apache.ignite.configuration.annotation.ConfigValue) Config(org.apache.ignite.configuration.annotation.Config) PolymorphicConfig(org.apache.ignite.configuration.annotation.PolymorphicConfig) ArrayDeque(java.util.ArrayDeque) Field(java.lang.reflect.Field) NamedConfigValue(org.apache.ignite.configuration.annotation.NamedConfigValue) ConfigurationRoot(org.apache.ignite.configuration.annotation.ConfigurationRoot) HashSet(java.util.HashSet)

Aggregations

BRIDGE (com.facebook.presto.bytecode.Access.BRIDGE)1 FINAL (com.facebook.presto.bytecode.Access.FINAL)1 PRIVATE (com.facebook.presto.bytecode.Access.PRIVATE)1 PUBLIC (com.facebook.presto.bytecode.Access.PUBLIC)1 STATIC (com.facebook.presto.bytecode.Access.STATIC)1 SYNTHETIC (com.facebook.presto.bytecode.Access.SYNTHETIC)1 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)1 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)1 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)1 ClassGenerator (com.facebook.presto.bytecode.ClassGenerator)1 FieldDefinition (com.facebook.presto.bytecode.FieldDefinition)1 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)1 Parameter.arg (com.facebook.presto.bytecode.Parameter.arg)1 ParameterizedType (com.facebook.presto.bytecode.ParameterizedType)1 ParameterizedType.type (com.facebook.presto.bytecode.ParameterizedType.type)1 ParameterizedType.typeFromJavaClassName (com.facebook.presto.bytecode.ParameterizedType.typeFromJavaClassName)1 Variable (com.facebook.presto.bytecode.Variable)1 IfStatement (com.facebook.presto.bytecode.control.IfStatement)1 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)1 BytecodeExpressions.constantBoolean (com.facebook.presto.bytecode.expression.BytecodeExpressions.constantBoolean)1