Remove files that are not longer used for create/update premium list (#1288)

* Remove files that are not longer used for create/update premium list

* Remove comments/notes related to create/update premium list action files
This commit is contained in:
Rachel Guan 2021-08-18 14:04:57 -04:00 committed by GitHub
parent 2da8b53739
commit 03bb360a94
12 changed files with 1 additions and 482 deletions

View file

@ -44,7 +44,6 @@ def outcastTestPatterns = [
"google/registry/flows/domain/DomainCreateFlowTest.*", "google/registry/flows/domain/DomainCreateFlowTest.*",
"google/registry/flows/domain/DomainUpdateFlowTest.*", "google/registry/flows/domain/DomainUpdateFlowTest.*",
"google/registry/tools/CreateDomainCommandTest.*", "google/registry/tools/CreateDomainCommandTest.*",
"google/registry/tools/server/CreatePremiumListActionTest.*",
] ]
// Tests that fail when running Gradle in a docker container, e. g. when // Tests that fail when running Gradle in a docker container, e. g. when

View file

@ -30,7 +30,6 @@ import google.registry.request.RequestComponentBuilder;
import google.registry.request.RequestModule; import google.registry.request.RequestModule;
import google.registry.request.RequestScope; import google.registry.request.RequestScope;
import google.registry.tools.server.CreateGroupsAction; import google.registry.tools.server.CreateGroupsAction;
import google.registry.tools.server.CreatePremiumListAction;
import google.registry.tools.server.GenerateZoneFilesAction; import google.registry.tools.server.GenerateZoneFilesAction;
import google.registry.tools.server.KillAllCommitLogsAction; import google.registry.tools.server.KillAllCommitLogsAction;
import google.registry.tools.server.KillAllEppResourcesAction; import google.registry.tools.server.KillAllEppResourcesAction;
@ -43,7 +42,6 @@ import google.registry.tools.server.ListTldsAction;
import google.registry.tools.server.RefreshDnsForAllDomainsAction; import google.registry.tools.server.RefreshDnsForAllDomainsAction;
import google.registry.tools.server.ResaveAllHistoryEntriesAction; import google.registry.tools.server.ResaveAllHistoryEntriesAction;
import google.registry.tools.server.ToolsServerModule; import google.registry.tools.server.ToolsServerModule;
import google.registry.tools.server.UpdatePremiumListAction;
import google.registry.tools.server.VerifyOteAction; import google.registry.tools.server.VerifyOteAction;
/** Dagger component with per-request lifetime for "tools" App Engine module. */ /** Dagger component with per-request lifetime for "tools" App Engine module. */
@ -61,7 +59,6 @@ import google.registry.tools.server.VerifyOteAction;
}) })
interface ToolsRequestComponent { interface ToolsRequestComponent {
CreateGroupsAction createGroupsAction(); CreateGroupsAction createGroupsAction();
CreatePremiumListAction createPremiumListAction();
EppToolAction eppToolAction(); EppToolAction eppToolAction();
FlowComponent.Builder flowComponentBuilder(); FlowComponent.Builder flowComponentBuilder();
GenerateZoneFilesAction generateZoneFilesAction(); GenerateZoneFilesAction generateZoneFilesAction();
@ -77,7 +74,6 @@ interface ToolsRequestComponent {
RefreshDnsForAllDomainsAction refreshDnsForAllDomainsAction(); RefreshDnsForAllDomainsAction refreshDnsForAllDomainsAction();
ResaveAllHistoryEntriesAction resaveAllHistoryEntriesAction(); ResaveAllHistoryEntriesAction resaveAllHistoryEntriesAction();
RestoreCommitLogsAction restoreCommitLogsAction(); RestoreCommitLogsAction restoreCommitLogsAction();
UpdatePremiumListAction updatePremiumListAction();
VerifyOteAction verifyOteAction(); VerifyOteAction verifyOteAction();
@Subcomponent.Builder @Subcomponent.Builder

View file

@ -43,7 +43,6 @@ public class CreatePremiumListCommand extends CreateOrUpdatePremiumListCommand {
String currencyUnit; String currencyUnit;
@Override @Override
// Using CreatePremiumListAction.java as reference;
protected String prompt() throws Exception { protected String prompt() throws Exception {
currency = CurrencyUnit.of(currencyUnit); currency = CurrencyUnit.of(currencyUnit);
name = Strings.isNullOrEmpty(name) ? convertFilePathToName(inputFile) : name; name = Strings.isNullOrEmpty(name) ? convertFilePathToName(inputFile) : name;
@ -51,7 +50,6 @@ public class CreatePremiumListCommand extends CreateOrUpdatePremiumListCommand {
!PremiumListDao.getLatestRevision(name).isPresent(), !PremiumListDao.getLatestRevision(name).isPresent(),
"A premium list already exists by this name"); "A premium list already exists by this name");
if (!override) { if (!override) {
// refer to CreatePremiumListAction.java
assertTldExists( assertTldExists(
name, name,
"Premium names must match the name of the TLD they are intended to be used on" "Premium names must match the name of the TLD they are intended to be used on"

View file

@ -37,7 +37,6 @@ import java.util.Optional;
class UpdatePremiumListCommand extends CreateOrUpdatePremiumListCommand { class UpdatePremiumListCommand extends CreateOrUpdatePremiumListCommand {
@Override @Override
// Using UpdatePremiumListAction.java as reference;
protected String prompt() throws Exception { protected String prompt() throws Exception {
name = Strings.isNullOrEmpty(name) ? convertFilePathToName(inputFile) : name; name = Strings.isNullOrEmpty(name) ? convertFilePathToName(inputFile) : name;
Optional<PremiumList> list = PremiumListDao.getLatestRevision(name); Optional<PremiumList> list = PremiumListDao.getLatestRevision(name);

View file

@ -1,76 +0,0 @@
// 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.tools.server;
import static com.google.common.flogger.LazyArgs.lazy;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.FluentLogger;
import google.registry.request.JsonResponse;
import google.registry.request.Parameter;
import javax.inject.Inject;
/** Abstract base class for actions that update premium lists. */
public abstract class CreateOrUpdatePremiumListAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static final int MAX_LOGGING_PREMIUM_LIST_LENGTH = 1000;
public static final String NAME_PARAM = "name";
public static final String INPUT_PARAM = "inputData";
@Inject JsonResponse response;
@Inject
@Parameter("premiumListName")
String name;
@Inject
@Parameter(INPUT_PARAM)
String inputData;
@Override
public void run() {
try {
checkArgumentNotNull(inputData, "Input data must not be null");
save();
} catch (IllegalArgumentException e) {
logger.atInfo().withCause(e).log(
"Usage error in attempting to save premium list from nomulus tool command");
response.setPayload(ImmutableMap.of("error", e.getMessage(), "status", "error"));
} catch (Exception e) {
logger.atSevere().withCause(e).log(
"Unexpected error saving premium list to Datastore from nomulus tool command");
response.setPayload(ImmutableMap.of("error", e.getMessage(), "status", "error"));
}
}
/** Logs the premium list data at INFO, truncated if too long. */
void logInputData() {
String logData = (inputData == null) ? "(null)" : inputData;
logger.atInfo().log(
"Received the following input data: %s",
lazy(
() ->
(logData.length() < MAX_LOGGING_PREMIUM_LIST_LENGTH)
? logData
: (logData.substring(0, MAX_LOGGING_PREMIUM_LIST_LENGTH) + "<truncated>")));
}
/** Saves the premium list to both Datastore and Cloud SQL. */
protected abstract void save();
}

View file

@ -1,79 +0,0 @@
// 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.tools.server;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.model.tld.Registries.assertTldExists;
import static google.registry.request.Action.Method.POST;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.FluentLogger;
import google.registry.model.tld.label.PremiumListDao;
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.auth.Auth;
import java.util.List;
import javax.inject.Inject;
import org.joda.money.CurrencyUnit;
/**
* An action that creates a premium list, for use by the {@code nomulus create_premium_list}
* command.
*/
@Action(
service = Action.Service.TOOLS,
path = CreatePremiumListAction.PATH,
method = POST,
auth = Auth.AUTH_INTERNAL_OR_ADMIN)
public class CreatePremiumListAction extends CreateOrUpdatePremiumListAction {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
public static final String OVERRIDE_PARAM = "override";
public static final String PATH = "/_dr/admin/createPremiumList";
public static final String CURRENCY = "currency";
@Inject @Parameter(OVERRIDE_PARAM) boolean override;
@Inject
@Parameter("currency")
CurrencyUnit currency;
@Inject CreatePremiumListAction() {}
@Override
protected void save() {
checkArgument(
!PremiumListDao.getLatestRevision(name).isPresent(),
"A premium list of this name already exists: %s",
name);
if (!override) {
assertTldExists(
name,
"Premium names must match the name of the TLD they are intended to be used on"
+ " (unless --override is specified), yet TLD %s does not exist");
}
logger.atInfo().log("Saving premium list for TLD %s", name);
logInputData();
List<String> inputDataPreProcessed =
Splitter.on('\n').omitEmptyStrings().splitToList(inputData);
PremiumListDao.save(name, currency, inputDataPreProcessed);
String message =
String.format("Saved premium list %s with %d entries", name, inputDataPreProcessed.size());
logger.atInfo().log(message);
response.setPayload(ImmutableMap.of("status", "success", "message", message));
}
}

View file

@ -15,7 +15,6 @@
package google.registry.tools.server; package google.registry.tools.server;
import static com.google.common.base.Strings.emptyToNull; import static com.google.common.base.Strings.emptyToNull;
import static google.registry.request.RequestParameters.extractBooleanParameter;
import static google.registry.request.RequestParameters.extractIntParameter; import static google.registry.request.RequestParameters.extractIntParameter;
import static google.registry.request.RequestParameters.extractOptionalParameter; import static google.registry.request.RequestParameters.extractOptionalParameter;
import static google.registry.request.RequestParameters.extractRequiredParameter; import static google.registry.request.RequestParameters.extractRequiredParameter;
@ -28,7 +27,6 @@ import google.registry.request.Parameter;
import google.registry.request.RequestParameters; import google.registry.request.RequestParameters;
import java.util.Optional; import java.util.Optional;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.joda.money.CurrencyUnit;
/** /**
* Dagger module for the tools package. * Dagger module for the tools package.
@ -55,30 +53,6 @@ public class ToolsServerModule {
return (s == null) ? Optional.empty() : Optional.of(Boolean.parseBoolean(s)); return (s == null) ? Optional.empty() : Optional.of(Boolean.parseBoolean(s));
} }
@Provides
@Parameter("inputData")
static String provideInput(HttpServletRequest req) {
return extractRequiredParameter(req, CreatePremiumListAction.INPUT_PARAM);
}
@Provides
@Parameter("premiumListName")
static String provideName(HttpServletRequest req) {
return extractRequiredParameter(req, CreatePremiumListAction.NAME_PARAM);
}
@Provides
@Parameter("currency")
static CurrencyUnit provideCurrency(HttpServletRequest req) {
return CurrencyUnit.of(extractRequiredParameter(req, CreatePremiumListAction.CURRENCY));
}
@Provides
@Parameter("override")
static boolean provideOverride(HttpServletRequest req) {
return extractBooleanParameter(req, CreatePremiumListAction.OVERRIDE_PARAM);
}
@Provides @Provides
@Parameter("printHeaderRow") @Parameter("printHeaderRow")
static Optional<Boolean> providePrintHeaderRow(HttpServletRequest req) { static Optional<Boolean> providePrintHeaderRow(HttpServletRequest req) {

View file

@ -1,70 +0,0 @@
// 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.tools.server;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.request.Action.Method.POST;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.FluentLogger;
import google.registry.model.tld.label.PremiumList;
import google.registry.model.tld.label.PremiumListDao;
import google.registry.request.Action;
import google.registry.request.auth.Auth;
import java.util.List;
import java.util.Optional;
import javax.inject.Inject;
/**
* An action that creates a premium list, for use by the {@code nomulus create_premium_list}
* command.
*/
@Action(
service = Action.Service.TOOLS,
path = UpdatePremiumListAction.PATH,
method = POST,
auth = Auth.AUTH_INTERNAL_OR_ADMIN)
public class UpdatePremiumListAction extends CreateOrUpdatePremiumListAction {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
public static final String PATH = "/_dr/admin/updatePremiumList";
@Inject UpdatePremiumListAction() {}
@Override
protected void save() {
Optional<PremiumList> existingList = PremiumListDao.getLatestRevision(name);
checkArgument(
existingList.isPresent(),
"Could not update premium list %s because it doesn't exist.",
name);
logger.atInfo().log("Updating premium list for TLD %s", name);
logInputData();
List<String> inputDataPreProcessed =
Splitter.on('\n').omitEmptyStrings().splitToList(inputData);
PremiumList newPremiumList =
PremiumListDao.save(name, existingList.get().getCurrency(), inputDataPreProcessed);
String message =
String.format(
"Updated premium list %s with %d entries.",
newPremiumList.getName(), inputDataPreProcessed.size());
logger.atInfo().log(message);
response.setPayload(ImmutableMap.of("status", "success", "message", message));
}
}

View file

@ -1,109 +0,0 @@
// 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.tools.server;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.loadPremiumEntries;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.joda.money.CurrencyUnit.USD;
import google.registry.model.tld.label.PremiumList;
import google.registry.model.tld.label.PremiumListDao;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.FakeJsonResponse;
import org.joda.money.Money;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/**
* Unit tests for {@link CreatePremiumListAction}.
*/
public class CreatePremiumListActionTest {
@RegisterExtension
public final AppEngineExtension appEngine =
AppEngineExtension.builder().withDatastoreAndCloudSql().build();
private CreatePremiumListAction action;
private FakeJsonResponse response;
@BeforeEach
void beforeEach() {
createTlds("foo", "xn--q9jyb4c", "how");
PremiumListDao.delete(PremiumListDao.getLatestRevision("foo").get());
action = new CreatePremiumListAction();
response = new FakeJsonResponse();
action.response = response;
}
@Test
void test_invalidRequest_missingInput_returnsErrorStatus() {
action.name = "foo";
action.run();
assertThat(response.getResponseMap().get("status")).isEqualTo("error");
}
@Test
void test_invalidRequest_listAlreadyExists_returnsErrorStatus() {
action.name = "how";
action.inputData = "richer,JPY 5000";
action.run();
assertThat(response.getResponseMap().get("status")).isEqualTo("error");
Object obj = response.getResponseMap().get("error");
assertThat(obj).isInstanceOf(String.class);
String error = obj.toString();
assertThat(error).contains("A premium list of this name already exists");
}
@Test
void test_nonExistentTld_fails() {
action.name = "zanzibar";
action.inputData = "zanzibar,USD 100";
action.run();
assertThat(response.getResponseMap().get("status")).isEqualTo("error");
assertThat(response.getResponseMap().get("error").toString())
.isEqualTo(
"Premium names must match the name of the TLD they are intended to be used on"
+ " (unless --override is specified), yet TLD zanzibar does not exist");
}
@Test
void test_nonExistentTld_successWithOverride() {
action.name = "zanzibar";
action.inputData = "zanzibar,USD 100";
action.override = true;
action.currency = USD;
action.run();
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(loadPremiumEntries(PremiumListDao.getLatestRevision("zanzibar").get())).hasSize(1);
}
@Test
void test_success() {
action.name = "foo";
action.inputData = "rich,USD 25\nricher,USD 1000\n";
action.currency = USD;
action.run();
assertThat(response.getStatus()).isEqualTo(SC_OK);
PremiumList premiumList = PremiumListDao.getLatestRevision("foo").get();
assertThat(loadPremiumEntries(premiumList)).hasSize(2);
assertThat(PremiumListDao.getPremiumPrice(premiumList.getName(), "rich"))
.hasValue(Money.parse("USD 25"));
assertThat(PremiumListDao.getPremiumPrice(premiumList.getName(), "diamond")).isEmpty();
}
}

View file

@ -1,110 +0,0 @@
// 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.tools.server;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.loadPremiumEntries;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.joda.money.CurrencyUnit.USD;
import com.google.common.base.Splitter;
import com.google.common.truth.Truth8;
import google.registry.model.tld.label.PremiumList;
import google.registry.model.tld.label.PremiumListDao;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.FakeJsonResponse;
import java.math.BigDecimal;
import java.util.List;
import org.joda.money.Money;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link UpdatePremiumListAction}. */
class UpdatePremiumListActionTest {
@RegisterExtension
final AppEngineExtension appEngine =
AppEngineExtension.builder().withDatastoreAndCloudSql().build();
private UpdatePremiumListAction action;
private FakeJsonResponse response;
@BeforeEach
void beforeEach() {
createTlds("foo", "xn--q9jyb4c", "how");
action = new UpdatePremiumListAction();
response = new FakeJsonResponse();
action.response = response;
}
@Test
void test_invalidRequest_missingInput_returnsErrorStatus() {
action.name = "foo";
action.run();
assertThat(response.getResponseMap().get("status")).isEqualTo("error");
}
@Test
void test_invalidRequest_listDoesNotExist_returnsErrorStatus() {
action.name = "bamboozle";
action.inputData = "richer,JPY 5000";
action.run();
assertThat(response.getResponseMap().get("status")).isEqualTo("error");
Object obj = response.getResponseMap().get("error");
assertThat(obj).isInstanceOf(String.class);
String error = obj.toString();
assertThat(error).contains("Could not update premium list");
}
@Test
void test_success() {
List<String> inputLines =
Splitter.on('\n')
.omitEmptyStrings()
.splitToList(
readResourceUtf8(DatabaseHelper.class, "default_premium_list_testdata.csv"));
PremiumListDao.save("foo", USD, inputLines);
action.name = "foo";
action.inputData = "rich,USD 75\nricher,USD 5000\npoor, USD 0.99";
action.run();
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(loadPremiumEntries(PremiumListDao.getLatestRevision("foo").get())).hasSize(3);
Truth8.assertThat(PremiumListDao.getPremiumPrice("foo", "rich"))
.hasValue(Money.parse("USD 75"));
Truth8.assertThat(PremiumListDao.getPremiumPrice("foo", "richer"))
.hasValue(Money.parse("USD 5000"));
Truth8.assertThat(PremiumListDao.getPremiumPrice("foo", "poor"))
.hasValue(Money.parse("USD 0.99"));
Truth8.assertThat(PremiumListDao.getPremiumPrice("foo", "diamond")).isEmpty();
jpaTm()
.transact(
() -> {
PremiumList persistedList = PremiumListDao.getLatestRevision("foo").get();
assertThat(persistedList.getLabelsToPrices())
.containsEntry("rich", new BigDecimal("75.00"));
assertThat(persistedList.getLabelsToPrices())
.containsEntry("richer", new BigDecimal("5000.00"));
assertThat(persistedList.getLabelsToPrices())
.containsEntry("poor", BigDecimal.valueOf(0.99));
assertThat(persistedList.getLabelsToPrices()).doesNotContainKey("diamond");
});
}
}

View file

@ -1,13 +1,11 @@
PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY
/_dr/admin/createGroups CreateGroupsAction POST n INTERNAL,API APP ADMIN /_dr/admin/createGroups CreateGroupsAction POST n INTERNAL,API APP ADMIN
/_dr/admin/createPremiumList CreatePremiumListAction POST n INTERNAL,API APP ADMIN
/_dr/admin/list/domains ListDomainsAction GET,POST n INTERNAL,API APP ADMIN /_dr/admin/list/domains ListDomainsAction GET,POST n INTERNAL,API APP ADMIN
/_dr/admin/list/hosts ListHostsAction GET,POST n INTERNAL,API APP ADMIN /_dr/admin/list/hosts ListHostsAction GET,POST n INTERNAL,API APP ADMIN
/_dr/admin/list/premiumLists ListPremiumListsAction GET,POST n INTERNAL,API APP ADMIN /_dr/admin/list/premiumLists ListPremiumListsAction GET,POST n INTERNAL,API APP ADMIN
/_dr/admin/list/registrars ListRegistrarsAction GET,POST n INTERNAL,API APP ADMIN /_dr/admin/list/registrars ListRegistrarsAction GET,POST n INTERNAL,API APP ADMIN
/_dr/admin/list/reservedLists ListReservedListsAction GET,POST n INTERNAL,API APP ADMIN /_dr/admin/list/reservedLists ListReservedListsAction GET,POST n INTERNAL,API APP ADMIN
/_dr/admin/list/tlds ListTldsAction GET,POST n INTERNAL,API APP ADMIN /_dr/admin/list/tlds ListTldsAction GET,POST n INTERNAL,API APP ADMIN
/_dr/admin/updatePremiumList UpdatePremiumListAction POST n INTERNAL,API APP ADMIN
/_dr/admin/verifyOte VerifyOteAction POST n INTERNAL,API APP ADMIN /_dr/admin/verifyOte VerifyOteAction POST n INTERNAL,API APP ADMIN
/_dr/epptool EppToolAction POST n INTERNAL,API APP ADMIN /_dr/epptool EppToolAction POST n INTERNAL,API APP ADMIN
/_dr/loadtest LoadTestAction POST y INTERNAL,API APP ADMIN /_dr/loadtest LoadTestAction POST y INTERNAL,API APP ADMIN

View file

@ -62,8 +62,7 @@ to `ToolsServlet` to execute the action on the server (these commands implement
[Remote API](https://cloud.google.com/appengine/docs/java/tools/remoteapi) [Remote API](https://cloud.google.com/appengine/docs/java/tools/remoteapi)
(these commands implement `RemoteApiCommand`). Server-side commands take more (these commands implement `RemoteApiCommand`). Server-side commands take more
work to implement because they require both a client and a server-side work to implement because they require both a client and a server-side
component, e.g. `CreatePremiumListCommand.java` and component.
`CreatePremiumListAction.java` respectively for creating a premium list.
However, they are fully capable of doing anything that is possible with App However, they are fully capable of doing anything that is possible with App
Engine, including running a large MapReduce, because they execute on the tools Engine, including running a large MapReduce, because they execute on the tools
service in the App Engine cloud. service in the App Engine cloud.