Skip to content

Commit 92ccd50

Browse files
committed
changes for closing httpResponse
1 parent 8f4832a commit 92ccd50

18 files changed

Lines changed: 266 additions & 98 deletions

src/main/java/io/cdap/plugin/servicenow/apiclient/ServiceNowTableAPIClientImpl.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ public MetadataAPISchemaResponse parseSchemaResponse(InputStream responseStream)
266266
* @throws ServiceNowAPIException
267267
*/
268268
public Schema fetchTableSchema(String tableName, SourceValueType valueType)
269-
throws ServiceNowAPIException {
270-
return fetchTableSchema(tableName, getAccessToken(), valueType, schemaType, false);
269+
throws ServiceNowAPIException {
270+
return fetchTableSchema(tableName, getAccessToken(), valueType, schemaType, true);
271271
}
272272

273273
private SchemaType getSchemaTypeBasedOnUseConnection(Boolean useConnection) {
@@ -291,7 +291,7 @@ private SchemaType getSchemaTypeBasedOnUseConnection(Boolean useConnection) {
291291
*/
292292
public Schema fetchTableSchema(String tableName, String accessToken, SourceValueType valueType,
293293
SchemaType schemaType, Boolean legacyMapping)
294-
throws ServiceNowAPIException {
294+
throws ServiceNowAPIException {
295295
ServiceNowTableAPIRequestBuilder requestBuilder = new ServiceNowTableAPIRequestBuilder(
296296
this.conf.getRestApiEndpoint(), tableName, true, schemaType)
297297
.setExcludeReferenceLink(true);
@@ -301,12 +301,16 @@ public Schema fetchTableSchema(String tableName, String accessToken, SourceValue
301301
restAPIResponse = executeGetWithRetries(requestBuilder.build());
302302
List<ServiceNowColumn> columns = new ArrayList<>();
303303

304-
if (schemaType == SchemaType.METADATA_API_BASED) {
305-
return prepareSchemaWithMetadataAPI(restAPIResponse, columns, tableName, valueType, legacyMapping);
306-
} else if (schemaType == SchemaType.SCHEMA_API_BASED) {
307-
return prepareSchemaWithSchemaAPI(restAPIResponse, columns, tableName);
308-
} else {
309-
return prepareStringBasedSchema(restAPIResponse, columns, tableName);
304+
try {
305+
if (schemaType == SchemaType.METADATA_API_BASED) {
306+
return prepareSchemaWithMetadataAPI(restAPIResponse, columns, tableName, valueType, legacyMapping);
307+
} else if (schemaType == SchemaType.SCHEMA_API_BASED) {
308+
return prepareSchemaWithSchemaAPI(restAPIResponse, columns, tableName, legacyMapping);
309+
} else {
310+
return prepareStringBasedSchema(restAPIResponse, columns, tableName, legacyMapping);
311+
}
312+
} catch (IOException exception) {
313+
throw new RuntimeException("Error in fetching schema for table " + tableName, exception);
310314
}
311315
}
312316

@@ -327,7 +331,7 @@ public Schema fetchTableSchema(String tableName, String accessToken, SourceValue
327331
* @throws RuntimeException if the schema response is null or contains no result.
328332
*/
329333
private Schema prepareSchemaWithSchemaAPI(RestAPIResponse restAPIResponse, List<ServiceNowColumn> columns,
330-
String tableName) throws ServiceNowAPIException {
334+
String tableName, Boolean legacyMapping) throws ServiceNowAPIException, IOException {
331335
SchemaAPISchemaResponse schemaAPISchemaResponse =
332336
GSON.fromJson(createJsonReader(restAPIResponse.getResponseStream()), SchemaAPISchemaResponse.class);
333337

@@ -339,7 +343,7 @@ private Schema prepareSchemaWithSchemaAPI(RestAPIResponse restAPIResponse, List<
339343
for (SchemaAPISchemaField field : schemaAPISchemaResponse.getResult()) {
340344
columns.add(new ServiceNowColumn(field.getName(), field.getInternalType()));
341345
}
342-
return SchemaBuilder.constructSchema(tableName, columns, false);
346+
return SchemaBuilder.constructSchema(tableName, columns, legacyMapping);
343347
}
344348

345349
/**
@@ -361,7 +365,7 @@ private Schema prepareSchemaWithSchemaAPI(RestAPIResponse restAPIResponse, List<
361365
* @throws RuntimeException if the response does not contain valid column information.
362366
*/
363367
private Schema prepareSchemaWithMetadataAPI(RestAPIResponse restAPIResponse, List<ServiceNowColumn> columns,
364-
String tableName, SourceValueType valueType, Boolean legacyMapping) throws ServiceNowAPIException {
368+
String tableName, SourceValueType valueType, Boolean legacyMapping) throws ServiceNowAPIException, IOException {
365369
MetadataAPISchemaResponse metadataAPISchemaResponse = parseSchemaResponse(restAPIResponse.getResponseStream());
366370

367371
if (metadataAPISchemaResponse.getResult() == null || metadataAPISchemaResponse.getResult().getColumns() == null ||
@@ -492,7 +496,7 @@ public String createRecordInDisplayMode(String tableName, HttpEntity entity) thr
492496
return systemID;
493497
}
494498

495-
private String getSystemId(RestAPIResponse restAPIResponse) {
499+
private String getSystemId(RestAPIResponse restAPIResponse) throws IOException {
496500
CreateRecordAPIResponse apiResponse = GSON.fromJson(
497501
new InputStreamReader(restAPIResponse.getResponseStream(), StandardCharsets.UTF_8),
498502
CreateRecordAPIResponse.class);
@@ -507,7 +511,7 @@ private String getSystemId(RestAPIResponse restAPIResponse) {
507511
* @param query The query
508512
*/
509513
public JsonObject getRecordFromServiceNowTable(String tableName, String query)
510-
throws ServiceNowAPIException {
514+
throws ServiceNowAPIException, IOException {
511515

512516
ServiceNowTableAPIRequestBuilder requestBuilder = new ServiceNowTableAPIRequestBuilder(
513517
this.conf.getRestApiEndpoint(), tableName, false, schemaType)
@@ -537,7 +541,7 @@ public JsonObject getRecordFromServiceNowTable(String tableName, String query)
537541
* @throws RuntimeException if the schema response is null or contains no result.
538542
*/
539543
private Schema prepareStringBasedSchema(RestAPIResponse restAPIResponse, List<ServiceNowColumn> columns,
540-
String tableName) {
544+
String tableName, Boolean legacyMapping) throws IOException {
541545
InputStream in = restAPIResponse.getResponseStream();
542546
JsonReader reader = new JsonReader(new InputStreamReader(in, StandardCharsets.UTF_8));
543547
JsonObject firstRecord;
@@ -551,7 +555,7 @@ private Schema prepareStringBasedSchema(RestAPIResponse restAPIResponse, List<Se
551555
firstRecord.entrySet().forEach(entry ->
552556
columns.add(new ServiceNowColumn(entry.getKey(), "string"))
553557
);
554-
return SchemaBuilder.constructSchema(tableName, columns, false);
558+
return SchemaBuilder.constructSchema(tableName, columns, legacyMapping);
555559
}
556560
return null;
557561
}

src/main/java/io/cdap/plugin/servicenow/connector/ServiceNowConnector.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public BrowseDetail browse(ConnectorContext connectorContext, BrowseRequest brow
108108
* Browse Details for the given AccessToken.
109109
*/
110110
public BrowseDetail browse(ConnectorContext connectorContext,
111-
String accessToken) throws ServiceNowAPIException {
111+
String accessToken) throws ServiceNowAPIException, IOException {
112112
int count = 0;
113113
FailureCollector collector = connectorContext.getFailureCollector();
114114
config.validateCredentialsFields(collector);
@@ -131,7 +131,7 @@ public BrowseDetail browse(ConnectorContext connectorContext,
131131
/**
132132
* @return the list of tables.
133133
*/
134-
private TableList listTables(String accessToken) throws ServiceNowAPIException {
134+
private TableList listTables(String accessToken) throws ServiceNowAPIException, IOException {
135135
ServiceNowTableAPIRequestBuilder requestBuilder = new ServiceNowTableAPIRequestBuilder(
136136
config.getRestApiEndpoint(), OBJECT_TABLE_LIST, false, SchemaType.SCHEMA_API_BASED);
137137
requestBuilder.setAuthHeader(accessToken);

src/main/java/io/cdap/plugin/servicenow/restapi/RestAPIClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public abstract class RestAPIClient {
5959
private static final int DEFAULT_CONNECT_TIMEOUT_MS = 120000;
6060

6161
/* Read Timeout in ms for waiting for data after the connection is established */
62-
private static final int DEFAULT_READ_TIMEOUT_MS = 300000;
62+
private static final int DEFAULT_READ_TIMEOUT_MS = 90000;
6363

6464
/* Maximum total connections. */
6565
private static final int MAX_CONNECTIONS = 200;

src/main/java/io/cdap/plugin/servicenow/restapi/RestAPIResponse.java

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.http.HttpEntity;
2525
import org.apache.http.HttpResponse;
2626
import org.apache.http.HttpStatus;
27+
import org.apache.http.client.methods.CloseableHttpResponse;
2728
import org.slf4j.Logger;
2829
import org.slf4j.LoggerFactory;
2930

@@ -52,15 +53,15 @@ public class RestAPIResponse {
5253
private final Map<String, String> headers;
5354
@Nullable private final ServiceNowAPIException exception;
5455

55-
// Input stream of the response body.
56-
private InputStream responseStream;
56+
// Keep reference of HttpResponse for error handling, as it needs to be closed after consuming the response stream.
57+
private HttpResponse httpResponse;
5758

5859
public RestAPIResponse(
5960
Map<String, String> headers,
60-
InputStream responseStream,
61+
HttpResponse httpResponse,
6162
@Nullable ServiceNowAPIException exception) {
6263
this.headers = headers;
63-
this.responseStream = responseStream;
64+
this.httpResponse = httpResponse;
6465
this.exception = exception;
6566
}
6667

@@ -89,22 +90,27 @@ public static RestAPIResponse parse(HttpResponse httpResponse, String... headerN
8990

9091
ServiceNowAPIException serviceNowAPIException = validateHttpResponse(httpResponse);
9192
if (serviceNowAPIException != null) {
92-
return new RestAPIResponse(headers, null, serviceNowAPIException);
93-
}
94-
try {
95-
return prepareResponse(httpResponse, headers, serviceNowAPIException);
96-
} catch (IOException e) {
97-
return new RestAPIResponse(headers, null, new ServiceNowAPIException(e, httpResponse));
93+
return new RestAPIResponse(headers, httpResponse, serviceNowAPIException);
9894
}
95+
return new RestAPIResponse(headers, httpResponse, null);
9996
}
10097

10198
public void close() throws IOException {
102-
if (responseStream != null) {
103-
responseStream.close();
99+
try {
100+
InputStream responseStream = getResponseStream();
101+
if (responseStream != null) {
102+
LOG.info("Closing response stream");
103+
responseStream.close();
104+
}
105+
} finally {
106+
if (httpResponse instanceof CloseableHttpResponse) {
107+
LOG.info("Closing HttpResponse");
108+
((CloseableHttpResponse) httpResponse).close();
109+
}
104110
}
105111
}
106112

107-
public static RestAPIResponse prepareResponse(HttpResponse httpResponse, Map<String, String> headers,
113+
/*public static RestAPIResponse prepareResponse(HttpResponse httpResponse, Map<String, String> headers,
108114
ServiceNowAPIException serviceNowAPIException) throws IOException {
109115
HttpEntity httpEntity = httpResponse.getEntity();
110116
InputStream inputStream;
@@ -114,7 +120,7 @@ public static RestAPIResponse prepareResponse(HttpResponse httpResponse, Map<Str
114120
} else {
115121
return new RestAPIResponse(headers, null, serviceNowAPIException);
116122
}
117-
}
123+
}*/
118124

119125
public static RestAPIResponse parse(HttpResponse httpResponse) throws IOException {
120126
return parse(httpResponse, new String[0]);
@@ -158,7 +164,11 @@ public boolean hasException() {
158164
return exception != null;
159165
}
160166

161-
public InputStream getResponseStream() {
162-
return responseStream;
167+
public InputStream getResponseStream() throws IOException {
168+
if (httpResponse == null) {
169+
return null;
170+
}
171+
HttpEntity entity = httpResponse.getEntity();
172+
return (entity != null) ? entity.getContent() : null;
163173
}
164174
}

src/main/java/io/cdap/plugin/servicenow/sink/service/ServiceNowSinkAPIRequestImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public void createPostRequest(Map<String, RestRequest> restRequestsMap, String a
171171
}
172172
}
173173

174-
private JsonReader getJsonReader(RestAPIResponse apiResponse) {
174+
private JsonReader getJsonReader(RestAPIResponse apiResponse) throws IOException {
175175
InputStreamReader inputStreamReader = new InputStreamReader(apiResponse.getResponseStream(),
176176
StandardCharsets.UTF_8);
177177
JsonReader jsonReader = new JsonReader(inputStreamReader);

src/main/java/io/cdap/plugin/servicenow/source/ServiceNowBaseRecordReader.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public abstract class ServiceNowBaseRecordReader extends RecordReader<NullWritab
5151
protected JsonObject row;
5252
protected final Gson gson = new Gson();
5353
protected JsonReader jsonReader = null;
54+
protected RestAPIResponse currentResponse = null;
5455

5556
public ServiceNowBaseRecordReader() {
5657
}
@@ -93,9 +94,10 @@ public boolean nextKeyValue() throws IOException {
9394

9495
public boolean openNextPage() throws IOException, ServiceNowAPIException {
9596
closeCurrentPage();
96-
RestAPIResponse resp = fetchData();
97-
InputStream in = resp.getResponseStream();
97+
this.currentResponse = fetchData();
98+
InputStream in = this.currentResponse.getResponseStream();
9899
if (in == null) {
100+
closeCurrentPage();
99101
return false;
100102
}
101103
this.jsonReader = new JsonReader(new InputStreamReader(in, StandardCharsets.UTF_8));
@@ -137,7 +139,6 @@ public boolean openNextPage() throws IOException, ServiceNowAPIException {
137139
jsonReader.endArray();
138140
// cleanup
139141
closeCurrentPage();
140-
closeRestAPIResponse(resp);
141142
return false;
142143
}
143144
} catch (IOException e) {
@@ -151,6 +152,7 @@ public boolean openNextPage() throws IOException, ServiceNowAPIException {
151152
}
152153

153154
public void closeCurrentPage() {
155+
LOG.info("Closing current page for table {}", tableName);
154156
if (this.jsonReader != null) {
155157
try {
156158
this.jsonReader.close();
@@ -160,14 +162,14 @@ public void closeCurrentPage() {
160162
this.jsonReader = null;
161163
}
162164
}
163-
}
164165

165-
public void closeRestAPIResponse(RestAPIResponse resp) {
166-
if (resp != null) {
166+
if (this.currentResponse != null) {
167167
try {
168-
resp.close();
168+
this.currentResponse.close();
169169
} catch (IOException e) {
170-
LOG.warn("Error closing RestAPIResponse", e);
170+
LOG.warn("Error closing RestAPIResponse for table {}", tableName, e);
171+
} finally {
172+
this.currentResponse = null;
171173
}
172174
}
173175
}
@@ -184,6 +186,11 @@ public float getProgress() throws IOException, InterruptedException {
184186
return pos / (float) split.getLength();
185187
}
186188

189+
public int getPos() {
190+
return pos;
191+
}
192+
187193
public void close() throws IOException {
194+
closeCurrentPage();
188195
}
189196
}

src/main/java/io/cdap/plugin/servicenow/source/ServiceNowRecordReader.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ public StructuredRecord getCurrentValue() throws IOException {
8787

8888
@Override
8989
RestAPIResponse fetchData() throws ServiceNowAPIException {
90+
LOG.info("Fetching data for table: {}, with offset: {} and page size: {}", tableName, split.getOffset(),
91+
pluginConf.getPageSize());
9092
// Get the table data
9193
RestAPIResponse restAPIResponse = restApi.fetchTableRecordsRetryableMode(tableName, pluginConf.getValueType(),
9294
split.getFilterQuery() , split.getOffset(), pluginConf.getPageSize());

0 commit comments

Comments
 (0)