Initial, easy changes to support later addition of RDAP metrics

I split this out to avoid having a giant CL that changes everything. The actual
metrics will follow later.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=174356874
This commit is contained in:
mountford 2017-11-02 11:39:25 -07:00 committed by jianglai
parent c126c05810
commit 5b8ee87ecc
13 changed files with 127 additions and 46 deletions

View file

@ -33,6 +33,7 @@ import com.googlecode.objectify.cmd.Query;
import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResource;
import google.registry.model.registrar.Registrar;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action;
import google.registry.request.FullServletPath;
@ -92,6 +93,9 @@ public abstract class RdapActionBase implements Runnable {
/** Returns a string like "domain name" or "nameserver", used for error strings. */
abstract String getHumanReadableObjectTypeName();
/** Returns the endpoint type used for recording metrics. */
abstract EndpointType getEndpointType();
/** Returns the servlet action path; used to extract the search string from the incoming path. */
abstract String getActionPath();
@ -381,23 +385,24 @@ public abstract class RdapActionBase implements Runnable {
* the query could not check deletion status (due to Datastore limitations such as the
* limit of one field queried for inequality, for instance), it may need to be set to true
* even when not including deleted records
* @return an {@link RdapResourcesAndIncompletenessWarningType} object containing the list of
* @return an {@link RdapResultSet} object containing the list of
* resources and an incompleteness warning flag, which is set to MIGHT_BE_INCOMPLETE iff
* any resources were excluded due to lack of visibility, and the resulting list of
* resources is less than the maximum allowable, which indicates that we may not have
* fetched enough resources
*/
<T extends EppResource> RdapResourcesAndIncompletenessWarningType<T> getMatchingResources(
<T extends EppResource> RdapResultSet<T> getMatchingResources(
Query<T> query, boolean checkForVisibility, DateTime now) {
Optional<String> desiredRegistrar = getDesiredRegistrar();
if (desiredRegistrar.isPresent()) {
query = query.filter("currentSponsorClientId", desiredRegistrar.get());
}
if (!checkForVisibility) {
return RdapResourcesAndIncompletenessWarningType.create(query.list());
return RdapResultSet.create(query.list());
}
// If we are including deleted resources, we need to check that we're authorized for each one.
List<T> resources = new ArrayList<>();
int numResourcesQueried = 0;
boolean someExcluded = false;
for (T resource : query) {
if (shouldBeVisible(resource, now)) {
@ -405,14 +410,16 @@ public abstract class RdapActionBase implements Runnable {
} else {
someExcluded = true;
}
numResourcesQueried++;
if (resources.size() > rdapResultSetMaxSize) {
break;
}
}
return RdapResourcesAndIncompletenessWarningType.create(
return RdapResultSet.create(
resources,
(someExcluded && (resources.size() < rdapResultSetMaxSize + 1))
? IncompletenessWarningType.MIGHT_BE_INCOMPLETE
: IncompletenessWarningType.NONE);
: IncompletenessWarningType.NONE,
numResourcesQueried);
}
}

View file

@ -18,6 +18,7 @@ import static google.registry.request.Action.Method.GET;
import static google.registry.request.Action.Method.HEAD;
import com.google.common.collect.ImmutableMap;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.request.Action;
import google.registry.request.HttpException.NotImplementedException;
import google.registry.request.auth.Auth;
@ -46,6 +47,11 @@ public class RdapAutnumAction extends RdapActionBase {
return "autnum";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.AUTNUM;
}
@Override
public String getActionPath() {
return PATH;

View file

@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableMap;
import google.registry.flows.EppException;
import google.registry.model.domain.DomainResource;
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.NotFoundException;
@ -56,6 +57,11 @@ public class RdapDomainAction extends RdapActionBase {
return PATH;
}
@Override
public EndpointType getEndpointType() {
return EndpointType.DOMAIN;
}
@Override
public ImmutableMap<String, Object> getJsonObjectForResource(
String pathSearchString, boolean isHeadRequest) {

View file

@ -34,6 +34,7 @@ import google.registry.model.domain.DomainResource;
import google.registry.model.host.HostResource;
import google.registry.rdap.RdapJsonFormatter.BoilerplateType;
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException;
@ -88,6 +89,11 @@ public class RdapDomainSearchAction extends RdapActionBase {
return "domain search";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.DOMAINS;
}
@Override
public String getActionPath() {
return PATH;
@ -468,15 +474,10 @@ public class RdapDomainSearchAction extends RdapActionBase {
return makeSearchResults(domains, IncompletenessWarningType.NONE, now);
}
/** Output JSON from data in an {@link RdapResourcesAndIncompletenessWarningType} object. */
/** Output JSON from data in an {@link RdapResultSet} object. */
private RdapSearchResults makeSearchResults(
RdapResourcesAndIncompletenessWarningType<DomainResource>
resourcesAndIncompletenessWarningType,
DateTime now) {
return makeSearchResults(
resourcesAndIncompletenessWarningType.resources(),
resourcesAndIncompletenessWarningType.incompletenessWarningType(),
now);
RdapResultSet<DomainResource> resultSet, DateTime now) {
return makeSearchResults(resultSet.resources(), resultSet.incompletenessWarningType(), now);
}
/**

View file

@ -27,6 +27,7 @@ import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.registrar.Registrar;
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.NotFoundException;
@ -66,6 +67,11 @@ public class RdapEntityAction extends RdapActionBase {
return "entity";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.ENTITY;
}
@Override
public String getActionPath() {
return PATH;

View file

@ -31,6 +31,7 @@ import google.registry.model.domain.DesignatedContact;
import google.registry.model.registrar.Registrar;
import google.registry.rdap.RdapJsonFormatter.BoilerplateType;
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException;
@ -76,6 +77,11 @@ public class RdapEntitySearchAction extends RdapActionBase {
return "entity search";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.ENTITIES;
}
@Override
public String getActionPath() {
return PATH;
@ -169,12 +175,10 @@ public class RdapEntitySearchAction extends RdapActionBase {
// Get the contact matches and return the results, fetching an additional contact to detect
// truncation. Don't bother searching for contacts by name if the request would not be able to
// see any names anyway.
RdapResourcesAndIncompletenessWarningType<ContactResource>
resourcesAndIncompletenessWarningType;
RdapResultSet<ContactResource> resultSet;
RdapAuthorization authorization = getAuthorization();
if (authorization.role() == RdapAuthorization.Role.PUBLIC) {
resourcesAndIncompletenessWarningType =
RdapResourcesAndIncompletenessWarningType.create(ImmutableList.of());
resultSet = RdapResultSet.create(ImmutableList.of());
} else {
Query<ContactResource> query =
queryItems(
@ -186,9 +190,9 @@ public class RdapEntitySearchAction extends RdapActionBase {
if (authorization.role() != RdapAuthorization.Role.ADMINISTRATOR) {
query = query.filter("currentSponsorClientId in", authorization.clientIds());
}
resourcesAndIncompletenessWarningType = getMatchingResources(query, false, now);
resultSet = getMatchingResources(query, false, now);
}
return makeSearchResults(resourcesAndIncompletenessWarningType, registrars, now);
return makeSearchResults(resultSet, registrars, now);
}
/**
@ -264,15 +268,9 @@ public class RdapEntitySearchAction extends RdapActionBase {
* arguments.
*/
private RdapSearchResults makeSearchResults(
RdapResourcesAndIncompletenessWarningType<ContactResource>
resourcesAndIncompletenessWarningType,
List<Registrar> registrars,
DateTime now) {
RdapResultSet<ContactResource> resultSet, List<Registrar> registrars, DateTime now) {
return makeSearchResults(
resourcesAndIncompletenessWarningType.resources(),
resourcesAndIncompletenessWarningType.incompletenessWarningType(),
registrars,
now);
resultSet.resources(), resultSet.incompletenessWarningType(), registrars, now);
}
/**

View file

@ -20,6 +20,7 @@ import static google.registry.request.Action.Method.HEAD;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.rdap.RdapJsonFormatter.BoilerplateType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.request.Action;
import google.registry.request.auth.Auth;
import google.registry.util.Clock;
@ -44,6 +45,11 @@ public class RdapHelpAction extends RdapActionBase {
return "help";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.HELP;
}
@Override
public String getActionPath() {
return PATH;

View file

@ -18,6 +18,7 @@ import static google.registry.request.Action.Method.GET;
import static google.registry.request.Action.Method.HEAD;
import com.google.common.collect.ImmutableMap;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.request.Action;
import google.registry.request.HttpException.NotImplementedException;
import google.registry.request.auth.Auth;
@ -46,6 +47,11 @@ public class RdapIpAction extends RdapActionBase {
return "ip";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.IP;
}
@Override
public String getActionPath() {
return PATH;

View file

@ -0,0 +1,31 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.rdap;
/** RDAP Instrumentation. */
public class RdapMetrics {
enum EndpointType {
AUTNUM,
DOMAIN,
DOMAINS,
ENTITY,
ENTITIES,
HELP,
IP,
NAMESERVER,
NAMESERVERS
}
}

View file

@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableMap;
import google.registry.flows.EppException;
import google.registry.model.host.HostResource;
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.NotFoundException;
@ -51,6 +52,11 @@ public class RdapNameserverAction extends RdapActionBase {
return "nameserver";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.NAMESERVER;
}
@Override
public String getActionPath() {
return PATH;

View file

@ -29,6 +29,7 @@ import google.registry.model.domain.DomainResource;
import google.registry.model.host.HostResource;
import google.registry.rdap.RdapJsonFormatter.BoilerplateType;
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException;
@ -75,6 +76,11 @@ public class RdapNameserverSearchAction extends RdapActionBase {
return "nameserver search";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.NAMESERVERS;
}
@Override
public String getActionPath() {
return PATH;
@ -244,17 +250,9 @@ public class RdapNameserverSearchAction extends RdapActionBase {
return makeSearchResults(getMatchingResources(query, shouldIncludeDeleted(), now), now);
}
/**
* Output JSON for a lists of hosts contained in an {@link
* RdapResourcesAndIncompletenessWarningType}.
*/
private RdapSearchResults makeSearchResults(
RdapResourcesAndIncompletenessWarningType<HostResource> resourcesAndIncompletenessWarningType,
DateTime now) {
return makeSearchResults(
resourcesAndIncompletenessWarningType.resources(),
resourcesAndIncompletenessWarningType.incompletenessWarningType(),
now);
/** Output JSON for a lists of hosts contained in an {@link RdapResultSet}. */
private RdapSearchResults makeSearchResults(RdapResultSet<HostResource> resultSet, DateTime now) {
return makeSearchResults(resultSet.resources(), resultSet.incompletenessWarningType(), now);
}
/** Output JSON for a list of hosts. */

View file

@ -20,17 +20,18 @@ import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import java.util.List;
@AutoValue
abstract class RdapResourcesAndIncompletenessWarningType<T extends EppResource> {
abstract class RdapResultSet<T extends EppResource> {
static <S extends EppResource> RdapResourcesAndIncompletenessWarningType<S> create(
List<S> resources) {
return create(resources, IncompletenessWarningType.NONE);
static <S extends EppResource> RdapResultSet<S> create(List<S> resources) {
return create(resources, IncompletenessWarningType.NONE, resources.size());
}
static <S extends EppResource> RdapResourcesAndIncompletenessWarningType<S> create(
List<S> resources, IncompletenessWarningType incompletenessWarningType) {
return new AutoValue_RdapResourcesAndIncompletenessWarningType<>(
resources, incompletenessWarningType);
static <S extends EppResource> RdapResultSet<S> create(
List<S> resources,
IncompletenessWarningType incompletenessWarningType,
int numResourcesRetrieved) {
return new AutoValue_RdapResultSet<>(
resources, incompletenessWarningType, numResourcesRetrieved);
}
/** List of EPP resources. */
@ -38,5 +39,8 @@ abstract class RdapResourcesAndIncompletenessWarningType<T extends EppResource>
/** Type of warning to display regarding possible incomplete data. */
abstract IncompletenessWarningType incompletenessWarningType();
/** Number of resources retrieved from the database in the process of assembling the data set. */
abstract int numResourcesRetrieved();
}

View file

@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.model.ofy.Ofy;
import google.registry.rdap.RdapJsonFormatter.BoilerplateType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
@ -64,6 +65,11 @@ public class RdapActionBaseTest {
return "human-readable string";
}
@Override
public EndpointType getEndpointType() {
return EndpointType.HELP;
}
@Override
public String getActionPath() {
return PATH;