Skip to content

Add StreamUtils class#935

Merged
ob-stripe merged 1 commit intointegration-client-refactorfrom
ob-stream-utils
Jan 15, 2020
Merged

Add StreamUtils class#935
ob-stripe merged 1 commit intointegration-client-refactorfrom
ob-stream-utils

Conversation

@ob-stripe
Copy link
Contributor

r? @brandur-stripe @richardm-stripe
cc @stripe/api-libraries

Amazingly, Java doesn't provide a standard way of extracting the contents of an InputStream into a String. There are many ways of doing so, this StackOverflow answer shows and compares 11 (!) different ways, some of them relying on third-party libraries.

Previously we were using #3, i.e. using Scanner to tokenize the stream with \A as the delimiter to tokenize the entire stream into a single string. This 1. feels hacky and 2. has pretty bad performance.

In this PR I added a new utility method StreamUtils.readToEnd() that uses #6, i.e. using StringBuilder and InputStreamReader, which feel like the right tools for the job (and should have better performance too).

Tagged as breaking because I changed the type of ApiResource.CHARSET from String to Charset, as well as the constructor of MultipartProcessor, though this shouldn't impact many users.

@ob-stripe
Copy link
Contributor Author

(Also I have vague hopes that this will help with some of the transient build failures we're observing on Travis from time to time, but I'm not holding my breath.)

Copy link
Contributor

@brandur-stripe brandur-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll just inject two general points that reading to the end of the stream can be a little risky in the case of:

  1. Huge response bodies (say you were reading back a large file from S3).
  2. Streaming APIs that don't immediately terminate a response.

However, we're just dealing with trusted endpoints here, and it's no worse than before anyway, so not a big deal. LGTM!

@ob-stripe
Copy link
Contributor Author

Thanks Brandur!

And yes, good point about this being potentially dangerous. Gson does have support for streams, so I think in theory we could deserialize the stream directly into a model, without first loading the entire stream into memory as a string. In practice I don't think we need to bother with this for the reasons you listed.

@ob-stripe ob-stripe merged commit 67fc150 into integration-client-refactor Jan 15, 2020
@ob-stripe ob-stripe deleted the ob-stream-utils branch January 15, 2020 19:05
ob-stripe added a commit that referenced this pull request Jan 15, 2020
ob-stripe added a commit that referenced this pull request Jan 15, 2020
ob-stripe added a commit that referenced this pull request Jan 15, 2020
* Refactor form encoding

* Refactor request telemetry

* Move HTTP request methods into new `HttpClient` class

* Add `StripeRequest` object

* Add `HttpClient` abstract class

* Stop disabling the DNS cache

* Fix deprecation warnings (#895)

* Add HttpContent class (#896)

* Add Stopwatch class (#897)

* Move all request properties in `StripeRequest` (#898)

* Remove ApiResource.RequestType (#899)

* Add support for automatic request retries (#900)

* Minor fixes (#902)

* `StringUtils` class & better API key validation (#928)

* Remove support for custom `URLStreamHandler` (#927)

* Refactor HTTP headers handling (#931)

* Add `CaseInsensitiveMap` class

* Add `HttpHeaders` class

* Use `HttpHeaders` in `StripeRequest`

* Use `HttpHeaders` in `StripeResponse`

* Address review comments

* Modernize `StripeResponse` (#932)

* Add `maxNetworkRetries` as a global and per-request setting (#934)

* Add `StreamUtils` class (#935)

* Remove support for `count` and `total_count` in list objects (#936)

* Codegen for openapi e07de1a (#938)

* Update README (#939)

Co-authored-by: remi-stripe <remi@stripe.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants