Skip to content

Commit 22f09c7

Browse files
authored
Bugfix: Catch RejectedExecutionException and skip validation (#13)
1 parent d2da0bc commit 22f09c7

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

openapi-validation-core/src/main/java/com/getyourguide/openapi/validation/core/OpenApiRequestValidator.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,25 @@
1212
import com.getyourguide.openapi.validation.api.model.ValidatorConfiguration;
1313
import com.getyourguide.openapi.validation.core.validator.OpenApiInteractionValidatorWrapper;
1414
import java.nio.charset.StandardCharsets;
15-
import java.util.concurrent.LinkedBlockingQueue;
15+
import java.util.concurrent.RejectedExecutionException;
1616
import java.util.concurrent.ThreadPoolExecutor;
17-
import java.util.concurrent.TimeUnit;
1817
import lombok.extern.slf4j.Slf4j;
1918
import org.apache.http.client.utils.URLEncodedUtils;
2019

2120
@Slf4j
2221
public class OpenApiRequestValidator {
23-
private final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 2, 1000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(10));
24-
22+
private final ThreadPoolExecutor threadPoolExecutor;
2523
private final OpenApiInteractionValidatorWrapper validator;
2624
private final ValidationReportHandler validationReportHandler;
2725

2826
public OpenApiRequestValidator(
27+
ThreadPoolExecutor threadPoolExecutor,
2928
ValidationReportHandler validationReportHandler,
3029
MetricsReporter metricsReporter,
3130
String specificationFilePath,
3231
ValidatorConfiguration configuration
3332
) {
33+
this.threadPoolExecutor = threadPoolExecutor;
3434
this.validator = new OpenApiInteractionValidatorFactory().build(specificationFilePath, configuration);
3535
this.validationReportHandler = validationReportHandler;
3636

@@ -42,11 +42,19 @@ public boolean isReady() {
4242
}
4343

4444
public void validateRequestObjectAsync(final RequestMetaData request, String requestBody) {
45-
threadPool.execute(() -> validateRequestObject(request, requestBody));
45+
executeAsync(() -> validateRequestObject(request, requestBody));
4646
}
4747

4848
public void validateResponseObjectAsync(final RequestMetaData request, ResponseMetaData response, final String responseBody) {
49-
threadPool.execute(() -> validateResponseObject(request, response, responseBody));
49+
executeAsync(() -> validateResponseObject(request, response, responseBody));
50+
}
51+
52+
private void executeAsync(Runnable command) {
53+
try {
54+
threadPoolExecutor.execute(command);
55+
} catch (RejectedExecutionException ignored) {
56+
// ignored
57+
}
5058
}
5159

5260
public ValidationResult validateRequestObject(final RequestMetaData request, String requestBody) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.getyourguide.openapi.validation.core;
2+
3+
import static org.mockito.Mockito.mock;
4+
5+
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
6+
import com.getyourguide.openapi.validation.api.model.ValidatorConfiguration;
7+
import java.util.concurrent.RejectedExecutionException;
8+
import java.util.concurrent.ThreadPoolExecutor;
9+
import org.junit.jupiter.api.BeforeEach;
10+
import org.junit.jupiter.api.Test;
11+
import org.mockito.Mockito;
12+
13+
public class OpenApiRequestValidatorTest {
14+
15+
private ThreadPoolExecutor threadPoolExecutor;
16+
17+
private OpenApiRequestValidator openApiRequestValidator;
18+
19+
@BeforeEach
20+
public void setup() {
21+
threadPoolExecutor = mock();
22+
ValidationReportHandler validationReportHandler = mock();
23+
MetricsReporter metricsReporter = mock();
24+
25+
openApiRequestValidator = new OpenApiRequestValidator(
26+
threadPoolExecutor,
27+
validationReportHandler,
28+
metricsReporter,
29+
"",
30+
new ValidatorConfiguration(null, null, null)
31+
);
32+
}
33+
34+
@Test
35+
public void testWhenThreadPoolExecutorRejectsExecutionThenItShouldNotThrow() {
36+
Mockito.doThrow(new RejectedExecutionException()).when(threadPoolExecutor).execute(Mockito.any());
37+
38+
openApiRequestValidator.validateRequestObjectAsync(mock(), null);
39+
}
40+
}

spring-boot-starter/spring-boot-starter-core/src/main/java/com/getyourguide/openapi/validation/autoconfigure/LibraryAutoConfiguration.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import com.getyourguide.openapi.validation.core.throttle.ValidationReportThrottler;
2121
import com.getyourguide.openapi.validation.core.throttle.ValidationReportThrottlerNone;
2222
import java.util.Optional;
23+
import java.util.concurrent.LinkedBlockingQueue;
24+
import java.util.concurrent.ThreadPoolExecutor;
25+
import java.util.concurrent.TimeUnit;
2326
import lombok.AllArgsConstructor;
2427
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2528
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -96,7 +99,17 @@ public OpenApiRequestValidator openApiRequestValidator(
9699
MetricsReporter metricsReporter,
97100
ValidatorConfiguration validatorConfiguration
98101
) {
102+
var threadPoolExecutor = new ThreadPoolExecutor(
103+
2,
104+
2,
105+
1000L,
106+
TimeUnit.MILLISECONDS,
107+
new LinkedBlockingQueue<>(10),
108+
new ThreadPoolExecutor.DiscardPolicy()
109+
);
110+
99111
return new OpenApiRequestValidator(
112+
threadPoolExecutor,
100113
validationReportHandler,
101114
metricsReporter,
102115
properties.getSpecificationFilePath(),

0 commit comments

Comments
 (0)