Order ExitCodeGenerators and return first non-zero exit code
See gh-30457
This commit is contained in:
parent
245e602ae0
commit
6718b10fa9
|
|
@ -354,7 +354,8 @@ include::code:MyApplication[]
|
||||||
Also, the `ExitCodeGenerator` interface may be implemented by exceptions.
|
Also, the `ExitCodeGenerator` interface may be implemented by exceptions.
|
||||||
When such an exception is encountered, Spring Boot returns the exit code provided by the implemented `getExitCode()` method.
|
When such an exception is encountered, Spring Boot returns the exit code provided by the implemented `getExitCode()` method.
|
||||||
|
|
||||||
|
If several `ExitCodeGenerator` are registered in a `ExitCodeGenerators`, they can be called in a specific order by using `org.springframework.core.annotation.Order` annotation or by implementing `org.springframework.core.Ordered`,
|
||||||
|
and `ExitCodeGenerators#getExitCode()` will return the first non-zero value.
|
||||||
|
|
||||||
[[features.spring-application.admin]]
|
[[features.spring-application.admin]]
|
||||||
=== Admin Features
|
=== Admin Features
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,22 @@ import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintains a collection of {@link ExitCodeGenerator} instances and allows the final exit
|
* Maintains a collection of {@link ExitCodeGenerator} instances and allows the final exit
|
||||||
* code to be calculated.
|
* code to be calculated.
|
||||||
*
|
*
|
||||||
|
* <p>If several {@code ExitCodeGenerator} are registered in {@code ExitCodeGenerators},
|
||||||
|
* they can be called in a specific order by using {@link Order @Order} or by implementing {@link Ordered},
|
||||||
|
* and {@link #getExitCode()} will return the first non-zero value.
|
||||||
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @author GenKui Du
|
||||||
* @see #getExitCode()
|
* @see #getExitCode()
|
||||||
* @see ExitCodeGenerator
|
* @see ExitCodeGenerator
|
||||||
*/
|
*/
|
||||||
|
|
@ -84,15 +92,17 @@ class ExitCodeGenerators implements Iterable<ExitCodeGenerator> {
|
||||||
*/
|
*/
|
||||||
int getExitCode() {
|
int getExitCode() {
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
|
AnnotationAwareOrderComparator.sort(this.generators);
|
||||||
for (ExitCodeGenerator generator : this.generators) {
|
for (ExitCodeGenerator generator : this.generators) {
|
||||||
try {
|
try {
|
||||||
int value = generator.getExitCode();
|
int value = generator.getExitCode();
|
||||||
if (value > 0 && value > exitCode || value < 0 && value < exitCode) {
|
if (value != 0) {
|
||||||
exitCode = value;
|
exitCode = value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
exitCode = (exitCode != 0) ? exitCode : 1;
|
exitCode = 1;
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,13 @@ import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.withSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link ExitCodeGenerators}.
|
* Tests for {@link ExitCodeGenerators}.
|
||||||
|
|
@ -89,12 +91,29 @@ class ExitCodeGeneratorsTests {
|
||||||
assertThat(generators.getExitCode()).isEqualTo(2);
|
assertThat(generators.getExitCode()).isEqualTo(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getExitCodeWithOrderedGenerator() {
|
||||||
|
ExitCodeGenerators generators = new ExitCodeGenerators();
|
||||||
|
generators.add(mockGenerator(0, 1));
|
||||||
|
generators.add(mockGenerator(1, 3));
|
||||||
|
generators.add(mockGenerator(2, 2));
|
||||||
|
generators.add(mockGenerator(3, 4));
|
||||||
|
assertThat(generators.getExitCode()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
private ExitCodeGenerator mockGenerator(int exitCode) {
|
private ExitCodeGenerator mockGenerator(int exitCode) {
|
||||||
ExitCodeGenerator generator = mock(ExitCodeGenerator.class);
|
ExitCodeGenerator generator = mock(ExitCodeGenerator.class);
|
||||||
given(generator.getExitCode()).willReturn(exitCode);
|
given(generator.getExitCode()).willReturn(exitCode);
|
||||||
return generator;
|
return generator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExitCodeGenerator mockGenerator(int exitCode, int orderValue) {
|
||||||
|
ExitCodeGenerator generator = mock(ExitCodeGenerator.class, withSettings().extraInterfaces(Ordered.class));
|
||||||
|
given(generator.getExitCode()).willReturn(exitCode);
|
||||||
|
given(((Ordered) generator).getOrder()).willReturn(orderValue);
|
||||||
|
return generator;
|
||||||
|
}
|
||||||
|
|
||||||
private ExitCodeExceptionMapper mockMapper(Class<?> exceptionType, int exitCode) {
|
private ExitCodeExceptionMapper mockMapper(Class<?> exceptionType, int exitCode) {
|
||||||
return (exception) -> {
|
return (exception) -> {
|
||||||
if (exceptionType.isInstance(exception)) {
|
if (exceptionType.isInstance(exception)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue