Skip to content

Commit ed6d548

Browse files
authored
Switches to client library request and adds exponential backoff (GoogleCloudPlatform#979)
1 parent 5aff7b9 commit ed6d548

File tree

1 file changed

+85
-36
lines changed
  • iot/api-client/manager/src/main/java/com/example/cloud/iot/examples

1 file changed

+85
-36
lines changed

iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExample.java

Lines changed: 85 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,32 @@
1818
package com.example.cloud.iot.examples;
1919

2020
// [START cloudiotcore_http_imports]
21+
import com.google.api.client.http.ByteArrayContent;
22+
import com.google.api.client.http.GenericUrl;
23+
import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
24+
import com.google.api.client.http.HttpHeaders;
25+
import com.google.api.client.http.HttpRequest;
26+
import com.google.api.client.http.HttpRequestFactory;
27+
import com.google.api.client.http.HttpRequestInitializer;
28+
import com.google.api.client.http.HttpResponse;
29+
import com.google.api.client.http.HttpTransport;
30+
import com.google.api.client.http.javanet.NetHttpTransport;
31+
import com.google.api.client.json.JsonFactory;
32+
import com.google.api.client.json.JsonObjectParser;
33+
import com.google.api.client.json.jackson2.JacksonFactory;
34+
35+
import com.google.api.client.util.Charsets;
36+
import com.google.api.client.util.ExponentialBackOff;
37+
import com.google.common.io.CharStreams;
2138
import io.jsonwebtoken.JwtBuilder;
2239
import io.jsonwebtoken.Jwts;
2340
import io.jsonwebtoken.SignatureAlgorithm;
41+
2442
import java.io.IOException;
2543
import java.io.InputStream;
44+
import java.io.InputStreamReader;
2645
import java.io.UnsupportedEncodingException;
27-
import java.net.HttpURLConnection;
2846
import java.net.ProtocolException;
29-
import java.net.URL;
3047
import java.nio.file.Files;
3148
import java.nio.file.Paths;
3249
import java.security.KeyFactory;
@@ -49,6 +66,9 @@
4966
* folder.
5067
*/
5168
public class HttpExample {
69+
static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
70+
static final JsonFactory JSON_FACTORY = new JacksonFactory();
71+
5272
// [START cloudiotcore_http_createjwt]
5373
/** Create a RSA-based JWT for the given project id, signed with the given private key. */
5474
private static String createJwtRsa(String projectId, String privateKeyFile) throws Exception {
@@ -99,32 +119,41 @@ public static void getConfig(String urlPath, String token, String projectId,
99119
String.format(
100120
"projects/%s/locations/%s/registries/%s/devices/%s",
101121
projectId, cloudRegion, registryId, deviceId);
102-
103122
urlPath = urlPath + devicePath + "/config?local_version=" + version;
104-
System.out.println(urlPath);
105-
URL url = new URL(urlPath);
106-
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
107-
httpCon.setDoOutput(true);
108-
httpCon.setRequestMethod("GET");
109-
110-
// Add headers.
111-
httpCon.setRequestProperty("authorization", String.format("Bearer %s", token));
112-
httpCon.setRequestProperty("content-type", "application/json; charset=UTF-8");
113-
httpCon.setRequestProperty("cache-control", "no-cache");
114-
115-
System.out.println(httpCon.getResponseCode());
116-
System.out.println(httpCon.getResponseMessage());
117-
byte[] buffer = new byte[1024];
118-
InputStream in = httpCon.getInputStream();
119-
int len = in.read(buffer);
120-
while (len != -1) {
121-
System.out.write(buffer, 0, len);
122-
len = in.read(buffer);
123-
}
123+
124+
HttpRequestFactory requestFactory =
125+
HTTP_TRANSPORT.createRequestFactory(new HttpRequestInitializer() {
126+
@Override
127+
public void initialize(HttpRequest request) {
128+
request.setParser(new JsonObjectParser(JSON_FACTORY));
129+
}
130+
});
131+
132+
final HttpRequest req = requestFactory.buildGetRequest(new GenericUrl(urlPath));
133+
HttpHeaders heads = new HttpHeaders();
134+
135+
heads.setAuthorization(String.format("Bearer %s", token));
136+
heads.setContentType("application/json; charset=UTF-8");
137+
heads.setCacheControl("no-cache");
138+
139+
req.setHeaders(heads);
140+
ExponentialBackOff backoff = new ExponentialBackOff.Builder()
141+
.setInitialIntervalMillis(500)
142+
.setMaxElapsedTimeMillis(900000)
143+
.setMaxIntervalMillis(6000)
144+
.setMultiplier(1.5)
145+
.setRandomizationFactor(0.5)
146+
.build();
147+
req.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(backoff));
148+
HttpResponse res = req.execute();
149+
System.out.println(res.getStatusCode());
150+
System.out.println(res.getStatusMessage());
151+
InputStream in = res.getContent();
152+
153+
System.out.println(CharStreams.toString(new InputStreamReader(in, Charsets.UTF_8)));
124154
}
125155
// [END cloudiotcore_http_getconfig]
126156

127-
128157
// [START cloudiotcore_http_publishmessage]
129158
/** Publish an event or state message using Cloud IoT Core via the HTTP API. */
130159
public static void publishMessage(String payload, String urlPath, String messageType,
@@ -143,15 +172,20 @@ public static void publishMessage(String payload, String urlPath, String message
143172
String encPayload = encoder.encodeToString(payload.getBytes("UTF-8"));
144173

145174
urlPath = urlPath + devicePath + ":" + urlSuffix;
146-
URL url = new URL(urlPath);
147-
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
148-
httpCon.setDoOutput(true);
149-
httpCon.setRequestMethod("POST");
150175

151-
// Add headers.
152-
httpCon.setRequestProperty("authorization", String.format("Bearer %s", token));
153-
httpCon.setRequestProperty("content-type", "application/json; charset=UTF-8");
154-
httpCon.setRequestProperty("cache-control", "no-cache");
176+
177+
final HttpRequestFactory requestFactory =
178+
HTTP_TRANSPORT.createRequestFactory(new HttpRequestInitializer() {
179+
@Override
180+
public void initialize(HttpRequest request) {
181+
request.setParser(new JsonObjectParser(JSON_FACTORY));
182+
}
183+
});
184+
185+
HttpHeaders heads = new HttpHeaders();
186+
heads.setAuthorization(String.format("Bearer %s", token));
187+
heads.setContentType("application/json; charset=UTF-8");
188+
heads.setCacheControl("no-cache");
155189

156190
// Add post data. The data sent depends on whether we're updating state or publishing events.
157191
JSONObject data = new JSONObject();
@@ -162,11 +196,26 @@ public static void publishMessage(String payload, String urlPath, String message
162196
state.put("binary_data", encPayload);
163197
data.put("state", state);
164198
}
165-
httpCon.getOutputStream().write(data.toString().getBytes("UTF-8"));
166-
httpCon.getOutputStream().close();
167199

168-
System.out.println(httpCon.getResponseCode());
169-
System.out.println(httpCon.getResponseMessage());
200+
ByteArrayContent content = new ByteArrayContent(
201+
"application/json", data.toString().getBytes("UTF-8"));
202+
203+
final HttpRequest req = requestFactory.buildGetRequest(new GenericUrl(urlPath));
204+
req.setHeaders(heads);
205+
req.setContent(content);
206+
req.setRequestMethod("POST");
207+
ExponentialBackOff backoff = new ExponentialBackOff.Builder()
208+
.setInitialIntervalMillis(500)
209+
.setMaxElapsedTimeMillis(900000)
210+
.setMaxIntervalMillis(6000)
211+
.setMultiplier(1.5)
212+
.setRandomizationFactor(0.5)
213+
.build();
214+
req.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(backoff));
215+
216+
HttpResponse res = req.execute();
217+
System.out.println(res.getStatusCode());
218+
System.out.println(res.getStatusMessage());
170219
}
171220
// [END cloudiotcore_http_publishmessage]
172221

0 commit comments

Comments
 (0)