Add RDAP pretty-printing option

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=176529676
This commit is contained in:
mountford 2017-11-21 10:41:01 -08:00 committed by jianglai
parent 6f659659ff
commit 67a41273bb
13 changed files with 71 additions and 9 deletions

View file

@ -21,6 +21,7 @@ java_library(
"@com_google_code_findbugs_jsr305", "@com_google_code_findbugs_jsr305",
"@com_google_dagger", "@com_google_dagger",
"@com_google_guava", "@com_google_guava",
"@com_google_http_client_jackson2",
"@com_google_re2j", "@com_google_re2j",
"@com_googlecode_json_simple", "@com_googlecode_json_simple",
"@javax_servlet_api", "@javax_servlet_api",

View file

@ -25,6 +25,7 @@ import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_OK; import static javax.servlet.http.HttpServletResponse.SC_OK;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.net.MediaType; import com.google.common.net.MediaType;
import com.google.re2j.Pattern; import com.google.re2j.Pattern;
@ -48,6 +49,7 @@ import google.registry.request.auth.AuthResult;
import google.registry.request.auth.UserAuthInfo; import google.registry.request.auth.UserAuthInfo;
import google.registry.ui.server.registrar.SessionUtils; import google.registry.ui.server.registrar.SessionUtils;
import google.registry.util.FormattingLogger; import google.registry.util.FormattingLogger;
import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
@ -89,6 +91,7 @@ public abstract class RdapActionBase implements Runnable {
@Inject RdapJsonFormatter rdapJsonFormatter; @Inject RdapJsonFormatter rdapJsonFormatter;
@Inject @Parameter("registrar") Optional<String> registrarParam; @Inject @Parameter("registrar") Optional<String> registrarParam;
@Inject @Parameter("includeDeleted") Optional<Boolean> includeDeletedParam; @Inject @Parameter("includeDeleted") Optional<Boolean> includeDeletedParam;
@Inject @Parameter("formatOutput") Optional<Boolean> formatOutputParam;
@Inject @Config("rdapWhoisServer") @Nullable String rdapWhoisServer; @Inject @Config("rdapWhoisServer") @Nullable String rdapWhoisServer;
@Inject @Config("rdapResultSetMaxSize") int rdapResultSetMaxSize; @Inject @Config("rdapResultSetMaxSize") int rdapResultSetMaxSize;
@Inject RdapMetrics rdapMetrics; @Inject RdapMetrics rdapMetrics;
@ -143,9 +146,7 @@ public abstract class RdapActionBase implements Runnable {
pathProper.substring(getActionPath().length()), requestMethod == Action.Method.HEAD); pathProper.substring(getActionPath().length()), requestMethod == Action.Method.HEAD);
response.setStatus(SC_OK); response.setStatus(SC_OK);
response.setContentType(RESPONSE_MEDIA_TYPE); response.setContentType(RESPONSE_MEDIA_TYPE);
if (requestMethod != Action.Method.HEAD) { setPayload(rdapJson);
response.setPayload(JSONValue.toJSONString(rdapJson));
}
metricInformationBuilder.setStatusCode(SC_OK); metricInformationBuilder.setStatusCode(SC_OK);
} catch (HttpException e) { } catch (HttpException e) {
setError(e.getResponseCode(), e.getResponseCodeString(), e.getMessage()); setError(e.getResponseCode(), e.getResponseCodeString(), e.getMessage());
@ -163,15 +164,25 @@ public abstract class RdapActionBase implements Runnable {
response.setStatus(status); response.setStatus(status);
response.setContentType(RESPONSE_MEDIA_TYPE); response.setContentType(RESPONSE_MEDIA_TYPE);
try { try {
if (requestMethod != Action.Method.HEAD) { setPayload(rdapJsonFormatter.makeError(status, title, description));
response.setPayload(
JSONValue.toJSONString(rdapJsonFormatter.makeError(status, title, description)));
}
} catch (Exception ex) { } catch (Exception ex) {
if (requestMethod != Action.Method.HEAD) {
response.setPayload(""); response.setPayload("");
} }
} }
void setPayload(ImmutableMap<String, Object> rdapJson) {
if (requestMethod == Action.Method.HEAD) {
return;
}
if (formatOutputParam.orElse(false)) {
try {
response.setPayload(new JacksonFactory().toPrettyString(rdapJson));
return;
} catch (IOException e) {
// On exception, fall back to unformatted output
}
}
response.setPayload(JSONValue.toJSONString(rdapJson));
} }
RdapAuthorization getAuthorization() { RdapAuthorization getAuthorization() {

View file

@ -72,4 +72,10 @@ public final class RdapModule {
static Optional<Boolean> provideIncludeDeleted(HttpServletRequest req) { static Optional<Boolean> provideIncludeDeleted(HttpServletRequest req) {
return RequestParameters.extractOptionalBooleanParameter(req, "includeDeleted"); return RequestParameters.extractOptionalBooleanParameter(req, "includeDeleted");
} }
@Provides
@Parameter("formatOutput")
static Optional<Boolean> provideFormatOutput(HttpServletRequest req) {
return RequestParameters.extractOptionalBooleanParameter(req, "formatOutput");
}
} }

View file

@ -123,6 +123,7 @@ public class RdapActionBaseTest {
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo); action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
action.includeDeletedParam = Optional.empty(); action.includeDeletedParam = Optional.empty();
action.registrarParam = Optional.empty(); action.registrarParam = Optional.empty();
action.formatOutputParam = Optional.empty();
action.response = response; action.response = response;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter(); action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapMetrics = rdapMetrics; action.rdapMetrics = rdapMetrics;
@ -231,4 +232,25 @@ public class RdapActionBaseTest {
.setIncompletenessWarningType(IncompletenessWarningType.COMPLETE) .setIncompletenessWarningType(IncompletenessWarningType.COMPLETE)
.build()); .build());
} }
@Test
public void testUnformatted() throws Exception {
action.requestPath = RdapTestAction.PATH + "no.thing";
action.fullServletPath = "http://myserver.example.com" + RdapTestAction.PATH;
action.requestMethod = GET;
action.run();
assertThat(response.getPayload() + '\n').isEqualTo(
loadFileWithSubstitutions(this.getClass(), "rdap_unformatted_output.json", null));
}
@Test
public void testFormatted() throws Exception {
action.requestPath = RdapTestAction.PATH + "no.thing?formatOutput=true";
action.fullServletPath = "http://myserver.example.com" + RdapTestAction.PATH;
action.requestMethod = GET;
action.formatOutputParam = Optional.of(true);
action.run();
assertThat(response.getPayload() + '\n').isEqualTo(
loadFileWithSubstitutions(this.getClass(), "rdap_formatted_output.json", null));
}
} }

View file

@ -268,6 +268,7 @@ public class RdapDomainActionTest {
action.response = response; action.response = response;
action.registrarParam = Optional.empty(); action.registrarParam = Optional.empty();
action.includeDeletedParam = Optional.empty(); action.includeDeletedParam = Optional.empty();
action.formatOutputParam = Optional.empty();
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter(); action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapWhoisServer = null; action.rdapWhoisServer = null;
action.sessionUtils = sessionUtils; action.sessionUtils = sessionUtils;

View file

@ -375,6 +375,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase {
action.response = response; action.response = response;
action.registrarParam = Optional.empty(); action.registrarParam = Optional.empty();
action.includeDeletedParam = Optional.empty(); action.includeDeletedParam = Optional.empty();
action.formatOutputParam = Optional.empty();
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter(); action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapWhoisServer = null; action.rdapWhoisServer = null;
action.sessionUtils = sessionUtils; action.sessionUtils = sessionUtils;

View file

@ -169,6 +169,7 @@ public class RdapEntityActionTest {
action.response = response; action.response = response;
action.registrarParam = Optional.empty(); action.registrarParam = Optional.empty();
action.includeDeletedParam = Optional.empty(); action.includeDeletedParam = Optional.empty();
action.formatOutputParam = Optional.empty();
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter(); action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapWhoisServer = null; action.rdapWhoisServer = null;
action.sessionUtils = sessionUtils; action.sessionUtils = sessionUtils;

View file

@ -160,6 +160,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase {
action.handleParam = Optional.empty(); action.handleParam = Optional.empty();
action.registrarParam = Optional.empty(); action.registrarParam = Optional.empty();
action.includeDeletedParam = Optional.empty(); action.includeDeletedParam = Optional.empty();
action.formatOutputParam = Optional.empty();
action.sessionUtils = sessionUtils; action.sessionUtils = sessionUtils;
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo); action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
action.rdapMetrics = rdapMetrics; action.rdapMetrics = rdapMetrics;

View file

@ -71,6 +71,7 @@ public class RdapHelpActionTest {
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo); action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
action.includeDeletedParam = Optional.empty(); action.includeDeletedParam = Optional.empty();
action.registrarParam = Optional.empty(); action.registrarParam = Optional.empty();
action.formatOutputParam = Optional.empty();
action.response = response; action.response = response;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter(); action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapWhoisServer = null; action.rdapWhoisServer = null;

View file

@ -124,6 +124,7 @@ public class RdapNameserverActionTest {
action.requestPath = RdapNameserverAction.PATH.concat(input); action.requestPath = RdapNameserverAction.PATH.concat(input);
action.registrarParam = desiredRegistrar; action.registrarParam = desiredRegistrar;
action.includeDeletedParam = includeDeleted; action.includeDeletedParam = includeDeleted;
action.formatOutputParam = Optional.empty();
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter(); action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapWhoisServer = null; action.rdapWhoisServer = null;
action.authResult = authResult; action.authResult = authResult;

View file

@ -164,6 +164,7 @@ public class RdapNameserverSearchActionTest extends RdapSearchActionTestCase {
action.nameParam = Optional.empty(); action.nameParam = Optional.empty();
action.registrarParam = Optional.empty(); action.registrarParam = Optional.empty();
action.includeDeletedParam = Optional.empty(); action.includeDeletedParam = Optional.empty();
action.formatOutputParam = Optional.empty();
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo); action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
action.sessionUtils = sessionUtils; action.sessionUtils = sessionUtils;
action.rdapMetrics = rdapMetrics; action.rdapMetrics = rdapMetrics;

View file

@ -0,0 +1,14 @@
{
"key" : "value",
"rdapConformance" : [ "rdap_level_0" ],
"notices" : [ {
"title" : "RDAP Terms of Service",
"description" : [ "By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.", "Any information provided is 'as is' without any guarantee of accuracy.", "Please do not misuse the Domain Database. It is intended solely for query-based access.", "Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.", "Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of any ICANN-accredited registrar.", "You may only use the information contained in the Domain Database for lawful purposes.", "Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.", "We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.", "We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.", "We reserve the right to modify this agreement at any time." ],
"links" : [ {
"value" : "http://myserver.example.com/help/tos",
"rel" : "alternate",
"href" : "https://www.registry.tld/about/rdap/tos.html",
"type" : "text/html"
} ]
} ]
}

View file

@ -0,0 +1 @@
{"key":"value","rdapConformance":["rdap_level_0"],"notices":[{"title":"RDAP Terms of Service","description":["By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.","Any information provided is 'as is' without any guarantee of accuracy.","Please do not misuse the Domain Database. It is intended solely for query-based access.","Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.","Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of any ICANN-accredited registrar.","You may only use the information contained in the Domain Database for lawful purposes.","Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.","We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.","We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.","We reserve the right to modify this agreement at any time."],"links":[{"value":"http:\/\/myserver.example.com\/help\/tos","rel":"alternate","href":"https:\/\/www.registry.tld\/about\/rdap\/tos.html","type":"text\/html"}]}]}