Make FlowReporter log tld and various other fields

As part of b/36599833, this makes FlowReporter log the tld(s) of every domain
flow it executes, so we can provide ICANN reporting totals on a per-TLD basis.

It also adds several other fields that we're computing anyway and which seem
useful, particularly for debugging any issues we see in production with the data
that we're attempting to record for ICANN reporting.  The full set of fields is:

  - commandType (e.g. "create", "info", "transfer")
  - resourceType* (e.g. "domain", "contact", "host")
  - flowClassName (e.g. "ContactCreateFlow", "DomainRestoreRequestFlow")
  - targetId* (e.g. "ns1.foo.com", "bar.org", "contact-1234")
  - targetIds* - plural of the above, for multi-resource checks
  - tld** (e.g. "com", "co.uk") - extracted from targetId, lowercased
  - tlds** - plural of the above, deduplicated, for multi-resource checks

* = only non-empty for resource flows (not e.g. login, logout, poll)
** = only non-empty for domain flows

Note that TLD extraction is deliberately very lenient to avoid the complexity
overhead of double-validation of the domain names in the common case.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=154070794
This commit is contained in:
nickfelt 2017-04-24 11:08:29 -07:00 committed by Ben McIlwain
parent c596d23523
commit f296b225af
21 changed files with 215 additions and 17 deletions

View file

@ -19,13 +19,17 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.testing.TestLogHandler;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.eppcommon.Trid;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppOutput.ResponseOrGreeting;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@ -68,6 +72,11 @@ public class FlowReporterTest extends ShardableTestCase {
flowReporter.clientId = "TheRegistrar";
flowReporter.inputXmlBytes = "<xml/>".getBytes(UTF_8);
flowReporter.flowClass = TestCommandFlow.class;
flowReporter.eppInput = mock(EppInput.class);
when(flowReporter.eppInput.getCommandType()).thenReturn("info");
when(flowReporter.eppInput.getResourceType()).thenReturn(Optional.of("domain"));
when(flowReporter.eppInput.getSingleTargetId()).thenReturn(Optional.of("target.foo"));
when(flowReporter.eppInput.getTargetIds()).thenReturn(ImmutableList.of("target.foo"));
}
@Test
@ -96,8 +105,15 @@ public class FlowReporterTest extends ShardableTestCase {
flowReporter.recordToLogs();
assertThat(parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: ")))
.containsExactly(
"trid", "server-456",
"serverTrid", "server-456",
"clientId", "TheRegistrar",
"commandType", "info",
"resourceType", "domain",
"flowClassName", "TestCommandFlow",
"targetId", "target.foo",
"targetIds", ImmutableList.of("target.foo"),
"tld", "foo",
"tlds", ImmutableList.of("foo"),
"icannActivityReportField", "");
}
@ -105,22 +121,109 @@ public class FlowReporterTest extends ShardableTestCase {
public void testRecordToLogs_metadata_withReportingSpec() throws Exception {
flowReporter.flowClass = TestReportingSpecCommandFlow.class;
flowReporter.recordToLogs();
assertThat(parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: ")))
.containsExactly(
"trid", "server-456",
"clientId", "TheRegistrar",
"icannActivityReportField", "srs-cont-check");
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("flowClassName", "TestReportingSpecCommandFlow");
assertThat(json).containsEntry("icannActivityReportField", "srs-cont-check");
}
@Test
public void testRecordToLogs_metadata_noClientId() throws Exception {
flowReporter.clientId = "";
flowReporter.recordToLogs();
assertThat(parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: ")))
.containsExactly(
"trid", "server-456",
"clientId", "",
"icannActivityReportField", "");
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("clientId", "");
}
@Test
public void testRecordToLogs_metadata_notResourceFlow_noResourceTypeOrTld() throws Exception {
when(flowReporter.eppInput.getResourceType()).thenReturn(Optional.absent());
flowReporter.recordToLogs();
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("resourceType", "");
assertThat(json).containsEntry("tld", "");
assertThat(json).containsEntry("tlds", ImmutableList.of());
}
@Test
public void testRecordToLogs_metadata_notDomainFlow_noTld() throws Exception {
when(flowReporter.eppInput.getResourceType()).thenReturn(Optional.of("contact"));
flowReporter.recordToLogs();
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("resourceType", "contact");
assertThat(json).containsEntry("tld", "");
assertThat(json).containsEntry("tlds", ImmutableList.of());
}
@Test
public void testRecordToLogs_metadata_multipartDomainName_multipartTld() throws Exception {
when(flowReporter.eppInput.getSingleTargetId()).thenReturn(Optional.of("target.co.uk"));
when(flowReporter.eppInput.getTargetIds()).thenReturn(ImmutableList.of("target.co.uk"));
flowReporter.recordToLogs();
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("targetId", "target.co.uk");
assertThat(json).containsEntry("targetIds", ImmutableList.of("target.co.uk"));
assertThat(json).containsEntry("tld", "co.uk");
assertThat(json).containsEntry("tlds", ImmutableList.of("co.uk"));
}
@Test
public void testRecordToLogs_metadata_multipleTargetIds_uniqueTldSet() throws Exception {
when(flowReporter.eppInput.getSingleTargetId()).thenReturn(Optional.absent());
when(flowReporter.eppInput.getTargetIds())
.thenReturn(ImmutableList.of("target.co.uk", "foo.uk", "bar.uk", "baz.com"));
flowReporter.recordToLogs();
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("targetId", "");
assertThat(json).containsEntry(
"targetIds", ImmutableList.of("target.co.uk", "foo.uk", "bar.uk", "baz.com"));
assertThat(json).containsEntry("tld", "");
assertThat(json).containsEntry("tlds", ImmutableList.of("co.uk", "uk", "com"));
}
@Test
public void testRecordToLogs_metadata_uppercaseDomainName_lowercaseTld() throws Exception {
when(flowReporter.eppInput.getSingleTargetId()).thenReturn(Optional.of("TARGET.FOO"));
when(flowReporter.eppInput.getTargetIds()).thenReturn(ImmutableList.of("TARGET.FOO"));
flowReporter.recordToLogs();
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("targetId", "TARGET.FOO");
assertThat(json).containsEntry("targetIds", ImmutableList.of("TARGET.FOO"));
assertThat(json).containsEntry("tld", "foo");
assertThat(json).containsEntry("tlds", ImmutableList.of("foo"));
}
@Test
public void testRecordToLogs_metadata_invalidDomainName_stillGuessesTld() throws Exception {
when(flowReporter.eppInput.getSingleTargetId()).thenReturn(Optional.of("<foo@bar.com>"));
when(flowReporter.eppInput.getTargetIds()).thenReturn(ImmutableList.of("<foo@bar.com>"));
flowReporter.recordToLogs();
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("targetId", "<foo@bar.com>");
assertThat(json).containsEntry("targetIds", ImmutableList.of("<foo@bar.com>"));
assertThat(json).containsEntry("tld", "com>");
assertThat(json).containsEntry("tlds", ImmutableList.of("com>"));
}
@Test
public void testRecordToLogs_metadata_domainWithoutPeriod_noTld() throws Exception {
when(flowReporter.eppInput.getSingleTargetId()).thenReturn(Optional.of("target,foo"));
when(flowReporter.eppInput.getTargetIds()).thenReturn(ImmutableList.of("target,foo"));
flowReporter.recordToLogs();
Map<String, Object> json =
parseJsonMap(findLogMessageByPrefix(handler, "FLOW-LOG-SIGNATURE-METADATA: "));
assertThat(json).containsEntry("targetId", "target,foo");
assertThat(json).containsEntry("targetIds", ImmutableList.of("target,foo"));
assertThat(json).containsEntry("tld", "");
assertThat(json).containsEntry("tlds", ImmutableList.of());
}
@SuppressWarnings("unchecked")