use of org.apache.ignite.internal.configuration.SuperRoot in project ignite-3 by apache.
the class ConfigurationUtilTest method testSuperRootWithInternalConfig.
@Test
void testSuperRootWithInternalConfig() {
ConfigurationAsmGenerator generator = new ConfigurationAsmGenerator();
Class<?> schemaClass = InternalWithoutSuperclassConfigurationSchema.class;
RootKey<?, ?> schemaKey = InternalWithoutSuperclassConfiguration.KEY;
generator.compileRootSchema(schemaClass, Map.of(), Map.of());
SuperRoot superRoot = new SuperRoot(s -> new RootInnerNode(schemaKey, generator.instantiateNode(schemaClass)));
assertThrows(NoSuchElementException.class, () -> superRoot.construct(schemaKey.key(), null, false));
superRoot.construct(schemaKey.key(), null, true);
superRoot.addRoot(schemaKey, generator.instantiateNode(schemaClass));
assertThrows(KeyNotFoundException.class, () -> find(List.of(schemaKey.key()), superRoot, false));
assertNotNull(find(List.of(schemaKey.key()), superRoot, true));
Map<String, Object> config = (Map<String, Object>) superRoot.accept(schemaKey.key(), new ConverterToMapVisitor(false));
assertTrue(config.isEmpty());
config = (Map<String, Object>) superRoot.accept(schemaKey.key(), new ConverterToMapVisitor(true));
assertEquals(1, config.size());
assertNotNull(config.get(schemaKey.key()));
}
use of org.apache.ignite.internal.configuration.SuperRoot in project ignite-3 by apache.
the class ValidationUtilTest method validateNamedListNode.
@Test
public void validateNamedListNode() throws Exception {
var rootsNode = new SuperRoot(key -> null, Map.of(ValidatedRootConfiguration.KEY, root));
Validator<NamedListValidation, NamedListView<?>> validator = new Validator<>() {
@Override
public void validate(NamedListValidation annotation, ValidationContext<NamedListView<?>> ctx) {
assertEquals("root.elements", ctx.currentKey());
assertEquals(List.of(), ctx.getOldValue().namedListKeys());
assertEquals(List.of(), ctx.getNewValue().namedListKeys());
ctx.addIssue(new ValidationIssue("bar"));
}
};
Map<Class<? extends Annotation>, Set<Validator<?, ?>>> validators = Map.of(NamedListValidation.class, Set.of(validator));
List<ValidationIssue> issues = ValidationUtil.validate(rootsNode, rootsNode, null, new HashMap<>(), validators);
assertEquals(1, issues.size());
assertEquals("bar", issues.get(0).message());
}
use of org.apache.ignite.internal.configuration.SuperRoot 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();
}
Aggregations