Make ICANN reporting not fail on success upload (#791)

* Make ICANN reporting not fail on success upload

According to the spec
(https://tools.ietf.org/html/draft-lozano-icann-registry-interfaces-13#page-16),
when an upload succeeds (HTTP response code 200), the result code
contained in the response message is always 1000 (success). So there is
no need to parse the response content and check the result code. Given
that we are having a problem parsing the response content due to encoding,
it is best that we don't check it so as to not get false negative
alerts when the upload is successful.

The current logic also has a bug: HttpRequest.execute() will by default
throw when the response code is non-20X. Therefore for a 400 response,
our parsing logic never runs on it. Coincidentally, this month when we
uploaded the July activity report (due to stale cursors), we get 400
responses (due to existing reports on the ICANN servers). The stack
trace printed for the thrown exceptions from the 400 responses contained
correctly parsed response contents. This lead us to believe that the issue with
encoding was transient last month. However when we tried again to upload this
month's report, our parser failed again (because the response code was 200 this
time, and our parser actually ran on the response contents).

This seems to suggest that ICANN is sending back readable response
contents, but our parser somehow failed to understand it, assuming that
ICANN is using the same encoding for 200 (which we tried and failed to
parse) and 400 response contents (which caused an exception and was printed
corrected in the stack trace).

This PR changed the transport behavior so that it doesn't throw
automatically for non-20X responses. We will print the content for both
200 and 400 responses, but only try to parse 400 response content. We
put the 400 response in an HttpResponseException and print stack trace
from it, which should display the content correctly so that we can
compare it with the result of our own parsing.

* Add tests
This commit is contained in:
Lai Jiang 2020-09-03 15:57:30 -04:00 committed by GitHub
parent dc8e095e55
commit a86fcf79f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 6 deletions

View file

@ -21,6 +21,8 @@ import static google.registry.testing.DatastoreHelper.createTld;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.http.LowLevelHttpRequest;
import com.google.api.client.http.LowLevelHttpResponse;
import com.google.api.client.testing.http.MockHttpTransport;
@ -50,7 +52,8 @@ class IcannHttpReporterTest {
AppEngineExtension appEngineRule =
new AppEngineExtension.Builder().withDatastoreAndCloudSql().build();
private MockHttpTransport createMockTransport(final ByteSource iirdeaResponse) {
private MockHttpTransport createMockTransport(
int statusCode, final ByteSource iirdeaResponse) {
return new MockHttpTransport() {
@Override
public LowLevelHttpRequest buildRequest(String method, String url) {
@ -59,7 +62,7 @@ class IcannHttpReporterTest {
@Override
public LowLevelHttpResponse execute() throws IOException {
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
response.setStatusCode(200);
response.setStatusCode(statusCode);
response.setContentType(PLAIN_TEXT_UTF_8.toString());
response.setContent(iirdeaResponse.read());
return response;
@ -71,6 +74,10 @@ class IcannHttpReporterTest {
};
}
private MockHttpTransport createMockTransport(final ByteSource iirdeaResponse) {
return createMockTransport(HttpStatusCodes.STATUS_CODE_OK, iirdeaResponse);
}
@BeforeEach
void beforeEach() {
createTld("test");
@ -117,10 +124,21 @@ class IcannHttpReporterTest {
@Test
void testFail_BadIirdeaResponse() throws Exception {
IcannHttpReporter reporter = createReporter();
reporter.httpTransport = createMockTransport(IIRDEA_BAD_XML);
reporter.httpTransport =
createMockTransport(HttpStatusCodes.STATUS_CODE_BAD_REQUEST, IIRDEA_BAD_XML);
assertThat(reporter.send(FAKE_PAYLOAD, "test-transactions-201706.csv")).isFalse();
}
@Test
void testFail_transportException() throws Exception {
IcannHttpReporter reporter = createReporter();
reporter.httpTransport =
createMockTransport(HttpStatusCodes.STATUS_CODE_FORBIDDEN, ByteSource.empty());
assertThrows(
HttpResponseException.class,
() -> reporter.send(FAKE_PAYLOAD, "test-transactions-201706.csv"));
}
@Test
void testFail_invalidFilename_nonSixDigitYearMonth() {
IcannHttpReporter reporter = createReporter();