Skip to content

Commit 382f554

Browse files
feat(timeouts): Configure post timeouts for clouddriver. Using standard okhttpclient (#4522)
1 parent 386da27 commit 382f554

File tree

5 files changed

+86
-27
lines changed

5 files changed

+86
-27
lines changed

orca-clouddriver/src/main/java/com/netflix/spinnaker/orca/clouddriver/config/LambdaConfigurationProperties.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@
2222
@Data
2323
@ConfigurationProperties(prefix = "lambda")
2424
public class LambdaConfigurationProperties {
25+
private int cloudDriverPostTimeoutSeconds = 120;
2526

26-
private int cloudDriverReadTimeout = 60;
27-
private int cloudDriverConnectTimeout = 15;
2827
private int cacheRefreshRetryWaitTime = 15;
2928
private int cacheOnDemandRetryWaitTime = 15;
3029
private int cloudDriverPostRequestRetries = 5;

orca-clouddriver/src/main/java/com/netflix/spinnaker/orca/clouddriver/tasks/providers/aws/lambda/LambdaCacheRefreshTask.java

+16-8
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,25 @@
4545
public class LambdaCacheRefreshTask implements LambdaStageBaseTask {
4646
private static final Logger logger = LoggerFactory.getLogger(LambdaCacheRefreshTask.class);
4747
private static final String CLOUDDRIVER_REFRESH_CACHE_PATH = "/cache/aws/function";
48+
private final OkHttpClient client;
4849

49-
@Autowired CloudDriverConfigurationProperties props;
50+
CloudDriverConfigurationProperties props;
5051

51-
@Autowired private LambdaCloudDriverUtils utils;
52+
private LambdaCloudDriverUtils utils;
5253

53-
@Autowired LambdaConfigurationProperties config;
54+
LambdaConfigurationProperties config;
55+
56+
@Autowired
57+
public LambdaCacheRefreshTask(
58+
CloudDriverConfigurationProperties props,
59+
LambdaCloudDriverUtils utils,
60+
OkHttpClient client,
61+
LambdaConfigurationProperties config) {
62+
this.props = props;
63+
this.utils = utils;
64+
this.client = client;
65+
this.config = config;
66+
}
5467

5568
private static final ObjectMapper objectMapper = new ObjectMapper();
5669

@@ -98,11 +111,6 @@ private void forceCacheRefresh(StageExecution stage, int tries) {
98111
.retry(
99112
() -> {
100113
try {
101-
OkHttpClient client =
102-
new OkHttpClient.Builder()
103-
.connectTimeout(Duration.ofSeconds(config.getCloudDriverConnectTimeout()))
104-
.readTimeout(Duration.ofSeconds(config.getCloudDriverReadTimeout()))
105-
.build();
106114
Call call = client.newCall(request);
107115
Response response = call.execute();
108116
String respString = response.body().string();

orca-clouddriver/src/main/java/com/netflix/spinnaker/orca/clouddriver/utils/LambdaCloudDriverUtils.java

+31-12
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,16 @@
4242
import java.util.ArrayList;
4343
import java.util.Comparator;
4444
import java.util.List;
45+
import java.util.concurrent.TimeUnit;
4546
import java.util.stream.Collectors;
46-
import okhttp3.*;
47+
import okhttp3.Call;
48+
import okhttp3.Headers;
49+
import okhttp3.HttpUrl;
50+
import okhttp3.MediaType;
51+
import okhttp3.OkHttpClient;
52+
import okhttp3.Request;
53+
import okhttp3.RequestBody;
54+
import okhttp3.Response;
4755
import org.apache.commons.lang3.ObjectUtils;
4856
import org.apache.commons.lang3.math.NumberUtils;
4957
import org.pf4j.util.StringUtils;
@@ -63,11 +71,24 @@ public class LambdaCloudDriverUtils {
6371
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
6472
}
6573

66-
@Autowired LambdaConfigurationProperties config;
74+
private final LambdaConfigurationProperties config;
6775

68-
@Autowired CloudDriverConfigurationProperties props;
76+
private final CloudDriverConfigurationProperties props;
6977

70-
@Autowired OortService oort;
78+
private final OortService oort;
79+
private final OkHttpClient client;
80+
81+
@Autowired
82+
public LambdaCloudDriverUtils(
83+
LambdaConfigurationProperties config,
84+
CloudDriverConfigurationProperties props,
85+
OkHttpClient client,
86+
OortService oort) {
87+
this.config = config;
88+
this.props = props;
89+
this.client = client;
90+
this.oort = oort;
91+
}
7192

7293
public LambdaCloudDriverResponse postToCloudDriver(String endPointUrl, String jsonString) {
7394
return postToCloudDriver(endPointUrl, jsonString, config.getCloudDriverPostRequestRetries());
@@ -82,8 +103,12 @@ public LambdaCloudDriverResponse postToCloudDriver(
82103
.retry(
83104
() -> {
84105
try {
85-
OkHttpClient client = new OkHttpClient();
86-
Call call = client.newCall(request);
106+
Call call =
107+
client
108+
.newBuilder()
109+
.readTimeout(config.getCloudDriverPostTimeoutSeconds(), TimeUnit.SECONDS)
110+
.build()
111+
.newCall(request);
87112
Response response = call.execute();
88113
String respString = response.body().string();
89114

@@ -184,11 +209,6 @@ public LambdaCloudDriverTaskResults verifyStatus(String endPoint) {
184209

185210
public String getFromCloudDriver(String endPoint) {
186211
Request request = new Request.Builder().url(endPoint).headers(buildHeaders()).get().build();
187-
OkHttpClient client =
188-
new OkHttpClient.Builder()
189-
.connectTimeout(Duration.ofSeconds(config.getCloudDriverConnectTimeout()))
190-
.readTimeout(Duration.ofSeconds(config.getCloudDriverReadTimeout()))
191-
.build();
192212
Call call = client.newCall(request);
193213
try {
194214
Response response = call.execute();
@@ -229,7 +249,6 @@ public LambdaDefinition retrieveLambdaFromCache(LambdaGetInput inp) {
229249
httpBuilder.addQueryParameter("functionName", fName);
230250
Request request =
231251
new Request.Builder().url(httpBuilder.build()).headers(buildHeaders()).build();
232-
OkHttpClient client = new OkHttpClient();
233252
Call call = client.newCall(request);
234253
try {
235254
Response response = call.execute();

orca-clouddriver/src/test/java/com/netflix/spinnaker/orca/clouddriver/tasks/providers/aws/lambda/LambdaCacheRefreshTaskTest.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434
import java.util.List;
3535
import java.util.Map;
3636
import okhttp3.Headers;
37+
import okhttp3.OkHttpClient;
3738
import org.junit.jupiter.api.BeforeEach;
3839
import org.junit.jupiter.api.Test;
3940
import org.junit.jupiter.api.extension.ExtendWith;
40-
import org.mockito.InjectMocks;
4141
import org.mockito.Mock;
4242
import org.mockito.Mockito;
4343
import org.mockito.MockitoAnnotations;
@@ -49,7 +49,7 @@ public class LambdaCacheRefreshTaskTest {
4949

5050
WireMockServer wireMockServer;
5151

52-
@InjectMocks private LambdaCacheRefreshTask lambdaCacheRefreshTask;
52+
private LambdaCacheRefreshTask lambdaCacheRefreshTask;
5353

5454
@Mock private CloudDriverConfigurationProperties propsMock;
5555

@@ -86,6 +86,9 @@ void init(
8686
new ResponseDefinitionBuilder().withStatus(202).withBody(responseDefinitionBuilderJson);
8787

8888
this.wireMockServer.stubFor(WireMock.post("/cache/aws/function").willReturn(mockResponse));
89+
lambdaCacheRefreshTask =
90+
new LambdaCacheRefreshTask(
91+
propsMock, lambdaCloudDriverUtilsMock, new OkHttpClient(), config);
8992
}
9093

9194
@Test

orca-clouddriver/src/test/java/com/netflix/spinnaker/orca/clouddriver/utils/LambdaClouddriverUtilsTest.java

+33-3
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616

1717
package com.netflix.spinnaker.orca.clouddriver.utils;
1818

19+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
1920
import static org.junit.jupiter.api.Assertions.*;
2021

2122
import com.github.tomakehurst.wiremock.WireMockServer;
2223
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
2324
import com.github.tomakehurst.wiremock.client.WireMock;
2425
import com.google.common.collect.ImmutableMap;
26+
import com.netflix.spinnaker.kork.exceptions.SpinnakerException;
2527
import com.netflix.spinnaker.orca.api.pipeline.models.PipelineExecution;
2628
import com.netflix.spinnaker.orca.api.pipeline.models.StageExecution;
2729
import com.netflix.spinnaker.orca.clouddriver.config.CloudDriverConfigurationProperties;
@@ -31,16 +33,17 @@
3133
import com.netflix.spinnaker.orca.clouddriver.tasks.providers.aws.lambda.model.LambdaDefinition;
3234
import com.netflix.spinnaker.orca.clouddriver.tasks.providers.aws.lambda.model.input.LambdaDeploymentInput;
3335
import com.netflix.spinnaker.orca.clouddriver.tasks.providers.aws.lambda.model.input.LambdaGetInput;
36+
import java.net.SocketTimeoutException;
3437
import java.util.ArrayList;
3538
import java.util.HashMap;
3639
import java.util.List;
3740
import java.util.Map;
3841
import java.util.stream.Collectors;
3942
import java.util.stream.Stream;
43+
import okhttp3.OkHttpClient;
4044
import org.junit.jupiter.api.BeforeEach;
4145
import org.junit.jupiter.api.Test;
4246
import org.junit.jupiter.api.extension.ExtendWith;
43-
import org.mockito.InjectMocks;
4447
import org.mockito.Mock;
4548
import org.mockito.Mockito;
4649
import org.mockito.MockitoAnnotations;
@@ -54,20 +57,47 @@ public class LambdaClouddriverUtilsTest {
5457

5558
String CLOUDDRIVER_BASE_URL;
5659

57-
@InjectMocks private LambdaCloudDriverUtils lambdaCloudDriverUtils;
60+
private LambdaCloudDriverUtils lambdaCloudDriverUtils;
5861

5962
@Mock private CloudDriverConfigurationProperties propsMock;
6063

61-
@Mock private LambdaConfigurationProperties config;
64+
private LambdaConfigurationProperties config;
6265

6366
@BeforeEach
6467
void init(
6568
@WiremockResolver.Wiremock WireMockServer wireMockServer,
6669
@WiremockUriResolver.WiremockUri String uri) {
70+
config = new LambdaConfigurationProperties();
6771
this.wireMockServer = wireMockServer;
6872
CLOUDDRIVER_BASE_URL = uri;
6973
MockitoAnnotations.initMocks(this);
7074
Mockito.when(propsMock.getCloudDriverBaseUrl()).thenReturn(uri);
75+
lambdaCloudDriverUtils =
76+
new LambdaCloudDriverUtils(config, propsMock, new OkHttpClient(), null);
77+
}
78+
79+
@Test
80+
public void handleTimeout() {
81+
82+
config.setCloudDriverPostTimeoutSeconds(1);
83+
config.setCloudDriverPostRequestRetries(1);
84+
this.wireMockServer.stubFor(
85+
WireMock.post("/healthcheck")
86+
.willReturn(aResponse().withStatus(200).withFixedDelay(20000)));
87+
SpinnakerException exception =
88+
assertThrows(
89+
SpinnakerException.class,
90+
() -> {
91+
lambdaCloudDriverUtils.postToCloudDriver(
92+
CLOUDDRIVER_BASE_URL.concat("/healthcheck"), "{}");
93+
});
94+
exception.getCause().printStackTrace();
95+
assertTrue(
96+
exception.getCause() instanceof SocketTimeoutException,
97+
"Should have been socket timeout... real cause was "
98+
+ exception.getCause().getClass()
99+
+ ", "
100+
+ exception.getCause().getMessage());
71101
}
72102

73103
@Test

0 commit comments

Comments
 (0)