Output all failing bootstrap checks
This commit modifies the boostrap checks to output all failing checks instead of early-failing on the first check and then possibly failing again after the user resolves the first failing check. Closes #17474
This commit is contained in:
parent
cfc23a9d67
commit
fc7442739c
|
@ -34,6 +34,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We enforce limits once any network host is configured. In this case we assume the node is running in production
|
* We enforce limits once any network host is configured. In this case we assume the node is running in production
|
||||||
|
@ -72,14 +73,22 @@ final class BootstrapCheck {
|
||||||
static void check(final boolean enforceLimits, final List<Check> checks, final String nodeName) {
|
static void check(final boolean enforceLimits, final List<Check> checks, final String nodeName) {
|
||||||
final ESLogger logger = Loggers.getLogger(BootstrapCheck.class, nodeName);
|
final ESLogger logger = Loggers.getLogger(BootstrapCheck.class, nodeName);
|
||||||
|
|
||||||
for (final Check check : checks) {
|
final List<String> errors =
|
||||||
final boolean fail = check.check();
|
checks.stream()
|
||||||
if (fail) {
|
.filter(BootstrapCheck.Check::check)
|
||||||
if (enforceLimits) {
|
.map(BootstrapCheck.Check::errorMessage)
|
||||||
throw new RuntimeException(check.errorMessage());
|
.collect(Collectors.toList());
|
||||||
} else {
|
|
||||||
logger.warn(check.errorMessage());
|
if (!errors.isEmpty()) {
|
||||||
}
|
final List<String> messages = new ArrayList<>(1 + errors.size());
|
||||||
|
messages.add("bootstrap checks failed");
|
||||||
|
messages.addAll(errors);
|
||||||
|
if (enforceLimits) {
|
||||||
|
final RuntimeException re = new RuntimeException(String.join("\n", messages));
|
||||||
|
errors.stream().map(IllegalStateException::new).forEach(re::addSuppressed);
|
||||||
|
throw re;
|
||||||
|
} else {
|
||||||
|
messages.forEach(message -> logger.warn(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,16 @@ import org.elasticsearch.common.transport.TransportAddress;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.allOf;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.Matchers.hasToString;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
@ -97,6 +101,42 @@ public class BootstrapCheckTests extends ESTestCase {
|
||||||
assertTrue(BootstrapCheck.enforceLimits(boundTransportAddress));
|
assertTrue(BootstrapCheck.enforceLimits(boundTransportAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testExceptionAggregation() {
|
||||||
|
final List<BootstrapCheck.Check> checks = Arrays.asList(
|
||||||
|
new BootstrapCheck.Check() {
|
||||||
|
@Override
|
||||||
|
public boolean check() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String errorMessage() {
|
||||||
|
return "first";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new BootstrapCheck.Check() {
|
||||||
|
@Override
|
||||||
|
public boolean check() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String errorMessage() {
|
||||||
|
return "second";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
final RuntimeException e =
|
||||||
|
expectThrows(RuntimeException.class, () -> BootstrapCheck.check(true, checks, "testExceptionAggregation"));
|
||||||
|
assertThat(e, hasToString(allOf(containsString("bootstrap checks failed"), containsString("first"), containsString("second"))));
|
||||||
|
final Throwable[] suppressed = e.getSuppressed();
|
||||||
|
assertThat(suppressed.length, equalTo(2));
|
||||||
|
assertThat(suppressed[0], instanceOf(IllegalStateException.class));
|
||||||
|
assertThat(suppressed[0], hasToString(containsString("first")));
|
||||||
|
assertThat(suppressed[1], instanceOf(IllegalStateException.class));
|
||||||
|
assertThat(suppressed[1], hasToString(containsString("second")));
|
||||||
|
}
|
||||||
|
|
||||||
public void testFileDescriptorLimits() {
|
public void testFileDescriptorLimits() {
|
||||||
final boolean osX = randomBoolean(); // simulates OS X versus non-OS X
|
final boolean osX = randomBoolean(); // simulates OS X versus non-OS X
|
||||||
final int limit = osX ? 10240 : 1 << 16;
|
final int limit = osX ? 10240 : 1 << 16;
|
||||||
|
|
Loading…
Reference in New Issue