Skip to content

Commit bb00f8c

Browse files
authored
Fix http throwable responses (#2251)
* handle throwable response plus cleanup
1 parent 30aef63 commit bb00f8c

File tree

9 files changed

+76
-24
lines changed

9 files changed

+76
-24
lines changed

operator/src/main/java/oracle/kubernetes/operator/helpers/AnnotationHelper.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package oracle.kubernetes.operator.helpers;
55

66
import java.util.Map;
7+
import java.util.Objects;
78
import java.util.Optional;
89
import java.util.function.Function;
910

@@ -36,22 +37,22 @@ static void annotateForPrometheus(V1ObjectMeta meta, String applicationContext,
3637
meta.putAnnotationsItem("prometheus.io/scrape", "true");
3738
}
3839

39-
public static V1Pod withSha256Hash(V1Pod pod) {
40+
static V1Pod withSha256Hash(V1Pod pod) {
4041
return DEBUG ? addHashAndDebug(pod) : addHash(pod);
4142
}
4243

4344
public static <K extends KubernetesObject> K withSha256Hash(K kubernetesObject) {
4445
return withSha256Hash(kubernetesObject, kubernetesObject);
4546
}
4647

47-
public static <K extends KubernetesObject> K withSha256Hash(K kubernetesObject, Object objectToHash) {
48+
static <K extends KubernetesObject> K withSha256Hash(K kubernetesObject, Object objectToHash) {
4849
return addHash(kubernetesObject, objectToHash);
4950
}
5051

5152
private static V1Pod addHashAndDebug(V1Pod pod) {
5253
String dump = Yaml.dump(pod);
5354
addHash(pod);
54-
pod.getMetadata().putAnnotationsItem(HASHED_STRING, dump);
55+
Objects.requireNonNull(pod.getMetadata()).putAnnotationsItem(HASHED_STRING, dump);
5556
return pod;
5657
}
5758

operator/src/main/java/oracle/kubernetes/operator/helpers/PodStepContext.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ private Step getConflictStep() {
126126

127127
abstract Map<String, String> getPodAnnotations();
128128

129-
String getNamespace() {
129+
private String getNamespace() {
130130
return info.getNamespace();
131131
}
132132

@@ -156,7 +156,7 @@ Domain getDomain() {
156156
return info.getDomain();
157157
}
158158

159-
String getDomainName() {
159+
private String getDomainName() {
160160
return domainTopology.getName();
161161
}
162162

@@ -172,7 +172,7 @@ String getAsName() {
172172
return domainTopology.getAdminServerName();
173173
}
174174

175-
Integer getAsPort() {
175+
private Integer getAsPort() {
176176
return domainTopology
177177
.getServerConfig(domainTopology.getAdminServerName())
178178
.getLocalAdminProtocolChannelPort();
@@ -375,7 +375,7 @@ private Step patchCurrentPod(V1Pod currentPod, Step next) {
375375
return createProgressingStep(patchPod(currentPod, next));
376376
}
377377

378-
protected Step patchPod(V1Pod currentPod, Step next) {
378+
private Step patchPod(V1Pod currentPod, Step next) {
379379
JsonPatchBuilder patchBuilder = Json.createPatchBuilder();
380380
KubernetesUtils.addPatches(
381381
patchBuilder, "/metadata/labels/", getLabels(currentPod), getNonHashedPodLabels());

operator/src/main/java/oracle/kubernetes/operator/http/HttpAsyncRequestStep.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import java.net.http.HttpClient;
99
import java.net.http.HttpRequest;
1010
import java.net.http.HttpResponse;
11-
import java.util.Optional;
1211
import java.util.concurrent.CompletableFuture;
1312
import java.util.concurrent.TimeUnit;
1413

@@ -53,7 +52,7 @@ private HttpAsyncRequestStep(HttpRequest request, HttpResponseStep responseStep)
5352
* @param responseStep the step to handle the response
5453
* @return a new step to run as part of a fiber, linked to the response step
5554
*/
56-
public static HttpAsyncRequestStep createGetRequest(String url, HttpResponseStep responseStep) {
55+
static HttpAsyncRequestStep createGetRequest(String url, HttpResponseStep responseStep) {
5756
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).GET().build();
5857
return create(request, responseStep);
5958
}
@@ -107,11 +106,14 @@ private void checkTimeout(AsyncFiber fiber) {
107106
}
108107

109108
private void resume(AsyncFiber fiber, HttpResponse<String> response, Throwable throwable) {
110-
if (throwable != null) {
111-
LOGGER.fine(MessageKeys.HTTP_REQUEST_TIMED_OUT, request.method(), request.uri(), throwable);
109+
if (throwable instanceof HttpTimeoutException) {
110+
LOGGER.fine(MessageKeys.HTTP_REQUEST_TIMED_OUT, throwable.getMessage());
111+
} else if (response != null) {
112+
recordResponse(response);
113+
} else if (throwable != null) {
114+
recordThrowableResponse(throwable);
112115
}
113-
114-
Optional.ofNullable(response).ifPresent(this::recordResponse);
116+
115117
fiber.resume(packet);
116118
}
117119

@@ -121,8 +123,12 @@ private void recordResponse(HttpResponse<String> response) {
121123
}
122124
HttpResponseStep.addToPacket(packet, response);
123125
}
124-
}
125126

127+
private void recordThrowableResponse(Throwable throwable) {
128+
LOGGER.warning(MessageKeys.HTTP_REQUEST_GOT_THROWABLE, request.method(), request.uri(), throwable.getMessage());
129+
HttpResponseStep.addToPacket(packet, throwable);
130+
}
131+
}
126132

127133
private static CompletableFuture<HttpResponse<String>> createFuture(HttpRequest request) {
128134
return httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString());
@@ -132,7 +138,7 @@ static class HttpTimeoutException extends RuntimeException {
132138
private final String method;
133139
private final URI uri;
134140

135-
public HttpTimeoutException(String method, URI uri) {
141+
HttpTimeoutException(String method, URI uri) {
136142
this.method = method;
137143
this.uri = uri;
138144
}

operator/src/main/java/oracle/kubernetes/operator/http/HttpResponseStep.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,19 @@ public HttpResponseStep(Step next) {
2121

2222
@Override
2323
public NextAction apply(Packet packet) {
24-
return Optional.ofNullable(getResponse(packet)).map(r -> doApply(packet, r)).orElse(doNext(packet));
24+
return Optional.ofNullable(getResponse(packet))
25+
.map(r -> doApply(packet, r))
26+
.orElse(handlePossibleThrowableOrContinue(packet));
27+
}
28+
29+
private NextAction handlePossibleThrowableOrContinue(Packet packet) {
30+
return Optional.ofNullable(getThrowableResponse(packet))
31+
.map(t -> onFailure(packet, null))
32+
.orElse(doNext(packet));
33+
}
34+
35+
private Throwable getThrowableResponse(Packet packet) {
36+
return packet.getSpi(Throwable.class);
2537
}
2638

2739
private NextAction doApply(Packet packet, HttpResponse<String> response) {
@@ -46,6 +58,15 @@ static void addToPacket(Packet packet, HttpResponse<String> response) {
4658
packet.getComponents().put(RESPONSE, Component.createFor(HttpResponse.class, response));
4759
}
4860

61+
/**
62+
* Adds the specified throwable to a packet so that this step can access it via {@link Packet#getSpi(Class)} call.
63+
* @param packet the packet to which the response should be added
64+
* @param throwable the throwable from the server
65+
*/
66+
static void addToPacket(Packet packet, Throwable throwable) {
67+
packet.getComponents().put(RESPONSE, Component.createFor(Throwable.class, throwable));
68+
}
69+
4970
/**
5071
* Removes any current response from the packet.
5172
* @param packet the packet from which the response should be removed

operator/src/main/java/oracle/kubernetes/operator/logging/MessageKeys.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public class MessageKeys {
139139
public static final String BEGIN_MANAGING_NAMESPACE = "WLSKO-0186";
140140
public static final String END_MANAGING_NAMESPACE = "WLSKO-0187";
141141
public static final String MII_DOMAIN_DYNAMICALLY_UPDATED = "WLSKO-0188";
142+
public static final String HTTP_REQUEST_GOT_THROWABLE = "WLSKO-0189";
142143

143144
// domain status messages
144145
public static final String DUPLICATE_SERVER_NAME_FOUND = "WLSDO-0001";

operator/src/main/java/oracle/kubernetes/operator/steps/ManagedServerUpIteratorStep.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ public class ManagedServerUpIteratorStep extends Step {
4949
private static final LoggingFacade LOGGER = LoggingFactory.getLogger("Operator", "Operator");
5050

5151
/** The interval in msec that the operator will wait to ensure that started pods have been scheduled on a node. */
52-
public static final int SCHEDULING_DETECTION_DELAY = 100;
52+
static final int SCHEDULING_DETECTION_DELAY = 100;
5353

5454
private final Collection<ServerStartupInfo> startupInfos;
5555

56-
public ManagedServerUpIteratorStep(Collection<ServerStartupInfo> startupInfos, Step next) {
56+
ManagedServerUpIteratorStep(Collection<ServerStartupInfo> startupInfos, Step next) {
5757
super(next);
5858
this.startupInfos = startupInfos;
5959
}
@@ -133,7 +133,7 @@ private StepAndPacket createManagedServerUpWaiters(Packet packet, ServerStartupI
133133
createPacketForServer(packet, ssi));
134134
}
135135

136-
String getPodName(DomainPresenceInfo info, String serverName) {
136+
private String getPodName(DomainPresenceInfo info, String serverName) {
137137
return LegalNames.toPodName(info.getDomainUid(), serverName);
138138
}
139139

@@ -234,7 +234,7 @@ private static class StartClusteredServersStepFactory {
234234
this.maxConcurrency = maxConcurrency;
235235
}
236236

237-
public int getMaxConcurrency() {
237+
int getMaxConcurrency() {
238238
return this.maxConcurrency;
239239
}
240240

operator/src/main/java/oracle/kubernetes/operator/steps/ReadHealthStep.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353

5454
public class ReadHealthStep extends Step {
5555

56-
public static final String OVERALL_HEALTH_NOT_AVAILABLE = "Not available";
57-
public static final String OVERALL_HEALTH_FOR_SERVER_OVERLOADED =
56+
static final String OVERALL_HEALTH_NOT_AVAILABLE = "Not available";
57+
static final String OVERALL_HEALTH_FOR_SERVER_OVERLOADED =
5858
OVERALL_HEALTH_NOT_AVAILABLE + " (possibly overloaded)";
5959
private static final LoggingFacade LOGGER = LoggingFactory.getLogger("Operator", "Operator");
6060

@@ -305,7 +305,10 @@ private Map<String, String> getServerStateMap() {
305305
}
306306

307307
private boolean isServerOverloaded() {
308-
return isServerOverloaded(getResponse().statusCode());
308+
return Optional.ofNullable(getResponse())
309+
.map(HttpResponse::statusCode)
310+
.map(this::isServerOverloaded)
311+
.orElse(false);
309312
}
310313

311314
private boolean isServerOverloaded(int statusCode) {

operator/src/main/resources/Operator.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ WLSKO-0166=for {0}
118118
WLSKO-0167=with {0}
119119
WLSKO-0168={0}: {1}
120120
WLSKO-0169=Job {0} is created at {1}
121-
WLSKO-0170=HTTP timeout: exception {0}.
121+
WLSKO-0170=HTTP timeout: {0}.
122122
WLSKO-0171=Namespace {0} is in operator's domain namespaces list but doesn't exist
123123
WLSKO-0173=Replace custom resource definition failed: {0}
124124
WLSKO-0174=Create custom resource definition failed: {0}
@@ -137,6 +137,7 @@ WLSKO-0185=Patching Pod Disruption Budget for WebLogic domain with UID: {0}. Clu
137137
WLSKO-0186=Start managing namespace {0}
138138
WLSKO-0187=Stop managing namespace {0}
139139
WLSKO-0188=Model in Image domain with DomainUID ''{0}'' and server name ''{1}'' online updated successfully. No restart is necessary
140+
WLSKO-0189=HTTP request method {0} to {1} failed with exception {2}.
140141

141142
# Domain status messages
142143

operator/src/test/java/oracle/kubernetes/operator/http/HttpAsyncRequestStepTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929

3030
import static com.meterware.simplestub.Stub.createStub;
3131
import static oracle.kubernetes.operator.logging.MessageKeys.HTTP_METHOD_FAILED;
32+
import static oracle.kubernetes.operator.logging.MessageKeys.HTTP_REQUEST_GOT_THROWABLE;
3233
import static oracle.kubernetes.operator.logging.MessageKeys.HTTP_REQUEST_TIMED_OUT;
3334
import static oracle.kubernetes.utils.LogMatcher.containsFine;
35+
import static oracle.kubernetes.utils.LogMatcher.containsWarning;
3436
import static org.hamcrest.Matchers.equalTo;
3537
import static org.hamcrest.Matchers.is;
3638
import static org.hamcrest.Matchers.nullValue;
@@ -109,6 +111,12 @@ private void receiveResponseBeforeTimeout(NextAction nextAction, HttpResponse<St
109111
FiberTestSupport.doOnExit(nextAction, fiber);
110112
}
111113

114+
private void completeWithThrowableBeforeTimeout(NextAction nextAction, Throwable throwable) {
115+
responseFuture.completeExceptionally(throwable);
116+
FiberTestSupport.doOnExit(nextAction, fiber);
117+
}
118+
119+
112120
@Test
113121
public void whenErrorResponseReceived_logMessage() {
114122
final NextAction nextAction = requestStep.apply(packet);
@@ -118,6 +126,17 @@ public void whenErrorResponseReceived_logMessage() {
118126
assertThat(logRecords, containsFine(HTTP_METHOD_FAILED));
119127
}
120128

129+
@Test
130+
public void whenThrowableResponseReceived_logMessage() {
131+
consoleMemento
132+
.collectLogMessages(logRecords, HTTP_REQUEST_GOT_THROWABLE)
133+
.withLogLevel(Level.WARNING);
134+
final NextAction nextAction = requestStep.apply(packet);
135+
136+
completeWithThrowableBeforeTimeout(nextAction, new Throwable("Test"));
137+
138+
assertThat(logRecords, containsWarning(HTTP_REQUEST_GOT_THROWABLE));
139+
}
121140

122141
@Test
123142
public void whenResponseReceived_populatePacket() {

0 commit comments

Comments
 (0)