Search in sources :

Example 6 with ConfigurationSource

use of org.apache.ignite.internal.configuration.tree.ConfigurationSource in project ignite-3 by apache.

the class ConfigurationChangerTest method source.

private static <CHANGET> ConfigurationSource source(RootKey<?, ? super CHANGET> rootKey, Consumer<CHANGET> changer) {
    return new ConfigurationSource() {

        @Override
        public void descend(ConstructableTreeNode node) {
            ConfigurationSource changerSrc = new ConfigurationSource() {

                @Override
                public void descend(ConstructableTreeNode node) {
                    changer.accept((CHANGET) node);
                }
            };
            node.construct(rootKey.key(), changerSrc, true);
        }
    };
}
Also used : ConfigurationSource(org.apache.ignite.internal.configuration.tree.ConfigurationSource) ConstructableTreeNode(org.apache.ignite.internal.configuration.tree.ConstructableTreeNode)

Example 7 with ConfigurationSource

use of org.apache.ignite.internal.configuration.tree.ConfigurationSource in project ignite-3 by apache.

the class ConfigurationExtension method cfgValue.

/**
 * Instantiates a configuration instance for injection.
 *
 * @param type Type of the field or parameter. Class name must end with {@code Configuration}.
 * @param annotation Annotation present on the field or parameter.
 * @param cgen Runtime code generator associated with the extension instance.
 * @param pool Single-threaded executor service to perform configuration changes.
 * @param revisionListenerHolder Configuration storage revision change listener holder.
 * @return Mock configuration instance.
 * @throws ClassNotFoundException If corresponding configuration schema class is not found.
 */
private static Object cfgValue(Class<?> type, InjectConfiguration annotation, ConfigurationAsmGenerator cgen, ExecutorService pool, StorageRevisionListenerHolderImpl revisionListenerHolder) throws ClassNotFoundException {
    // Trying to find a schema class using configuration naming convention. This code won't work for inner Java
    // classes, extension is designed to mock actual configurations from public API to configure Ignite components.
    Class<?> schemaClass = Class.forName(type.getCanonicalName() + "Schema");
    cgen.compileRootSchema(schemaClass, internalSchemaExtensions(List.of(annotation.internalExtensions())), polymorphicSchemaExtensions(List.of(annotation.polymorphicExtensions())));
    // RootKey must be mocked, there's no way to instantiate it using a public constructor.
    RootKey rootKey = mock(RootKey.class);
    when(rootKey.key()).thenReturn("mock");
    when(rootKey.type()).thenReturn(LOCAL);
    when(rootKey.schemaClass()).thenReturn(schemaClass);
    when(rootKey.internal()).thenReturn(false);
    SuperRoot superRoot = new SuperRoot(s -> new RootInnerNode(rootKey, cgen.instantiateNode(schemaClass)));
    ConfigObject hoconCfg = ConfigFactory.parseString(annotation.value()).root();
    HoconConverter.hoconSource(hoconCfg).descend(superRoot);
    ConfigurationUtil.addDefaults(superRoot);
    // Reference to the super root is required to make DynamicConfigurationChanger#change method atomic.
    var superRootRef = new AtomicReference<>(superRoot);
    // Reference that's required for notificator.
    var cfgRef = new AtomicReference<DynamicConfiguration<?, ?>>();
    cfgRef.set(cgen.instantiateCfg(rootKey, new DynamicConfigurationChanger() {

        /**
         * {@inheritDoc}
         */
        @Override
        public CompletableFuture<Void> change(ConfigurationSource change) {
            return CompletableFuture.supplyAsync(() -> {
                SuperRoot sr = superRootRef.get();
                SuperRoot copy = sr.copy();
                change.descend(copy);
                ConfigurationUtil.dropNulls(copy);
                if (superRootRef.compareAndSet(sr, copy)) {
                    long storageRevision = revisionListenerHolder.storageRev.incrementAndGet();
                    long notificationNumber = revisionListenerHolder.notificationListenerCnt.incrementAndGet();
                    List<CompletableFuture<?>> futures = new ArrayList<>();
                    futures.addAll(notifyListeners(sr.getRoot(rootKey), copy.getRoot(rootKey), (DynamicConfiguration<InnerNode, ?>) cfgRef.get(), storageRevision, notificationNumber));
                    futures.addAll(revisionListenerHolder.notifyStorageRevisionListeners(storageRevision, notificationNumber));
                    return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
                }
                return change(change);
            }, pool).thenCompose(Function.identity());
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public InnerNode getRootNode(RootKey<?, ?> rk) {
            return superRootRef.get().getRoot(rk);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public <T> T getLatest(List<KeyPathNode> path) {
            return findEx(path, superRootRef.get());
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public long notificationCount() {
            return revisionListenerHolder.notificationListenerCnt.get();
        }
    }));
    touch(cfgRef.get());
    return cfgRef.get();
}
Also used : ConfigurationSource(org.apache.ignite.internal.configuration.tree.ConfigurationSource) RootKey(org.apache.ignite.configuration.RootKey) SuperRoot(org.apache.ignite.internal.configuration.SuperRoot) AtomicReference(java.util.concurrent.atomic.AtomicReference) DynamicConfigurationChanger(org.apache.ignite.internal.configuration.DynamicConfigurationChanger) RootInnerNode(org.apache.ignite.internal.configuration.RootInnerNode) InnerNode(org.apache.ignite.internal.configuration.tree.InnerNode) RootInnerNode(org.apache.ignite.internal.configuration.RootInnerNode) ArrayList(java.util.ArrayList) List(java.util.List) ConfigObject(com.typesafe.config.ConfigObject)

Example 8 with ConfigurationSource

use of org.apache.ignite.internal.configuration.tree.ConfigurationSource in project ignite-3 by apache.

the class ConfigurationAsmGenerator method addNodeConstructMethod.

/**
 * Implements {@link ConstructableTreeNode#construct(String, ConfigurationSource, boolean)} method.
 *
 * @param classDef                     Class definition.
 * @param fieldDefs                    Definitions for all fields in {@code schemaFields}.
 * @param schemaFields                 Fields of the schema class.
 * @param internalFields               Fields of internal extensions of the configuration schema.
 * @param polymorphicFieldsByExtension Fields of polymorphic configuration instances grouped by them.
 * @param polymorphicTypeIdFieldDef    Identification field for the polymorphic configuration instance.
 * @param changePolymorphicTypeIdMtd   Method for changing the type of polymorphic configuration.
 */
private void addNodeConstructMethod(ClassDefinition classDef, Map<String, FieldDefinition> fieldDefs, Collection<Field> schemaFields, Collection<Field> internalFields, Map<Class<?>, List<Field>> polymorphicFieldsByExtension, @Nullable FieldDefinition polymorphicTypeIdFieldDef, @Nullable MethodDefinition changePolymorphicTypeIdMtd) {
    MethodDefinition constructMtd = classDef.declareMethod(of(PUBLIC), "construct", type(void.class), arg("key", type(String.class)), arg("src", type(ConfigurationSource.class)), arg("includeInternal", type(boolean.class))).addException(NoSuchElementException.class);
    Variable keyVar = constructMtd.getScope().getVariable("key");
    Variable srcVar = constructMtd.getScope().getVariable("src");
    // Create switch for public (common in case polymorphic config) fields only.
    StringSwitchBuilder switchBuilder = new StringSwitchBuilder(constructMtd.getScope()).expression(keyVar);
    for (Field schemaField : schemaFields) {
        if (isInjectedName(schemaField)) {
            continue;
        }
        String fieldName = fieldName(schemaField);
        FieldDefinition fieldDef = fieldDefs.get(fieldName);
        if (isPolymorphicId(schemaField)) {
            // src == null ? null : src.unwrap(FieldType.class);
            BytecodeExpression getTypeIdFromSrcVar = inlineIf(isNull(srcVar), constantNull(fieldDef.getType()), srcVar.invoke(UNWRAP, constantClass(fieldDef.getType())).cast(fieldDef.getType()));
            // this.changePolymorphicTypeId(src == null ? null : src.unwrap(FieldType.class));
            switchBuilder.addCase(fieldName, new BytecodeBlock().append(constructMtd.getThis()).append(getTypeIdFromSrcVar).invokeVirtual(changePolymorphicTypeIdMtd).ret());
        } else {
            switchBuilder.addCase(fieldName, treatSourceForConstruct(constructMtd, schemaField, fieldDef).ret());
        }
    }
    if (!internalFields.isEmpty()) {
        // Create switch for public + internal fields.
        StringSwitchBuilder switchBuilderAllFields = new StringSwitchBuilder(constructMtd.getScope()).expression(keyVar).defaultCase(throwException(NoSuchElementException.class, keyVar));
        for (Field schemaField : union(schemaFields, internalFields)) {
            if (isInjectedName(schemaField)) {
                continue;
            }
            String fieldName = fieldName(schemaField);
            switchBuilderAllFields.addCase(fieldName, treatSourceForConstruct(constructMtd, schemaField, fieldDefs.get(fieldName)).ret());
        }
        // if (includeInternal) switch_by_all_fields
        // else switch_only_public_fields
        constructMtd.getBody().append(new IfStatement().condition(constructMtd.getScope().getVariable("includeInternal")).ifTrue(switchBuilderAllFields.build()).ifFalse(switchBuilder.defaultCase(throwException(NoSuchElementException.class, keyVar)).build())).ret();
    } else if (!polymorphicFieldsByExtension.isEmpty()) {
        assert polymorphicTypeIdFieldDef != null : classDef.getName();
        // Create switch by polymorphicTypeIdField.
        StringSwitchBuilder switchBuilderTypeId = typeIdSwitchBuilder(constructMtd, polymorphicTypeIdFieldDef);
        for (Map.Entry<Class<?>, List<Field>> e : polymorphicFieldsByExtension.entrySet()) {
            // Create switch for specific polymorphic instance.
            StringSwitchBuilder switchBuilderPolymorphicExtension = new StringSwitchBuilder(constructMtd.getScope()).expression(keyVar).defaultCase(throwException(NoSuchElementException.class, keyVar));
            for (Field polymorphicField : e.getValue()) {
                String fieldName = fieldName(polymorphicField);
                FieldDefinition fieldDef = fieldDefs.get(fieldName);
                switchBuilderPolymorphicExtension.addCase(polymorphicField.getName(), treatSourceForConstruct(constructMtd, polymorphicField, fieldDef).ret());
            }
            switchBuilderTypeId.addCase(polymorphicInstanceId(e.getKey()), switchBuilderPolymorphicExtension.build());
        }
        // switch_by_common_fields
        // switch_by_polymorphicTypeIdField
        // switch_by_polymorphic_0_fields
        // switch_by_polymorphic_1_fields
        // ...
        constructMtd.getBody().append(switchBuilder.defaultCase(new BytecodeBlock()).build()).append(switchBuilderTypeId.build()).ret();
    } else {
        constructMtd.getBody().append(switchBuilder.defaultCase(throwException(NoSuchElementException.class, keyVar)).build()).ret();
    }
}
Also used : Field(java.lang.reflect.Field) IfStatement(com.facebook.presto.bytecode.control.IfStatement) ConfigurationSource(org.apache.ignite.internal.configuration.tree.ConfigurationSource) Variable(com.facebook.presto.bytecode.Variable) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) FieldDefinition(com.facebook.presto.bytecode.FieldDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) BytecodeExpressions.constantString(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantString) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression) NoSuchElementException(java.util.NoSuchElementException)

Example 9 with ConfigurationSource

use of org.apache.ignite.internal.configuration.tree.ConfigurationSource in project ignite-3 by apache.

the class DynamicProperty method update.

/**
 * {@inheritDoc}
 */
@Override
public CompletableFuture<Void> update(T newValue) {
    Objects.requireNonNull(newValue, "Configuration value cannot be null.");
    if (listenOnly) {
        throw listenOnlyException();
    }
    if (readOnly) {
        throw new ConfigurationReadOnlyException("Read only mode: " + keys);
    }
    assert keys instanceof RandomAccess;
    assert !keys.isEmpty();
    ConfigurationSource src = new ConfigurationSource() {

        /**
         * Current index in the {@code keys}.
         */
        private int level = 0;

        /**
         * {@inheritDoc}
         */
        @Override
        public void descend(ConstructableTreeNode node) {
            assert level < keys.size();
            node.construct(keys.get(level++), this, true);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public <T> T unwrap(Class<T> clazz) {
            assert level == keys.size();
            assert clazz.isInstance(newValue);
            return clazz.cast(newValue);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void reset() {
            level = 0;
        }
    };
    // Use resulting tree as update request for the storage.
    return changer.change(src);
}
Also used : ConfigurationSource(org.apache.ignite.internal.configuration.tree.ConfigurationSource) ConfigurationReadOnlyException(org.apache.ignite.configuration.ConfigurationReadOnlyException) RandomAccess(java.util.RandomAccess) ConstructableTreeNode(org.apache.ignite.internal.configuration.tree.ConstructableTreeNode)

Aggregations

ConfigurationSource (org.apache.ignite.internal.configuration.tree.ConfigurationSource)9 ConstructableTreeNode (org.apache.ignite.internal.configuration.tree.ConstructableTreeNode)7 List (java.util.List)4 NoSuchElementException (java.util.NoSuchElementException)4 ExecutionException (java.util.concurrent.ExecutionException)4 TimeoutException (java.util.concurrent.TimeoutException)4 ConfigurationChangeException (org.apache.ignite.configuration.ConfigurationChangeException)4 RootKey (org.apache.ignite.configuration.RootKey)4 Serializable (java.io.Serializable)3 FIELD (java.lang.annotation.ElementType.FIELD)3 Retention (java.lang.annotation.Retention)3 RUNTIME (java.lang.annotation.RetentionPolicy.RUNTIME)3 Target (java.lang.annotation.Target)3 Arrays (java.util.Arrays)3 Map (java.util.Map)3 Set (java.util.Set)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 SECONDS (java.util.concurrent.TimeUnit.SECONDS)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 Consumer (java.util.function.Consumer)3