use of org.apache.ignite.internal.configuration.tree.InnerNode in project ignite-3 by apache.
the class ConfigurationUtilTest method testFlattenedMapPolymorphicNamedConfig.
@Test
void testFlattenedMapPolymorphicNamedConfig() {
InnerNode polymorphicRootInnerNode = newNodeInstance(PolymorphicRootConfigurationSchema.class);
PolymorphicRootChange polymorphicRootChange = ((PolymorphicRootChange) polymorphicRootInnerNode);
polymorphicRootChange.changePolymorphicNamedCfg(c -> c.create("0", c1 -> {
}));
addDefaults(polymorphicRootInnerNode);
RootKey<?, ?> rootKey = PolymorphicRootConfiguration.KEY;
SuperRoot superRoot = new SuperRoot(key -> null, Map.of(rootKey, polymorphicRootInnerNode));
final Map<String, Serializable> act = flattenedMap(superRoot, rootKey, node -> ((PolymorphicRootChange) node).changePolymorphicNamedCfg(c -> c.createOrUpdate("0", c1 -> c1.convert(SecondPolymorphicInstanceChange.class))));
NamedListNode<?> polymorphicNamedCfgListNode = (NamedListNode<?>) polymorphicRootChange.polymorphicNamedCfg();
UUID internalId = polymorphicNamedCfgListNode.internalId("0");
Map<String, Serializable> exp = new HashMap<>();
exp.put("rootPolymorphic.polymorphicNamedCfg." + internalId + ".typeId", "second");
exp.put("rootPolymorphic.polymorphicNamedCfg." + internalId + ".longVal", 0L);
exp.put("rootPolymorphic.polymorphicNamedCfg." + internalId + ".strVal", null);
exp.put("rootPolymorphic.polymorphicNamedCfg." + internalId + ".intVal", 0);
assertEquals(exp, act);
}
use of org.apache.ignite.internal.configuration.tree.InnerNode 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);
}
}
use of org.apache.ignite.internal.configuration.tree.InnerNode in project ignite-3 by apache.
the class ConfigurationAsmGenerator method addCfgAddMembersMethod.
/**
* Adds a {@code DynamicConfiguration#addMembers} override for the polymorphic configuration case.
*
* @param classDef Definition of a polymorphic configuration class (parent).
* @param schemaClass Polymorphic configuration schema (parent).
* @param polymorphicExtensions Polymorphic configuration instance schemas (children).
* @param fieldDefs Field definitions for all fields of {@code classDef}.
* @param polymorphicFields Fields of polymorphic extensions.
* @param polymorphicTypeIdFieldDef Identification field for the polymorphic configuration instance.
*/
private void addCfgAddMembersMethod(ClassDefinition classDef, Class<?> schemaClass, Set<Class<?>> polymorphicExtensions, Map<String, FieldDefinition> fieldDefs, Collection<Field> polymorphicFields, FieldDefinition polymorphicTypeIdFieldDef) {
MethodDefinition removeMembersMtd = classDef.declareMethod(of(PUBLIC), "addMembers", type(void.class), arg("newValue", type(Object.class)), arg("members", type(Map.class)));
// InnerNode newValue;
Variable newValueVar = removeMembersMtd.getScope().getVariable("newValue");
// Map members;
Variable membersVar = removeMembersMtd.getScope().getVariable("members");
// String tmpStr;
Variable tmpStrVar = removeMembersMtd.getScope().createTempVariable(String.class);
StringSwitchBuilder switchBuilder = new StringSwitchBuilder(removeMembersMtd.getScope()).expression(tmpStrVar).defaultCase(throwException(ConfigurationWrongPolymorphicTypeIdException.class, tmpStrVar));
for (Class<?> polymorphicExtension : polymorphicExtensions) {
Collection<Field> addFields = polymorphicFields.stream().filter(f -> polymorphicExtension.equals(f.getDeclaringClass())).collect(toList());
BytecodeBlock blockCode = new BytecodeBlock();
for (Field addField : addFields) {
// this.addMember(members, this.field);
blockCode.append(removeMembersMtd.getThis()).append(membersVar).append(getThisFieldCode(removeMembersMtd, fieldDefs.get(fieldName(addField)))).invokeVirtual(ADD_MEMBER_MTD);
}
switchBuilder.addCase(polymorphicInstanceId(polymorphicExtension), blockCode);
}
// ConfigNode
ParameterizedType nodeType = typeFromJavaClassName(schemasInfo.get(schemaClass).nodeClassName);
// tmpStr = ((ConfigNode) newValue).typeId;
// switch(tmpStr) ...
removeMembersMtd.getBody().append(tmpStrVar.set(newValueVar.cast(nodeType).getField(polymorphicTypeIdFieldDef.getName(), String.class))).append(switchBuilder.build()).ret();
}
use of org.apache.ignite.internal.configuration.tree.InnerNode in project ignite-3 by apache.
the class ConfigurationAsmGenerator method addCfgRemoveMembersMethod.
/**
* Adds a {@code DynamicConfiguration#removeMembers} override for the polymorphic configuration case.
*
* @param classDef Definition of a polymorphic configuration class (parent).
* @param schemaClass Polymorphic configuration schema (parent).
* @param polymorphicExtensions Polymorphic configuration instance schemas (children).
* @param fieldDefs Field definitions for all fields of {@code classDef}.
* @param polymorphicFields Fields of polymorphic extensions.
* @param polymorphicTypeIdFieldDef Identification field for the polymorphic configuration instance.
*/
private void addCfgRemoveMembersMethod(ClassDefinition classDef, Class<?> schemaClass, Set<Class<?>> polymorphicExtensions, Map<String, FieldDefinition> fieldDefs, Collection<Field> polymorphicFields, FieldDefinition polymorphicTypeIdFieldDef) {
MethodDefinition removeMembersMtd = classDef.declareMethod(of(PUBLIC), "removeMembers", type(void.class), arg("oldValue", type(Object.class)), arg("members", type(Map.class)));
// InnerNode oldValue;
Variable oldValueVar = removeMembersMtd.getScope().getVariable("oldValue");
// Map members;
Variable membersVar = removeMembersMtd.getScope().getVariable("members");
// String tmpStr;
Variable tmpStrVar = removeMembersMtd.getScope().createTempVariable(String.class);
StringSwitchBuilder switchBuilder = new StringSwitchBuilder(removeMembersMtd.getScope()).expression(tmpStrVar).defaultCase(throwException(ConfigurationWrongPolymorphicTypeIdException.class, tmpStrVar));
for (Class<?> polymorphicExtension : polymorphicExtensions) {
Collection<Field> removeFields = polymorphicFields.stream().filter(f -> !polymorphicExtension.equals(f.getDeclaringClass())).collect(toList());
BytecodeBlock blockCode = new BytecodeBlock();
for (Field removeField : removeFields) {
// this.removeMember(members, this.field);
blockCode.append(removeMembersMtd.getThis()).append(membersVar).append(getThisFieldCode(removeMembersMtd, fieldDefs.get(fieldName(removeField)))).invokeVirtual(REMOVE_MEMBER_MTD);
}
switchBuilder.addCase(polymorphicInstanceId(polymorphicExtension), blockCode);
}
// ConfigNode
ParameterizedType nodeType = typeFromJavaClassName(schemasInfo.get(schemaClass).nodeClassName);
// tmpStr = ((ConfigNode) oldValue).typeId;
// switch(tmpStr) ...
removeMembersMtd.getBody().append(tmpStrVar.set(oldValueVar.cast(nodeType).getField(polymorphicTypeIdFieldDef.getName(), String.class))).append(switchBuilder.build()).ret();
}
use of org.apache.ignite.internal.configuration.tree.InnerNode in project ignite-3 by apache.
the class ConfigurationChanger method start.
/**
* Start component.
*/
// ConfigurationChangeException, really?
public void start() throws ConfigurationChangeException {
Data data;
try {
data = storage.readAll();
} catch (StorageException e) {
throw new ConfigurationChangeException("Failed to initialize configuration: " + e.getMessage(), e);
}
SuperRoot superRoot = new SuperRoot(rootCreator());
Map<String, ?> dataValuesPrefixMap = toPrefixMap(data.values());
for (RootKey<?, ?> rootKey : rootKeys.values()) {
Map<String, ?> rootPrefixMap = (Map<String, ?>) dataValuesPrefixMap.get(rootKey.key());
InnerNode rootNode = createRootNode(rootKey);
if (rootPrefixMap != null) {
fillFromPrefixMap(rootNode, rootPrefixMap);
}
superRoot.addRoot(rootKey, rootNode);
}
// Workaround for distributed configuration.
addDefaults(superRoot);
storageRoots = new StorageRoots(superRoot, data.changeId());
storage.registerConfigurationListener(this::updateFromListener);
}
Aggregations