Skip to content

Commit 5b559b5

Browse files
committed
improve handling of error status code in HttpClient
1 parent 87aa1a9 commit 5b559b5

File tree

6 files changed

+159
-19
lines changed

6 files changed

+159
-19
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2017, 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
3+
4+
package oracle.kubernetes.operator.http;
5+
6+
/**
7+
* Exception when a HTTP status code is received that indicates the request was not successful
8+
*/
9+
public class HTTPException extends Exception {
10+
11+
final int statusCode;
12+
13+
public HTTPException(int statusCode) {
14+
super("status code: " + statusCode);
15+
this.statusCode = statusCode;
16+
}
17+
18+
public int getStatusCode() {
19+
return statusCode;
20+
}
21+
}

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

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,39 +49,97 @@ private HttpClient(Client httpClient, String principal, String encodedCredential
4949
this.encodedCredentials = encodedCredentials;
5050
}
5151

52-
public String executeGetOnServiceClusterIP(String requestUrl, String serviceName, String namespace) {
53-
String serviceURL = SERVICE_URL == null ? getServiceURL(principal, serviceName, namespace) : SERVICE_URL;
52+
/**
53+
* Constructs a URL using the provided service URL and request URL, and use the resulting URL to issue a HTTP GET request
54+
*
55+
* @param requestUrl The request URL containing the request of the REST call
56+
* @param serviceURL The service URL containing the host and port of the server where the HTTP
57+
* request is to be sent to
58+
*
59+
* @return A Result object containing the respond from the REST call
60+
*/
61+
public Result executeGetOnServiceClusterIP(String requestUrl, String serviceURL) {
5462
String url = serviceURL + requestUrl;
5563
WebTarget target = httpClient.target(url);
5664
Invocation.Builder invocationBuilder = target.request().accept("application/json")
5765
.header("Authorization", "Basic " + encodedCredentials);
5866
Response response = invocationBuilder.get();
67+
String responseString = null;
68+
int status = response.getStatus();
69+
boolean successful = false;
5970
if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) {
71+
successful = true;
6072
if (response.hasEntity()) {
61-
return String.valueOf(response.readEntity(String.class));
73+
responseString = String.valueOf(response.readEntity(String.class));
6274
}
6375
} else {
6476
LOGGER.warning(MessageKeys.HTTP_METHOD_FAILED, "GET", url, response.getStatus());
6577
}
66-
return null;
78+
return new Result(responseString, status, successful);
6779
}
6880

69-
public String executePostUrlOnServiceClusterIP(String requestUrl, String serviceURL, String namespace, String payload) {
81+
/**
82+
* Constructs a URL using the provided service URL and request URL, and use the resulting URL and the
83+
* payload provided to issue a HTTP POST request.
84+
* This method does not throw HTTPException if the HTTP request returns failure status code
85+
*
86+
* @param requestUrl The request URL containing the request of the REST call
87+
* @param serviceURL The service URL containing the host and port of the server where the HTTP
88+
* request is to be sent to
89+
* @param payload The payload to be used in the HTTP POST request
90+
*
91+
* @return A Result object containing the respond from the REST call
92+
* @throws HTTPException if throwOnFailure is true and the status of the HTTP response indicates the request was not
93+
* successful
94+
*/ public Result executePostUrlOnServiceClusterIP(String requestUrl, String serviceURL, String payload) {
95+
Result result = null;
96+
try {
97+
result = executePostUrlOnServiceClusterIP(requestUrl, serviceURL, payload, false);
98+
} catch (HTTPException httpException) {
99+
// ignore as executePostUrlOnServiceClusterIP only throw HTTPException if throwOnFailure is true
100+
}
101+
return result;
102+
}
103+
104+
/**
105+
* Constructs a URL using the provided service URL and request URL, and use the resulting URL and the
106+
* payload provided to issue a HTTP POST request
107+
*
108+
* @param requestUrl The request URL containing the request of the REST call
109+
* @param serviceURL The service URL containing the host and port of the server where the HTTP
110+
* request is to be sent to
111+
* @param payload The payload to be used in the HTTP POST request
112+
* @param throwOnFailure Throws HTTPException if the status code in the HTTP response indicates any error
113+
*
114+
* @return A Result object containing the respond from the REST call
115+
* @throws HTTPException if throwOnFailure is true and the status of the HTTP response indicates the request was not
116+
* successful
117+
*/
118+
public Result executePostUrlOnServiceClusterIP(String requestUrl, String serviceURL, String payload,
119+
boolean throwOnFailure) throws HTTPException {
120+
70121
String url = serviceURL + requestUrl;
71122
WebTarget target = httpClient.target(url);
72123
Invocation.Builder invocationBuilder = target.request().accept("application/json")
73124
.header("Authorization", "Basic " + encodedCredentials)
74125
.header("X-Requested-By", "WebLogicOperator");
75126
Response response = invocationBuilder.post(Entity.json(payload));
76127
LOGGER.finer("Response is " + response.getStatusInfo());
128+
String responseString = null;
129+
int status = response.getStatus();
130+
boolean successful = false;
77131
if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) {
132+
successful = true;
78133
if (response.hasEntity()) {
79-
return String.valueOf(response.readEntity(String.class));
134+
responseString = String.valueOf(response.readEntity(String.class));
80135
}
81136
} else {
82137
LOGGER.warning(MessageKeys.HTTP_METHOD_FAILED, "POST", url, response.getStatus());
138+
if (throwOnFailure) {
139+
throw new HTTPException(status);
140+
}
83141
}
84-
return null;
142+
return new Result(responseString, status, successful);
85143
}
86144

87145
/**
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
3+
4+
package oracle.kubernetes.operator.http;
5+
6+
/**
7+
* Holder of response received from REST requests invoked using methods in {@link HttpClient} class
8+
*/
9+
public class Result {
10+
11+
final String response;
12+
final int status;
13+
final boolean successful;
14+
15+
public Result(String response, int status, boolean successful) {
16+
this.response = response;
17+
this.status = status;
18+
this.successful = successful;
19+
}
20+
21+
/**
22+
*
23+
* @return The String response received from the REST request
24+
*/
25+
public String getResponse() {
26+
return response;
27+
}
28+
29+
/**
30+
*
31+
* @return HTTP status code from the REST request
32+
*/
33+
public int getStatus() {
34+
return status;
35+
}
36+
37+
/**
38+
*
39+
* @return True if the REST request returns a status code that indicates successful request, false otherwise
40+
*/
41+
public boolean isSuccessful() {
42+
return successful;
43+
}
44+
45+
@Override
46+
public String toString() {
47+
return "Result{" +
48+
"response='" + response + '\'' +
49+
", status=" + status +
50+
", successful=" + successful +
51+
'}';
52+
}
53+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,6 @@ private MessageKeys() {}
134134
public static final String CLUSTER_SERVICE_DELETED = "WLSKO-0124";
135135
public static final String INGRESS_DELETED = "WLSKO-0125";
136136
public static final String TUNING_PARAMETERS = "WLSKO-0126";
137+
public static final String WLS_HEALTH_READ_FAILED = "WLSKO-0127";
137138

138139
}

operator/src/main/java/oracle/kubernetes/operator/wlsconfig/WlsRetriever.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -188,23 +188,24 @@ public NextAction apply(Packet packet) {
188188
if (RequestType.CONFIG.equals(requestType)) {
189189
WlsDomainConfig wlsDomainConfig = null;
190190
String jsonResult = httpClient.executePostUrlOnServiceClusterIP(
191-
WlsDomainConfig.getRetrieveServersSearchUrl(), serviceURL, namespace,
192-
WlsDomainConfig.getRetrieveServersSearchPayload());
193-
if (jsonResult != null) {
194-
wlsDomainConfig = WlsDomainConfig.create().load(jsonResult);
195-
}
196-
191+
WlsDomainConfig.getRetrieveServersSearchUrl(), serviceURL,
192+
WlsDomainConfig.getRetrieveServersSearchPayload(),
193+
true).getResponse();
194+
195+
wlsDomainConfig = WlsDomainConfig.create().load(jsonResult);
196+
197197
// validate domain spec against WLS configuration. Currently this only logs warning messages.
198198
wlsDomainConfig.updateDomainSpecAsNeeded(dom.getSpec());
199-
199+
200200
info.setScan(wlsDomainConfig);
201201
info.setLastScanTime(new DateTime());
202-
202+
203203
LOGGER.info(MessageKeys.WLS_CONFIGURATION_READ, (System.currentTimeMillis() - ((Long) packet.get(START_TIME))), wlsDomainConfig);
204+
204205
} else { // RequestType.HEALTH
205206
String jsonResult = httpClient.executePostUrlOnServiceClusterIP(
206-
getRetrieveHealthSearchUrl(), serviceURL, namespace,
207-
getRetrieveHealthSearchPayload());
207+
getRetrieveHealthSearchUrl(), serviceURL,
208+
getRetrieveHealthSearchPayload(), true).getResponse();
208209

209210
ObjectMapper mapper = new ObjectMapper();
210211
JsonNode root = mapper.readTree(jsonResult);
@@ -253,7 +254,11 @@ public NextAction apply(Packet packet) {
253254

254255
return doNext(packet);
255256
} catch (Throwable t) {
256-
LOGGER.warning(MessageKeys.WLS_CONFIGURATION_READ_FAILED, t);
257+
if (RequestType.CONFIG.equals(requestType)) {
258+
LOGGER.warning(MessageKeys.WLS_CONFIGURATION_READ_FAILED, t);
259+
} else {
260+
LOGGER.warning(MessageKeys.WLS_HEALTH_READ_FAILED, packet.get(ProcessingConstants.SERVER_NAME), t);
261+
}
257262

258263
// exponential back-off
259264
Integer retryCount = (Integer) packet.get(RETRY_COUNT);
@@ -339,7 +344,8 @@ private WlsDomainConfig getWlsDomainConfig(String principal, long timeout) throw
339344
try {
340345
connectAdminServer(principal);
341346
String serviceURL = HttpClient.getServiceURL(principal, asServiceName, namespace);
342-
String jsonResult = httpClient.executePostUrlOnServiceClusterIP(WlsDomainConfig.getRetrieveServersSearchUrl(), serviceURL, namespace, WlsDomainConfig.getRetrieveServersSearchPayload());
347+
String jsonResult =
348+
httpClient.executePostUrlOnServiceClusterIP(WlsDomainConfig.getRetrieveServersSearchUrl(), serviceURL, WlsDomainConfig.getRetrieveServersSearchPayload()).getResponse();
343349
if (jsonResult != null) {
344350
result = WlsDomainConfig.create().load(jsonResult);
345351
}

operator/src/main/resources/Operator.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,6 @@ WLSKO-0123=Service for domain with domainUID {0} in namespace {1} and with serve
125125
WLSKO-0124=Service for domain with domainUID {0} in namespace {1} and with cluster name {2} deleted; validating domain
126126
WLSKO-0125=Ingress for domain with domainUID {0} in namespace {1} and with cluster name {2} deleted; validating domain
127127
WLSKO-0126=Reloading tuning parameters from Operator's config map
128+
WLSKO-0127=Failed to read health information from server {0} due to exception: {1}
128129
129130

0 commit comments

Comments
 (0)