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);
}
};
}
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();
}
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();
}
}
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);
}
Aggregations