blob: 72a5c834c8100b78d445ef7c07e86c9efc132be4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ignite.internal.configuration.asm;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.UUID;
import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.ConfigValue;
import org.apache.ignite.configuration.annotation.ConfigurationRoot;
import org.apache.ignite.configuration.annotation.InternalConfiguration;
import org.apache.ignite.configuration.annotation.NamedConfigValue;
import org.apache.ignite.configuration.annotation.Value;
import org.apache.ignite.internal.configuration.ConfigurationChanger;
import org.apache.ignite.internal.configuration.DynamicConfiguration;
import org.apache.ignite.internal.configuration.TestConfigurationChanger;
import org.apache.ignite.internal.configuration.storage.TestConfigurationStorage;
import org.apache.ignite.internal.configuration.tree.InnerNode;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.addDefaults;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Testing the {@link ConfigurationAsmGenerator}.
*/
public class ConfigurationAsmGeneratorTest {
/** Configuration changer. */
private static ConfigurationChanger changer;
/** Configuration generator. */
private static ConfigurationAsmGenerator generator;
/** */
@BeforeAll
public static void beforeAll() {
Collection<Class<?>> extensions = List.of(
ExtendedTestRootConfigurationSchema.class,
ExtendedSecondTestRootConfigurationSchema.class,
ExtendedTestConfigurationSchema.class,
ExtendedSecondTestConfigurationSchema.class
);
generator = new ConfigurationAsmGenerator();
changer = new TestConfigurationChanger(
generator,
List.of(TestRootConfiguration.KEY),
Map.of(),
new TestConfigurationStorage(LOCAL),
extensions
);
changer.start();
changer.initializeDefaults();
}
/** */
@AfterAll
public static void after() {
changer.stop();
generator = null;
changer = null;
}
/** */
@Test
void testExtendedRootConfiguration() throws Exception {
DynamicConfiguration<?, ?> config = generator.instantiateCfg(TestRootConfiguration.KEY, changer);
TestRootConfiguration baseRootConfig = (TestRootConfiguration)config;
ExtendedTestRootConfiguration extendedRootConfig = (ExtendedTestRootConfiguration)config;
ExtendedSecondTestRootConfiguration extendedSecondRootConfig = (ExtendedSecondTestRootConfiguration)config;
assertSame(baseRootConfig.i0(), extendedRootConfig.i0());
assertSame(baseRootConfig.i0(), extendedSecondRootConfig.i0());
assertSame(baseRootConfig.str0(), extendedRootConfig.str0());
assertSame(baseRootConfig.str0(), extendedSecondRootConfig.str0());
assertSame(baseRootConfig.subCfg(), extendedRootConfig.subCfg());
assertSame(baseRootConfig.subCfg(), extendedSecondRootConfig.subCfg());
assertSame(baseRootConfig.namedCfg(), extendedRootConfig.namedCfg());
assertSame(baseRootConfig.namedCfg(), extendedSecondRootConfig.namedCfg());
assertNotNull(extendedSecondRootConfig.i1());
// Check view and change interfaces.
assertTrue(baseRootConfig.value() instanceof ExtendedTestRootView);
assertTrue(baseRootConfig.value() instanceof ExtendedSecondTestRootView);
assertSame(baseRootConfig.value(), extendedRootConfig.value());
assertSame(baseRootConfig.value(), extendedSecondRootConfig.value());
baseRootConfig.change(c -> {
assertTrue(c instanceof ExtendedTestRootChange);
assertTrue(c instanceof ExtendedSecondTestRootChange);
c.changeI0(10).changeStr0("str0");
((ExtendedTestRootChange)c).changeStr1("str1").changeStr0("str0");
((ExtendedSecondTestRootChange)c).changeI1(200).changeStr0("str0");
}).get(1, SECONDS);
}
/** */
@Test
void testExtendedSubConfiguration() throws Exception {
DynamicConfiguration<?, ?> config = generator.instantiateCfg(TestRootConfiguration.KEY, changer);
TestRootConfiguration rootConfig = (TestRootConfiguration)config;
TestConfiguration baseSubConfig = rootConfig.subCfg();
ExtendedTestConfiguration extendedSubConfig = (ExtendedTestConfiguration)rootConfig.subCfg();
ExtendedSecondTestConfiguration extendedSecondSubConfig =
(ExtendedSecondTestConfiguration)rootConfig.subCfg();
assertSame(baseSubConfig.i0(), extendedSubConfig.i0());
assertSame(baseSubConfig.i0(), extendedSecondSubConfig.i0());
assertSame(baseSubConfig.str2(), extendedSubConfig.str2());
assertSame(baseSubConfig.str2(), extendedSecondSubConfig.str2());
assertNotNull(extendedSecondSubConfig.i1());
// Check view and change interfaces.
assertTrue(baseSubConfig.value() instanceof ExtendedTestView);
assertTrue(baseSubConfig.value() instanceof ExtendedSecondTestView);
assertSame(baseSubConfig.value(), extendedSubConfig.value());
assertSame(baseSubConfig.value(), extendedSecondSubConfig.value());
baseSubConfig.change(c -> {
assertTrue(c instanceof ExtendedTestChange);
assertTrue(c instanceof ExtendedSecondTestChange);
c.changeI0(10).changeStr2("str2");
((ExtendedTestChange)c).changeStr3("str3").changeStr2("str2");
((ExtendedSecondTestChange)c).changeI1(200).changeStr2("str2");
}).get(1, SECONDS);
}
/** */
@Test
void testExtendedNamedConfiguration() throws Exception {
DynamicConfiguration<?, ?> config = generator.instantiateCfg(TestRootConfiguration.KEY, changer);
TestRootConfiguration rootConfig = (TestRootConfiguration)config;
String key = UUID.randomUUID().toString();
rootConfig.namedCfg().change(c -> c.create(key, c0 -> c0.changeI0(0).changeStr2("foo2"))).get(1, SECONDS);
TestConfiguration namedConfig = rootConfig.namedCfg().get(key);
assertTrue(namedConfig instanceof ExtendedTestConfiguration);
assertTrue(namedConfig instanceof ExtendedSecondTestConfiguration);
// Check view and change interfaces.
assertTrue(namedConfig.value() instanceof ExtendedTestView);
assertTrue(namedConfig.value() instanceof ExtendedSecondTestView);
namedConfig.change(c -> {
assertTrue(c instanceof ExtendedTestChange);
assertTrue(c instanceof ExtendedSecondTestChange);
c.changeStr2("str2").changeI0(10);
((ExtendedTestChange)c).changeStr3("str3").changeStr2("str2");
((ExtendedSecondTestChange)c).changeI1(100).changeStr2("str2");
}).get(1, SECONDS);
}
/** */
@Test
void testConstructInternalConfig() {
InnerNode innerNode = generator.instantiateNode(TestRootConfiguration.KEY.schemaClass());
addDefaults(innerNode);
InnerNode subInnerNode = (InnerNode)((TestRootView)innerNode).subCfg();
// Check that no fields for internal configuration will be changed.
assertThrows(NoSuchElementException.class, () -> innerNode.construct("str1", null, false));
assertThrows(NoSuchElementException.class, () -> innerNode.construct("i1", null, false));
assertThrows(NoSuchElementException.class, () -> subInnerNode.construct("str3", null, false));
assertThrows(NoSuchElementException.class, () -> subInnerNode.construct("i1", null, false));
// Check that fields for internal configuration will be changed.
innerNode.construct("str1", null, true);
innerNode.construct("i1", null, true);
subInnerNode.construct("str3", null, true);
subInnerNode.construct("i1", null, true);
}
/**
* Test root configuration schema.
*/
@ConfigurationRoot(rootName = "test")
public static class TestRootConfigurationSchema {
/** Integer field. */
@Value(hasDefault = true)
public int i0 = 0;
/** String field. */
@Value(hasDefault = true)
public String str0 = "str0";
/** Sub configuration field. */
@ConfigValue
public TestConfigurationSchema subCfg;
/** Named configuration field. */
@NamedConfigValue
public TestConfigurationSchema namedCfg;
}
/**
* Extending the {@link TestRootConfigurationSchema}.
*/
@InternalConfiguration
public static class ExtendedTestRootConfigurationSchema extends TestRootConfigurationSchema {
/** String field. */
@Value(hasDefault = true)
public String str1 = "str1";
}
/**
* Extending the {@link TestRootConfigurationSchema}.
*/
@InternalConfiguration
public static class ExtendedSecondTestRootConfigurationSchema extends TestRootConfigurationSchema {
/** Integer field. */
@Value(hasDefault = true)
public int i1 = 0;
}
/**
* Test configuration schema.
*/
@Config
public static class TestConfigurationSchema {
/** Integer field. */
@Value(hasDefault = true)
public int i0 = 0;
/** String field. */
@Value(hasDefault = true)
public String str2 = "str2";
}
/**
* Extending the {@link TestConfigurationSchema}.
*/
@InternalConfiguration
public static class ExtendedTestConfigurationSchema extends TestConfigurationSchema {
/** String field. */
@Value(hasDefault = true)
public String str3 = "str3";
}
/**
* Extending the {@link TestConfigurationSchema}.
*/
@InternalConfiguration
public static class ExtendedSecondTestConfigurationSchema extends TestConfigurationSchema {
/** Integer field. */
@Value(hasDefault = true)
public int i1 = 0;
}
}