use of io.pravega.segmentstore.server.reading.ReadIndexConfig in project pravega by pravega.
the class ServiceBuilderConfigTests method testGetConfig.
/**
* Verifies the include(ConfigBuilder) and getConfig() work properly. This test follows a bit of an unusual approach
* in that it picks a few known config classes, populates them using their builders and reflection, then uses reflection
* once again to compare expected output (generated using their builders) with output from the ServiceBuilderConfig.getConfig().
* <p>
* This verifies that the namespacing inside ServiceBuilderConfig.builder() works correctly, as well as the constructors
* for various configs.
*/
@Test
@SuppressWarnings("unchecked")
public void testGetConfig() throws Exception {
// Select a few classes to test dynamically.
val testClasses = new HashMap<Class<?>, Supplier<ConfigBuilder<?>>>();
testClasses.put(ReadIndexConfig.class, ReadIndexConfig::builder);
testClasses.put(WriterConfig.class, WriterConfig::builder);
testClasses.put(MetricsConfig.class, MetricsConfig::builder);
testClasses.put(DurableLogConfig.class, DurableLogConfig::builder);
testClasses.put(ServiceConfig.class, ServiceConfig::builder);
// Value generator.
val nextValue = new AtomicInteger(1000 * 1000 * 1000);
// Create instances of each test class and dynamically assign their properties some arbitrary values
val expectedValues = new HashMap<Class<?>, Object>();
val b = ServiceBuilderConfig.builder();
for (Map.Entry<Class<?>, Supplier<ConfigBuilder<?>>> e : testClasses.entrySet()) {
Class<?> c = e.getKey();
ConfigBuilder<?> configBuilder = e.getValue().get();
for (Field f : c.getDeclaredFields()) {
// type contains one of the supported types.
if (Modifier.isStatic(f.getModifiers()) && f.getType().isAssignableFrom(Property.class) && isSupportedType(f.getGenericType().getTypeName())) {
Property p = (Property) f.get(null);
if (p.getDefaultValue() != null && p.getDefaultValue() instanceof Boolean) {
configBuilder.with(p, nextValue.incrementAndGet() % 2 == 0);
} else {
// Any number can be interpreted as a string or number.
configBuilder.with(p, Integer.toString(nextValue.incrementAndGet()));
}
}
}
// Collect the built config object for later use.
expectedValues.put(c, configBuilder.build());
// Include the builder in the main builder.
b.include(configBuilder);
}
// Create the ServiceBuilderConfig, and verify that the created Config classes (using getConfig()) match the
// expected ones.
val builderConfig = b.build();
for (Map.Entry<Class<?>, Supplier<ConfigBuilder<?>>> e : testClasses.entrySet()) {
Class<?> c = e.getKey();
Object expectedConfig = expectedValues.get(c);
Object actualConfig = builderConfig.getConfig(e.getValue());
// All the properties we care about are public getters with no arguments - only check those.
for (Method m : c.getDeclaredMethods()) {
if (m.getName().startsWith("get") && m.getParameterCount() == 0 && !Modifier.isStatic(m.getModifiers()) && Modifier.isPublic(m.getModifiers())) {
Object expectedValue = m.invoke(expectedConfig);
Object actualValue = m.invoke(actualConfig);
if (expectedValue == null) {
Assert.assertNull("Expected a null value for " + getPropName(c, m), actualValue);
} else {
Assert.assertNotNull("Not expected a null value for " + getPropName(c, m), actualValue);
}
if (isSupportedType(expectedValue)) {
Assert.assertEquals("Unexpected value for " + getPropName(c, m), expectedValue, actualValue);
}
}
}
}
}
use of io.pravega.segmentstore.server.reading.ReadIndexConfig in project pravega by pravega.
the class ServiceBuilder method createReadIndexFactory.
protected ReadIndexFactory createReadIndexFactory() {
CacheFactory cacheFactory = getSingleton(this.cacheFactory, this.cacheFactoryCreator);
ReadIndexConfig readIndexConfig = this.serviceBuilderConfig.getConfig(ReadIndexConfig::builder);
return new ContainerReadIndexFactory(readIndexConfig, cacheFactory, this.coreExecutor);
}
use of io.pravega.segmentstore.server.reading.ReadIndexConfig in project pravega by pravega.
the class ContainerRecoverCommand method execute.
@Override
public void execute() throws Exception {
ensureArgCount(1);
int containerId = getIntArg(0);
@Cleanup val context = createContext();
val readIndexConfig = getCommandArgs().getState().getConfigBuilder().build().getConfig(ReadIndexConfig::builder);
// We create a special "read-only" BK log that will not be doing fencing or otherwise interfere with an active
// container. As a result, due to the nature of BK, it is possible that it may not contain all the latest writes
// since the Bookies may not have yet synchronized the LAC on the last (active ledger).
@Cleanup val log = context.logFactory.createDebugLogWrapper(containerId);
val bkLog = log.asReadOnly();
val recoveryState = new RecoveryState();
val callbacks = new DebugRecoveryProcessor.OperationCallbacks(recoveryState::newOperation, op -> recoveryState.operationComplete(op, null), recoveryState::operationComplete);
@Cleanup val rp = DebugRecoveryProcessor.create(containerId, bkLog, context.containerConfig, readIndexConfig, getCommandArgs().getState().getExecutor(), callbacks);
try {
rp.performRecovery();
output("Recovery complete: %d DataFrame(s) containing %d Operation(s).", recoveryState.dataFrameCount, recoveryState.operationCount);
} catch (Exception ex) {
output("Recovery FAILED: %d DataFrame(s) containing %d Operation(s) were able to be recovered.", recoveryState.dataFrameCount, recoveryState.operationCount);
ex.printStackTrace(getOut());
Throwable cause = Exceptions.unwrap(ex);
if (cause instanceof DataCorruptionException) {
unwrapDataCorruptionException((DataCorruptionException) cause);
}
}
}
Aggregations