mirror of
https://github.com/google/nomulus.git
synced 2025-07-31 15:06:29 +02:00
Add metrics for registrar console requests
Cardinality of this metric: clientId: there are currently 650 (on sandbox, because of OTE), and 200 on production. explicitClientId: 2 roles: 2 now, might be 3 soon if we add vendors status: 2 So we're talking about a cardinality of 2,000-8,000. Less when you consider that registrars only seldom actually need to access the console (certainly not daily or even weekly). Compare with, e.g., the /epp/processing_time from the above EppMetrics.java which has: Epp commands: 26 (manual counting) client IDs: 200 on prod status: the actual status CODE of the command. Can have many values, but looking at the past few weeks' metrics I counted 20 Note that not every command results in every status. Looking a few weeks back we can see around 80-100 (commands+status) combination. buckets: 16 so that's over 250,000-1,000,000 cardinality, on a very high-volume metric. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=218699280
This commit is contained in:
parent
f6d9b46622
commit
97aa98eb35
11 changed files with 223 additions and 25 deletions
|
@ -26,11 +26,13 @@ java_library(
|
|||
"//java/google/registry/util",
|
||||
"//third_party/objectify:objectify-v4_1",
|
||||
"@com_google_appengine_api_1_0_sdk",
|
||||
"@com_google_auto_value",
|
||||
"@com_google_code_findbugs_jsr305",
|
||||
"@com_google_dagger",
|
||||
"@com_google_flogger",
|
||||
"@com_google_flogger_system_backend",
|
||||
"@com_google_guava",
|
||||
"@com_google_monitoring_client_metrics",
|
||||
"@com_google_re2j",
|
||||
"@io_bazel_rules_closure//closure/templates",
|
||||
"@javax_inject",
|
||||
|
|
|
@ -75,6 +75,7 @@ public final class ConsoleUiAction implements Runnable {
|
|||
|
||||
@Inject HttpServletRequest req;
|
||||
@Inject Response response;
|
||||
@Inject RegistrarConsoleMetrics registrarConsoleMetrics;
|
||||
@Inject AuthenticatedRegistrarAccessor registrarAccessor;
|
||||
@Inject UserService userService;
|
||||
@Inject XsrfTokenManager xsrfTokenManager;
|
||||
|
@ -134,15 +135,19 @@ public final class ConsoleUiAction implements Runnable {
|
|||
data.put("username", user.getNickname());
|
||||
data.put("logoutUrl", userService.createLogoutURL(PATH));
|
||||
data.put("xsrfToken", xsrfTokenManager.generateToken(user.getEmail()));
|
||||
ImmutableSetMultimap<String, Role> roleMap = registrarAccessor.getAllClientIdWithRoles();
|
||||
ImmutableSetMultimap<Role, String> roleMapInverse = roleMap.inverse();
|
||||
// TODO(guyben):just return all the clientIDs in a single list, and add an "isAdmin" or "roles"
|
||||
// item
|
||||
data.put("ownerClientIds", roleMapInverse.get(OWNER));
|
||||
data.put(
|
||||
"adminClientIds", Sets.difference(roleMapInverse.get(ADMIN), roleMapInverse.get(OWNER)));
|
||||
// We set the initual value to the value that will show if guessClientId throws.
|
||||
String clientId = "<null>";
|
||||
try {
|
||||
String clientId = paramClientId.orElse(registrarAccessor.guessClientId());
|
||||
clientId = paramClientId.orElse(registrarAccessor.guessClientId());
|
||||
data.put("clientId", clientId);
|
||||
|
||||
ImmutableSetMultimap<Role, String> roleMap =
|
||||
registrarAccessor.getAllClientIdWithRoles().inverse();
|
||||
data.put("ownerClientIds", roleMap.get(OWNER));
|
||||
data.put("adminClientIds", Sets.difference(roleMap.get(ADMIN), roleMap.get(OWNER)));
|
||||
|
||||
// We want to load the registrar even if we won't use it later (even if we remove the
|
||||
// requireFeeExtension) - to make sure the user indeed has access to the guessed registrar.
|
||||
//
|
||||
|
@ -162,7 +167,13 @@ public final class ConsoleUiAction implements Runnable {
|
|||
.setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get())
|
||||
.setData(data)
|
||||
.render());
|
||||
registrarConsoleMetrics.registerConsoleRequest(
|
||||
clientId, paramClientId.isPresent(), roleMap.get(clientId), "FORBIDDEN");
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
registrarConsoleMetrics.registerConsoleRequest(
|
||||
clientId, paramClientId.isPresent(), roleMap.get(clientId), "UNEXPECTED ERROR");
|
||||
throw e;
|
||||
}
|
||||
|
||||
String payload = TOFU_SUPPLIER.get()
|
||||
|
@ -171,5 +182,7 @@ public final class ConsoleUiAction implements Runnable {
|
|||
.setData(data)
|
||||
.render();
|
||||
response.setPayload(payload);
|
||||
registrarConsoleMetrics.registerConsoleRequest(
|
||||
clientId, paramClientId.isPresent(), roleMap.get(clientId), "SUCCESS");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright 2018 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.ui.server.registrar;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.monitoring.metrics.IncrementableMetric;
|
||||
import com.google.monitoring.metrics.LabelDescriptor;
|
||||
import com.google.monitoring.metrics.MetricRegistryImpl;
|
||||
import google.registry.ui.server.registrar.AuthenticatedRegistrarAccessor.Role;
|
||||
import javax.inject.Inject;
|
||||
|
||||
final class RegistrarConsoleMetrics {
|
||||
|
||||
private static final ImmutableSet<LabelDescriptor> CONSOLE_LABEL_DESCRIPTORS =
|
||||
ImmutableSet.of(
|
||||
LabelDescriptor.create("clientId", "target registrar client ID"),
|
||||
LabelDescriptor.create("explicitClientId", "whether the client ID is set explicitly"),
|
||||
LabelDescriptor.create("role", "Role[s] of the user making the request"),
|
||||
LabelDescriptor.create("status", "whether the request is successful"));
|
||||
|
||||
static final IncrementableMetric consoleRequestMetric =
|
||||
MetricRegistryImpl.getDefault()
|
||||
.newIncrementableMetric(
|
||||
"/console/registrar/console_requests",
|
||||
"Count of /registrar requests",
|
||||
"count",
|
||||
CONSOLE_LABEL_DESCRIPTORS);
|
||||
|
||||
private static final ImmutableSet<LabelDescriptor> SETTINGS_LABEL_DESCRIPTORS =
|
||||
ImmutableSet.of(
|
||||
LabelDescriptor.create("clientId", "target registrar client ID"),
|
||||
LabelDescriptor.create("action", "action performed"),
|
||||
LabelDescriptor.create("role", "Role[s] of the user making the request"),
|
||||
LabelDescriptor.create("status", "whether the request is successful"));
|
||||
|
||||
static final IncrementableMetric settingsRequestMetric =
|
||||
MetricRegistryImpl.getDefault()
|
||||
.newIncrementableMetric(
|
||||
"/console/registrar/setting_requests",
|
||||
"Count of /registrar-settings requests",
|
||||
"count",
|
||||
SETTINGS_LABEL_DESCRIPTORS);
|
||||
|
||||
@Inject
|
||||
public RegistrarConsoleMetrics() {}
|
||||
|
||||
void registerConsoleRequest(
|
||||
String clientId, boolean explicitClientId, ImmutableSet<Role> roles, String status) {
|
||||
consoleRequestMetric.increment(
|
||||
clientId, String.valueOf(explicitClientId), String.valueOf(roles), status);
|
||||
}
|
||||
|
||||
void registerSettingsRequest(
|
||||
String clientId, String action, ImmutableSet<Role> roles, String status) {
|
||||
settingsRequestMetric.increment(clientId, action, String.valueOf(roles), status);
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
|
|||
import static google.registry.security.JsonResponseHelper.Status.ERROR;
|
||||
import static google.registry.security.JsonResponseHelper.Status.SUCCESS;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
|
@ -80,6 +81,7 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
|
|||
|
||||
@Inject JsonActionRunner jsonActionRunner;
|
||||
@Inject AppEngineServiceUtils appEngineServiceUtils;
|
||||
@Inject RegistrarConsoleMetrics registrarConsoleMetrics;
|
||||
@Inject SendEmailUtils sendEmailUtils;
|
||||
@Inject AuthenticatedRegistrarAccessor registrarAccessor;
|
||||
@Inject AuthResult authResult;
|
||||
|
@ -114,34 +116,55 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
|
|||
@SuppressWarnings("unchecked")
|
||||
Map<String, ?> args = (Map<String, Object>)
|
||||
Optional.<Object>ofNullable(input.get(ARGS_PARAM)).orElse(ImmutableMap.of());
|
||||
|
||||
logger.atInfo().log("Received request '%s' on registrar '%s' with args %s", op, clientId, args);
|
||||
String status = "SUCCESS";
|
||||
try {
|
||||
switch (op) {
|
||||
case "update":
|
||||
return update(args, clientId);
|
||||
return update(args, clientId).toJsonResponse();
|
||||
case "read":
|
||||
return read(clientId);
|
||||
return read(clientId).toJsonResponse();
|
||||
default:
|
||||
return JsonResponseHelper.create(ERROR, "Unknown or unsupported operation: " + op);
|
||||
throw new IllegalArgumentException("Unknown or unsupported operation: " + op);
|
||||
}
|
||||
} catch (FormFieldException e) {
|
||||
logger.atWarning().withCause(e).log(
|
||||
"Failed to perform operation '%s' on registrar '%s' for args %s", op, clientId, args);
|
||||
return JsonResponseHelper.createFormFieldError(e.getMessage(), e.getFieldName());
|
||||
} catch (Throwable e) {
|
||||
logger.atWarning().withCause(e).log(
|
||||
"Failed to perform operation '%s' on registrar '%s' for args %s", op, clientId, args);
|
||||
status = "ERROR: " + e.getClass().getSimpleName();
|
||||
if (e instanceof FormFieldException) {
|
||||
FormFieldException formFieldException = (FormFieldException) e;
|
||||
return JsonResponseHelper.createFormFieldError(
|
||||
formFieldException.getMessage(), formFieldException.getFieldName());
|
||||
}
|
||||
return JsonResponseHelper.create(
|
||||
ERROR, Optional.ofNullable(e.getMessage()).orElse("Unspecified error"));
|
||||
} finally {
|
||||
registrarConsoleMetrics.registerSettingsRequest(
|
||||
clientId, op, registrarAccessor.getAllClientIdWithRoles().get(clientId), status);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> read(String clientId) {
|
||||
return JsonResponseHelper.create(
|
||||
SUCCESS, "Success", registrarAccessor.getRegistrar(clientId).toJsonMap());
|
||||
@AutoValue
|
||||
abstract static class RegistrarResult {
|
||||
abstract String message();
|
||||
|
||||
abstract Registrar registrar();
|
||||
|
||||
Map<String, Object> toJsonResponse() {
|
||||
return JsonResponseHelper.create(SUCCESS, message(), registrar().toJsonMap());
|
||||
}
|
||||
|
||||
static RegistrarResult create(String message, Registrar registrar) {
|
||||
return new AutoValue_RegistrarSettingsAction_RegistrarResult(message, registrar);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> update(final Map<String, ?> args, String clientId) {
|
||||
private RegistrarResult read(String clientId) {
|
||||
return RegistrarResult.create("Success", registrarAccessor.getRegistrar(clientId));
|
||||
}
|
||||
|
||||
private RegistrarResult update(final Map<String, ?> args, String clientId) {
|
||||
return ofy()
|
||||
.transact(
|
||||
() -> {
|
||||
|
@ -196,8 +219,7 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
|
|||
// Email and return update.
|
||||
sendExternalUpdatesIfNecessary(
|
||||
registrar, contacts, updatedRegistrar, updatedContacts);
|
||||
return JsonResponseHelper.create(
|
||||
SUCCESS, "Saved " + clientId, updatedRegistrar.toJsonMap());
|
||||
return RegistrarResult.create("Saved " + clientId, updatedRegistrar);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ java_library(
|
|||
"@com_google_flogger_system_backend",
|
||||
"@com_google_guava",
|
||||
"@com_google_guava_testlib",
|
||||
"@com_google_monitoring_client_contrib",
|
||||
"@com_google_truth",
|
||||
"@com_google_truth_extensions_truth_java8_extension",
|
||||
"@com_googlecode_json_simple",
|
||||
|
|
|
@ -16,6 +16,7 @@ package google.registry.ui.server.registrar;
|
|||
|
||||
import static com.google.common.net.HttpHeaders.LOCATION;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.monitoring.metrics.contrib.LongMetricSubject.assertThat;
|
||||
import static google.registry.testing.DatastoreHelper.loadRegistrar;
|
||||
import static google.registry.ui.server.registrar.AuthenticatedRegistrarAccessor.Role.ADMIN;
|
||||
import static google.registry.ui.server.registrar.AuthenticatedRegistrarAccessor.Role.OWNER;
|
||||
|
@ -38,6 +39,7 @@ import google.registry.testing.FakeResponse;
|
|||
import google.registry.testing.UserInfo;
|
||||
import java.util.Optional;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
@ -73,6 +75,7 @@ public class ConsoleUiActionTest {
|
|||
action.technicalDocsUrl = "http://example.com/technical-docs";
|
||||
action.req = request;
|
||||
action.response = response;
|
||||
action.registrarConsoleMetrics = new RegistrarConsoleMetrics();
|
||||
action.registrarAccessor = registrarAccessor;
|
||||
action.userService = UserServiceFactory.getUserService();
|
||||
action.xsrfTokenManager = new XsrfTokenManager(new FakeClock(), action.userService);
|
||||
|
@ -91,24 +94,39 @@ public class ConsoleUiActionTest {
|
|||
when(registrarAccessor.guessClientId()).thenCallRealMethod();
|
||||
// Used for error message in guessClientId
|
||||
registrarAccessor.authResult = authResult;
|
||||
RegistrarConsoleMetrics.consoleRequestMetric.reset();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
assertThat(RegistrarConsoleMetrics.consoleRequestMetric).hasNoOtherValues();
|
||||
}
|
||||
|
||||
public void assertMetric(String clientId, String explicitClientId, String roles, String status) {
|
||||
assertThat(RegistrarConsoleMetrics.consoleRequestMetric)
|
||||
.hasValueForLabels(1, clientId, explicitClientId, roles, status);
|
||||
RegistrarConsoleMetrics.consoleRequestMetric.reset(clientId, explicitClientId, roles, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebPage_disallowsIframe() {
|
||||
action.run();
|
||||
assertThat(response.getHeaders()).containsEntry("X-Frame-Options", "SAMEORIGIN");
|
||||
assertMetric("TheRegistrar", "false", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebPage_setsHtmlUtf8ContentType() {
|
||||
action.run();
|
||||
assertThat(response.getContentType()).isEqualTo(MediaType.HTML_UTF_8);
|
||||
assertMetric("TheRegistrar", "false", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebPage_containsUserNickname() {
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("marla.singer");
|
||||
assertMetric("TheRegistrar", "false", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -116,6 +134,7 @@ public class ConsoleUiActionTest {
|
|||
action.run();
|
||||
assertThat(response.getPayload()).contains("Registrar Console");
|
||||
assertThat(response.getPayload()).contains("reg-content-and-footer");
|
||||
assertMetric("TheRegistrar", "false", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -131,6 +150,7 @@ public class ConsoleUiActionTest {
|
|||
action.run();
|
||||
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
|
||||
assertThat(response.getPayload()).contains("not associated with Nomulus.");
|
||||
assertMetric("<null>", "false", "[]", "FORBIDDEN");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -153,22 +173,25 @@ public class ConsoleUiActionTest {
|
|||
|
||||
@Test
|
||||
public void testSettingClientId_notAllowed_showsNeedPermissionPage() {
|
||||
action.paramClientId = Optional.of("OtherClientId");
|
||||
when(registrarAccessor.getRegistrar("OtherClientId"))
|
||||
// Behaves the same way if fakeRegistrar exists, but we don't have access to it
|
||||
action.paramClientId = Optional.of("fakeRegistrar");
|
||||
when(registrarAccessor.getRegistrar("fakeRegistrar"))
|
||||
.thenThrow(new ForbiddenException("forbidden"));
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
|
||||
assertThat(response.getPayload()).contains("not associated with the registrar OtherClientId.");
|
||||
assertThat(response.getPayload()).contains("not associated with the registrar fakeRegistrar.");
|
||||
assertMetric("fakeRegistrar", "true", "[]", "FORBIDDEN");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingClientId_allowed_showsRegistrarConsole() {
|
||||
action.paramClientId = Optional.of("OtherClientId");
|
||||
when(registrarAccessor.getRegistrar("OtherClientId"))
|
||||
action.paramClientId = Optional.of("OtherRegistrar");
|
||||
when(registrarAccessor.getRegistrar("OtherRegistrar"))
|
||||
.thenReturn(loadRegistrar("TheRegistrar"));
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Registrar Console");
|
||||
assertThat(response.getPayload()).contains("reg-content-and-footer");
|
||||
assertMetric("OtherRegistrar", "true", "[OWNER, ADMIN]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -177,5 +200,6 @@ public class ConsoleUiActionTest {
|
|||
assertThat(response.getPayload()).contains("<option value=\"TheRegistrar\" selected>");
|
||||
assertThat(response.getPayload()).contains("<option value=\"OtherRegistrar\">");
|
||||
assertThat(response.getPayload()).contains("<option value=\"AdminRegistrar\">");
|
||||
assertMetric("TheRegistrar", "false", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
List<Map<String, ?>> results = (List<Map<String, ?>>) response.get("results");
|
||||
assertThat(results.get(0).get("contacts"))
|
||||
.isEqualTo(loadRegistrar(CLIENT_ID).toJsonMap().get("contacts"));
|
||||
assertMetric(CLIENT_ID, "read", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -60,6 +61,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
"id", CLIENT_ID,
|
||||
"args", loadRegistrar(CLIENT_ID).toJsonMap()));
|
||||
assertThat(response).containsEntry("status", "SUCCESS");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -88,6 +90,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
.setTypes(ImmutableList.of(RegistrarContact.Type.ADMIN))
|
||||
.build();
|
||||
assertThat(loadRegistrar(CLIENT_ID).getContacts()).containsExactly(newContact);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -105,6 +108,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(response).containsEntry("status", "ERROR");
|
||||
assertThat(response).containsEntry("message", "Must have at least one "
|
||||
+ RegistrarContact.Type.ADMIN.getDisplayName() + " contact");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: ContactRequirementException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -131,6 +135,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(response).containsEntry("status", "ERROR");
|
||||
assertThat(response).containsEntry("message", "Please provide a phone number for at least one "
|
||||
+ RegistrarContact.Type.TECH.getDisplayName() + " contact");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: ContactRequirementException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -157,6 +162,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(response)
|
||||
.containsEntry(
|
||||
"message", "An abuse contact visible in domain WHOIS query must be designated");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: ContactRequirementException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -183,5 +189,6 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(response)
|
||||
.containsEntry(
|
||||
"message", "The abuse contact visible in domain WHOIS query must have a phone number");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: ContactRequirementException");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
.url(SyncRegistrarsSheetAction.PATH)
|
||||
.method("GET")
|
||||
.header("Host", "backend.hostname"));
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -74,6 +75,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"message",
|
||||
"One email address (etphonehome@example.com) cannot be used for multiple contacts");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: ContactRequirementException");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,6 +91,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"results", ImmutableList.of(),
|
||||
"message", "forbidden test error");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
assertMetric(CLIENT_ID, "read", "[]", "ERROR: ForbiddenException");
|
||||
}
|
||||
|
||||
/** This is the default read test for the registrar settings actions. */
|
||||
|
@ -100,6 +103,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"status", "SUCCESS",
|
||||
"message", "Success",
|
||||
"results", asList(loadRegistrar(CLIENT_ID).toJsonMap()));
|
||||
assertMetric(CLIENT_ID, "read", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -114,6 +118,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"results", ImmutableList.of(),
|
||||
"message", "This field is required.");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -128,6 +133,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"results", ImmutableList.of(),
|
||||
"message", "This field is required.");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -144,6 +150,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"status", "SUCCESS",
|
||||
"message", "Saved TheRegistrar",
|
||||
"results", asList(loadRegistrar(CLIENT_ID).toJsonMap()));
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -158,6 +165,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"results", ImmutableList.of(),
|
||||
"message", "forbidden test error");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
assertMetric(CLIENT_ID, "update", "[]", "ERROR: ForbiddenException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -174,6 +182,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"results", ImmutableList.of(),
|
||||
"message", "Please enter a valid email address.");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -188,6 +197,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"results", ImmutableList.of(),
|
||||
"message", "Not a valid ISO date-time string.");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -204,6 +214,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"results", ImmutableList.of(),
|
||||
"message", "Please only use ASCII-US characters.");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
|
||||
private <T> void doTestUpdate(
|
||||
|
@ -230,26 +241,31 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
public void testUpdate_premiumPriceAck() {
|
||||
doTestUpdate(
|
||||
Registrar::getPremiumPriceAckRequired, true, Registrar.Builder::setPremiumPriceAckRequired);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate_whoisServer() {
|
||||
doTestUpdate(Registrar::getWhoisServer, "new-whois.example", Registrar.Builder::setWhoisServer);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate_phoneNumber() {
|
||||
doTestUpdate(Registrar::getPhoneNumber, "+1.2345678900", Registrar.Builder::setPhoneNumber);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate_faxNumber() {
|
||||
doTestUpdate(Registrar::getFaxNumber, "+1.2345678900", Registrar.Builder::setFaxNumber);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate_url() {
|
||||
doTestUpdate(Registrar::getUrl, "new-url.example", Registrar.Builder::setUrl);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -258,6 +274,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
Registrar::getIpAddressWhitelist,
|
||||
ImmutableList.of(CidrAddressBlock.create("1.1.1.0/24")),
|
||||
Registrar.Builder::setIpAddressWhitelist);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -266,6 +283,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
Registrar::getClientCertificate,
|
||||
CertificateSamples.SAMPLE_CERT,
|
||||
(builder, s) -> builder.setClientCertificate(s, clock.nowUtc()));
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -274,6 +292,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
Registrar::getFailoverClientCertificate,
|
||||
CertificateSamples.SAMPLE_CERT,
|
||||
(builder, s) -> builder.setFailoverClientCertificate(s, clock.nowUtc()));
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -283,6 +302,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
Registrar::getAllowedTlds,
|
||||
ImmutableSet.of("newtld"),
|
||||
(builder, s) -> builder.setAllowedTlds(s));
|
||||
assertMetric(CLIENT_ID, "update", "[ADMIN]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -302,6 +322,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"status", "ERROR",
|
||||
"results", ImmutableList.of(),
|
||||
"message", "Only admin can update allowed TLDs.");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: ForbiddenException");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
}
|
||||
|
||||
|
@ -323,6 +344,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"status", "ERROR",
|
||||
"results", ImmutableList.of(),
|
||||
"message", "TLDs do not exist: invalidtld");
|
||||
assertMetric(CLIENT_ID, "update", "[ADMIN]", "ERROR: IllegalArgumentException");
|
||||
assertNoTasksEnqueued("sheet");
|
||||
}
|
||||
|
||||
|
@ -343,6 +365,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
"status", "SUCCESS",
|
||||
"message", "Saved TheRegistrar",
|
||||
"results", asList(loadRegistrar(CLIENT_ID).toJsonMap()));
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -351,6 +374,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
Registrar::getLocalizedAddress,
|
||||
loadRegistrar(CLIENT_ID).getLocalizedAddress().asBuilder().setCity("newCity").build(),
|
||||
Registrar.Builder::setLocalizedAddress);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -359,6 +383,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
Registrar::getLocalizedAddress,
|
||||
loadRegistrar(CLIENT_ID).getLocalizedAddress().asBuilder().setCountryCode("GB").build(),
|
||||
Registrar.Builder::setLocalizedAddress);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -367,6 +392,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
Registrar::getLocalizedAddress,
|
||||
loadRegistrar(CLIENT_ID).getLocalizedAddress().asBuilder().setState("NJ").build(),
|
||||
Registrar.Builder::setLocalizedAddress);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -379,6 +405,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
.setStreet(ImmutableList.of("new street"))
|
||||
.build(),
|
||||
Registrar.Builder::setLocalizedAddress);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -387,6 +414,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
|
|||
Registrar::getLocalizedAddress,
|
||||
loadRegistrar(CLIENT_ID).getLocalizedAddress().asBuilder().setZip("new zip").build(),
|
||||
Registrar.Builder::setLocalizedAddress);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
private static String getLastUpdateTime() {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
package google.registry.ui.server.registrar;
|
||||
|
||||
import static com.google.monitoring.metrics.contrib.LongMetricSubject.assertThat;
|
||||
import static google.registry.config.RegistryConfig.getGSuiteOutgoingEmailAddress;
|
||||
import static google.registry.config.RegistryConfig.getGSuiteOutgoingEmailDisplayName;
|
||||
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
|
||||
|
@ -53,6 +54,7 @@ import javax.mail.internet.MimeMessage;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -92,7 +94,7 @@ public class RegistrarSettingsActionTestCase {
|
|||
// of updating allowed tld for registrar
|
||||
createTlds("newtld");
|
||||
disallowRegistrarAccess(CLIENT_ID, "newtld");
|
||||
action.registrarAccessor = mock(AuthenticatedRegistrarAccessor.class);
|
||||
action.registrarAccessor = null;
|
||||
action.appEngineServiceUtils = appEngineServiceUtils;
|
||||
when(appEngineServiceUtils.getCurrentVersionHostname("backend")).thenReturn("backend.hostname");
|
||||
action.jsonActionRunner = new JsonActionRunner(
|
||||
|
@ -103,6 +105,7 @@ public class RegistrarSettingsActionTestCase {
|
|||
new SendEmailUtils(
|
||||
getGSuiteOutgoingEmailAddress(), getGSuiteOutgoingEmailDisplayName(), emailService);
|
||||
action.registryEnvironment = RegistryEnvironment.get();
|
||||
action.registrarConsoleMetrics = new RegistrarConsoleMetrics();
|
||||
action.authResult =
|
||||
AuthResult.create(
|
||||
AuthLevel.USER,
|
||||
|
@ -117,10 +120,24 @@ public class RegistrarSettingsActionTestCase {
|
|||
// We set the default to a user with access, as that's the most common test case. When we want
|
||||
// to specifically check a user without access, we can switch user for that specific test.
|
||||
setUserWithAccess();
|
||||
RegistrarConsoleMetrics.settingsRequestMetric.reset();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
assertThat(RegistrarConsoleMetrics.settingsRequestMetric).hasNoOtherValues();
|
||||
}
|
||||
|
||||
public void assertMetric(String clientId, String op, String roles, String status) {
|
||||
assertThat(RegistrarConsoleMetrics.settingsRequestMetric)
|
||||
.hasValueForLabels(1, clientId, op, roles, status);
|
||||
RegistrarConsoleMetrics.settingsRequestMetric.reset(clientId, op, roles, status);
|
||||
}
|
||||
|
||||
/** Sets registrarAccessor.getRegistrar to succeed for all AccessTypes. */
|
||||
protected void setUserWithAccess() {
|
||||
action.registrarAccessor = mock(AuthenticatedRegistrarAccessor.class);
|
||||
|
||||
when(action.registrarAccessor.getAllClientIdWithRoles())
|
||||
.thenReturn(ImmutableSetMultimap.of(CLIENT_ID, OWNER));
|
||||
when(action.registrarAccessor.getRegistrar(CLIENT_ID))
|
||||
|
@ -129,6 +146,8 @@ public class RegistrarSettingsActionTestCase {
|
|||
|
||||
/** Sets registrarAccessor.getRegistrar to always fail. */
|
||||
protected void setUserWithoutAccess() {
|
||||
action.registrarAccessor = mock(AuthenticatedRegistrarAccessor.class);
|
||||
|
||||
when(action.registrarAccessor.getAllClientIdWithRoles()).thenReturn(ImmutableSetMultimap.of());
|
||||
when(action.registrarAccessor.getRegistrar(CLIENT_ID))
|
||||
.thenThrow(new ForbiddenException("forbidden test error"));
|
||||
|
@ -138,7 +157,11 @@ public class RegistrarSettingsActionTestCase {
|
|||
* Sets registrarAccessor.getAllClientIdWithRoles to return a map with admin role for CLIENT_ID
|
||||
*/
|
||||
protected void setUserAdmin() {
|
||||
action.registrarAccessor = mock(AuthenticatedRegistrarAccessor.class);
|
||||
|
||||
when(action.registrarAccessor.getAllClientIdWithRoles())
|
||||
.thenReturn(ImmutableSetMultimap.of(CLIENT_ID, ADMIN));
|
||||
when(action.registrarAccessor.getRegistrar(CLIENT_ID))
|
||||
.thenAnswer(x -> loadRegistrar(CLIENT_ID));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ public class SecuritySettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(response).containsEntry("status", "SUCCESS");
|
||||
assertThat(response).containsEntry("results", asList(modified.toJsonMap()));
|
||||
assertThat(loadRegistrar(CLIENT_ID)).isEqualTo(modified);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -73,6 +74,7 @@ public class SecuritySettingsTest extends RegistrarSettingsActionTestCase {
|
|||
"args", reqJson));
|
||||
assertThat(response).containsEntry("status", "ERROR");
|
||||
assertThat(response).containsEntry("message", "Invalid X.509 PEM certificate");
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -88,6 +90,7 @@ public class SecuritySettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
|
||||
assertThat(registrar.getFailoverClientCertificate()).isNull();
|
||||
assertThat(registrar.getFailoverClientCertificateHash()).isNull();
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -100,6 +103,7 @@ public class SecuritySettingsTest extends RegistrarSettingsActionTestCase {
|
|||
Registrar registrar = loadRegistrar(CLIENT_ID);
|
||||
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT2);
|
||||
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT2_HASH);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -122,6 +126,7 @@ public class SecuritySettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
|
||||
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT2);
|
||||
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT2_HASH);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -61,6 +61,7 @@ public class WhoisSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(response.get("status")).isEqualTo("SUCCESS");
|
||||
assertThat(response.get("results")).isEqualTo(asList(modified.toJsonMap()));
|
||||
assertThat(loadRegistrar(CLIENT_ID)).isEqualTo(modified);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -87,6 +88,7 @@ public class WhoisSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(response.get("field")).isEqualTo("localizedAddress.state");
|
||||
assertThat(response.get("message")).isEqualTo("Unknown US state code.");
|
||||
assertThat(loadRegistrar(CLIENT_ID)).isNotEqualTo(modified);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -114,6 +116,7 @@ public class WhoisSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat((String) response.get("message"))
|
||||
.contains("Number of characters (600) not in range");
|
||||
assertThat(loadRegistrar(CLIENT_ID)).isNotEqualTo(modified);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -127,5 +130,6 @@ public class WhoisSettingsTest extends RegistrarSettingsActionTestCase {
|
|||
assertThat(response.get("field")).isEqualTo("whoisServer");
|
||||
assertThat(response.get("message")).isEqualTo("Not a valid hostname.");
|
||||
assertThat(loadRegistrar(CLIENT_ID)).isNotEqualTo(modified);
|
||||
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue