Use PrintStream in ConfirmingCommand (#2140)

* Use PrintStream in ConfirmingCommand

* Add errorPrintStream

* remove unneccesary line
This commit is contained in:
sarahcaseybot 2023-09-19 12:11:18 -04:00 committed by GitHub
parent e182692a5f
commit fc1857717d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 79 additions and 38 deletions

View file

@ -15,9 +15,12 @@
package google.registry.tools;
import static google.registry.tools.CommandUtilities.promptForYes;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beust.jcommander.Parameter;
import com.google.common.base.Strings;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
/** A {@link Command} that implements a confirmation step before executing. */
public abstract class ConfirmingCommand implements Command {
@ -27,23 +30,37 @@ public abstract class ConfirmingCommand implements Command {
description = "Do not prompt before executing")
boolean force;
public PrintStream printStream;
public PrintStream errorPrintStream;
protected ConfirmingCommand() {
try {
printStream = new PrintStream(System.out, false, UTF_8.name());
errorPrintStream = new PrintStream(System.err, false, UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
@Override
public final void run() throws Exception {
if (checkExecutionState()) {
init();
printLineIfNotEmpty(prompt());
printLineIfNotEmpty(prompt(), printStream);
if (dontRunCommand()) {
// This typically happens when all of the work is accomplished inside of prompt(), so do
// nothing further.
return;
} else if (force || promptForYes("Perform this command?")) {
System.out.println("Running ... ");
System.out.println(execute());
printLineIfNotEmpty(postExecute());
printStream.println("Running ... ");
printStream.println(execute());
printLineIfNotEmpty(postExecute(), printStream);
} else {
System.out.println("Command aborted.");
printStream.println("Command aborted.");
}
}
printStream.close();
errorPrintStream.close();
}
/** Run any pre-execute command checks and return true if they all pass. */
@ -76,9 +93,9 @@ public abstract class ConfirmingCommand implements Command {
}
/** Prints the provided text with a trailing newline, if text is not null or empty. */
private static void printLineIfNotEmpty(String text) {
private static void printLineIfNotEmpty(String text, PrintStream printStream) {
if (!Strings.isNullOrEmpty(text)) {
System.out.println(text);
printStream.println(text);
}
}
}

View file

@ -78,7 +78,7 @@ final class CreateDomainCommand extends CreateOrUpdateDomainCommand {
Money createCost = prices.getCreateCost();
currency = createCost.getCurrencyUnit().getCode();
cost = createCost.multipliedBy(period).getAmount().toString();
System.out.printf(
printStream.printf(
"NOTE: %s is premium at %s per year; sending total cost for %d year(s) of %s %s.\n",
domain, createCost, period, currency, cost);
}

View file

@ -39,6 +39,7 @@ import google.registry.tools.params.OptionalStringParameter;
import google.registry.tools.params.StringListParameter;
import google.registry.tools.params.TransitionListParameter.BillingCostTransitions;
import google.registry.tools.params.TransitionListParameter.TldStateTransitions;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -237,8 +238,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
description =
"The number of publish locks we allow in parallel for DNS updates under this tld "
+ "(1 for TLD-wide locks)",
arity = 1
)
arity = 1)
Integer numDnsPublishShards;
@Nullable
@ -301,7 +301,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
protected abstract void initTldCommand();
@Override
protected final void init() {
protected final void init() throws UnsupportedEncodingException {
assertAllowedEnvironment();
initTldCommand();
String duplicates = Joiner.on(", ").join(findDuplicates(mainParameters));
@ -360,7 +360,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
if (!renewBillingCostTransitions.isEmpty()) {
// TODO(b/20764952): need invoicing support for multiple renew billing costs.
if (renewBillingCostTransitions.size() > 1) {
System.err.println(
errorPrintStream.println(
"----------------------\n"
+ "WARNING: Do not set multiple renew cost transitions "
+ "until b/20764952 is fixed.\n"
@ -463,7 +463,8 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
}
}
private void checkReservedListValidityForTld(String tld, Set<String> reservedListNames) {
private void checkReservedListValidityForTld(String tld, Set<String> reservedListNames)
throws UnsupportedEncodingException {
ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
for (String reservedListName : reservedListNames) {
if (!reservedListName.startsWith("common_") && !reservedListName.startsWith(tld + "_")) {
@ -476,7 +477,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
Joiner.on(", ").join(invalidNames),
tld);
if (overrideReservedListRules) {
System.err.println("Error overridden: " + errMsg);
errorPrintStream.println("Error overridden: " + errMsg);
} else {
throw new IllegalArgumentException(errMsg);
}

View file

@ -85,7 +85,7 @@ final class DeleteAllocationTokensCommand extends UpdateOrDeleteAllocationTokens
if (!dryRun) {
tm().delete(tokensToDelete);
}
System.out.printf(
printStream.printf(
"%s tokens: %s\n",
dryRun ? "Would delete" : "Deleted",
JOINER.join(tokensToDelete.stream().map(VKey::getKey).sorted().collect(toImmutableList())));

View file

@ -14,6 +14,7 @@
package google.registry.tools;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.collect.ImmutableMap;
@ -86,17 +87,17 @@ class LoadTestCommand extends ConfirmingCommand implements CommandWithConnection
@Override
protected boolean checkExecutionState() {
if (RegistryToolEnvironment.get() == RegistryToolEnvironment.PRODUCTION) {
System.err.println("You may not run a load test against production.");
errorPrintStream.println("You may not run a load test against production.");
return false;
}
// Check validity of TLD and Client Id.
if (!Tlds.getTlds().contains(tld)) {
System.err.printf("No such TLD: %s\n", tld);
errorPrintStream.printf("No such TLD: %s\n", tld);
return false;
}
if (!Registrar.loadByRegistrarId(clientId).isPresent()) {
System.err.printf("No such client: %s\n", clientId);
errorPrintStream.printf("No such client: %s\n", clientId);
return false;
}
@ -112,7 +113,7 @@ class LoadTestCommand extends ConfirmingCommand implements CommandWithConnection
@Override
protected String execute() throws Exception {
System.err.println("Initiating load test...");
errorPrintStream.println("Initiating load test...");
ImmutableMap<String, Object> params = new ImmutableMap.Builder<String, Object>()
.put("tld", tld)

View file

@ -71,7 +71,7 @@ public abstract class LockOrUnlockDomainCommand extends ConfirmingCommand {
}
String duplicates = Joiner.on(", ").join(findDuplicates(mainParameters));
checkArgument(duplicates.isEmpty(), "Duplicate domain arguments found: '%s'", duplicates);
System.out.println(
printStream.println(
"== ENSURE THAT YOU HAVE AUTHENTICATED THE REGISTRAR BEFORE RUNNING THIS COMMAND ==");
}

View file

@ -42,6 +42,7 @@ import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry.Type;
import google.registry.util.Clock;
import google.registry.util.NonFinalForTesting;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Optional;
import javax.inject.Inject;
@ -76,7 +77,7 @@ class UnrenewDomainCommand extends ConfirmingCommand {
StatusValue.SERVER_UPDATE_PROHIBITED);
@Override
protected void init() {
protected void init() throws UnsupportedEncodingException {
checkArgument(period >= 1 && period <= 9, "Period must be in the range 1-9");
DateTime now = clock.nowUtc();
ImmutableSet.Builder<String> domainsNonexistentBuilder = new ImmutableSet.Builder<>();
@ -116,20 +117,24 @@ class UnrenewDomainCommand extends ConfirmingCommand {
&& domainsDeleting.isEmpty()
&& domainsWithDisallowedStatuses.isEmpty()
&& domainsExpiringTooSoon.isEmpty());
if (foundInvalidDomains) {
System.err.print("Found domains that cannot be unrenewed for the following reasons:\n\n");
errorPrintStream.print(
"Found domains that cannot be unrenewed for the following reasons:\n\n");
}
if (!domainsNonexistent.isEmpty()) {
System.err.printf("Domains that don't exist: %s\n\n", domainsNonexistent);
errorPrintStream.printf("Domains that don't exist: %s\n\n", domainsNonexistent);
}
if (!domainsDeleting.isEmpty()) {
System.err.printf("Domains that are deleted or pending delete: %s\n\n", domainsDeleting);
errorPrintStream.printf(
"Domains that are deleted or pending delete: %s\n\n", domainsDeleting);
}
if (!domainsWithDisallowedStatuses.isEmpty()) {
System.err.printf("Domains with disallowed statuses: %s\n\n", domainsWithDisallowedStatuses);
errorPrintStream.printf(
"Domains with disallowed statuses: %s\n\n", domainsWithDisallowedStatuses);
}
if (!domainsExpiringTooSoon.isEmpty()) {
System.err.printf("Domains expiring too soon: %s\n\n", domainsExpiringTooSoon);
errorPrintStream.printf("Domains expiring too soon: %s\n\n", domainsExpiringTooSoon);
}
checkArgument(!foundInvalidDomains, "Aborting because some domains cannot be unrenewed");
}
@ -154,7 +159,7 @@ class UnrenewDomainCommand extends ConfirmingCommand {
protected String execute() {
for (String domainName : mainParameters) {
tm().transact(() -> unrenewDomain(domainName));
System.out.printf("Unrenewed %s\n", domainName);
printStream.printf("Unrenewed %s\n", domainName);
}
return "Successfully unrenewed all domains.";
}

View file

@ -208,7 +208,7 @@ final class UpdateAllocationTokensCommand extends UpdateOrDeleteAllocationTokens
if (!dryRun) {
tm().putAll(batch);
}
System.out.printf(
printStream.printf(
"%s tokens: %s\n",
dryRun ? "Would update" : "Updated",
JOINER.join(

View file

@ -70,14 +70,14 @@ public class CreateCancellationsForBillingEventsCommand extends ConfirmingComman
}
});
billingEventsToCancel = billingEventsBuilder.build();
System.out.printf("Found %d BillingEvent(s) to cancel\n", billingEventsToCancel.size());
printStream.printf("Found %d BillingEvent(s) to cancel\n", billingEventsToCancel.size());
ImmutableSet<Long> missingIds = missingIdsBuilder.build();
if (!missingIds.isEmpty()) {
System.out.printf("Missing BillingEvent(s) for IDs %s\n", missingIds);
printStream.printf("Missing BillingEvent(s) for IDs %s\n", missingIds);
}
ImmutableSet<Long> alreadyCancelledIds = alreadyCancelledIdsBuilder.build();
if (!alreadyCancelledIds.isEmpty()) {
System.out.printf(
printStream.printf(
"The following BillingEvent IDs were already cancelled: %s\n", alreadyCancelledIds);
}
}
@ -96,7 +96,7 @@ public class CreateCancellationsForBillingEventsCommand extends ConfirmingComman
tm().transact(
() -> {
if (alreadyCancelled(billingEvent)) {
System.out.printf(
printStream.printf(
"BillingEvent %d already cancelled, this is unexpected.\n",
billingEvent.getId());
return 0;
@ -111,7 +111,7 @@ public class CreateCancellationsForBillingEventsCommand extends ConfirmingComman
.setReason(BillingBase.Reason.ERROR)
.setTargetId(billingEvent.getTargetId())
.build());
System.out.printf(
printStream.printf(
"Added BillingCancellation for BillingEvent with ID %d\n",
billingEvent.getId());
return 1;

View file

@ -198,7 +198,7 @@ public abstract class CommandTestCase<C extends Command> {
}
void assertInStderr(String... expected) {
String stderror = new String(stderr.toByteArray(), UTF_8);
String stderror = getStderrAsString();
for (String line : expected) {
assertThat(stderror).contains(line);
}

View file

@ -38,6 +38,7 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
@BeforeEach
void beforeEach() {
command.passwordGenerator = new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz");
command.printStream = System.out;
}
@Test

View file

@ -68,6 +68,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
2048,
ImmutableSet.of("secp256r1", "secp384r1"),
fakeClock);
command.printStream = System.out;
}
@Test

View file

@ -37,6 +37,7 @@ class CreateRegistrarGroupsCommandTest extends CommandTestCase<CreateRegistrarGr
@Test
void test_createGroupsForTwoRegistrars() throws Exception {
command.printStream = System.out;
runCommandForced("NewRegistrar", "TheRegistrar");
verify(connection)
.sendPostRequest(

View file

@ -521,6 +521,7 @@ class CreateTldCommandTest extends CommandTestCase<CreateTldCommand> {
@Test
void testSuccess_setCommonAndReservedListFromOtherTld_withOverride() throws Exception {
command.errorPrintStream = System.err;
runReservedListsTestOverride("common_abuse,tld_banned");
String errMsg =
"Error overridden: The reserved list(s) tld_banned "

View file

@ -53,6 +53,7 @@ class DeleteAllocationTokensCommandTest extends CommandTestCase<DeleteAllocation
preNot2 = persistToken("prefix8ZZZhs8", null, false);
othrRed = persistToken("h97987sasdfhh", null, true);
othrNot = persistToken("asdgfho7HASDS", null, false);
command.printStream = System.out;
}
@Test

View file

@ -37,6 +37,8 @@ class LoadTestCommandTest extends CommandTestCase<LoadTestCommand> {
command.setConnection(connection);
createTld("example");
persistNewRegistrar("acme", "ACME", Registrar.Type.REAL, 99L);
command.printStream = System.out;
command.errorPrintStream = System.err;
}
@Test

View file

@ -50,6 +50,7 @@ class LockDomainCommandTest extends CommandTestCase<LockDomainCommand> {
new DeterministicStringGenerator(Alphabets.BASE_58),
"adminreg",
new CloudTasksHelper(fakeClock).getTestCloudTasksUtils());
command.printStream = System.out;
}
@Test

View file

@ -61,6 +61,7 @@ class UniformRapidSuspensionCommandTest
ImmutableSet.of(
DomainDsData.create(1, 2, 3, new HexBinaryAdapter().unmarshal("dead")),
DomainDsData.create(4, 5, 6, new HexBinaryAdapter().unmarshal("beef")));
command.printStream = System.out;
}
private void persistDomainWithHosts(

View file

@ -53,6 +53,7 @@ class UnlockDomainCommandTest extends CommandTestCase<UnlockDomainCommand> {
new DeterministicStringGenerator(Alphabets.BASE_58),
"adminreg",
new CloudTasksHelper(fakeClock).getTestCloudTasksUtils());
command.printStream = System.out;
}
private Domain persistLockedDomain(String domainName, String registrarId) {

View file

@ -55,6 +55,7 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
createTld("tld");
fakeClock.setTo(DateTime.parse("2016-12-06T13:55:01Z"));
command.clock = fakeClock;
command.printStream = System.out;
}
@Test
@ -178,6 +179,7 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
@Test
void test_varietyOfInvalidDomains_displaysErrors() {
command.errorPrintStream = System.err;
DateTime now = fakeClock.nowUtc();
persistResource(
DatabaseHelper.newDomain("deleting.tld")

View file

@ -1048,6 +1048,7 @@ class UpdateTldCommandTest extends CommandTestCase<UpdateTldCommand> {
@Test
void testSuccess_setCommonAndReservedListFromOtherTld_withOverride() throws Exception {
command.errorPrintStream = System.err;
runReservedListsTestOverride("common_abuse,tld_banned");
String errMsg =
"Error overridden: The reserved list(s) tld_banned "

View file

@ -34,6 +34,7 @@ import google.registry.model.reporting.HistoryEntryDao;
import google.registry.persistence.VKey;
import google.registry.testing.DatabaseHelper;
import google.registry.tools.CommandTestCase;
import java.io.PrintStream;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.junit.jupiter.api.BeforeEach;
@ -59,6 +60,7 @@ public class CreateCancellationsForBillingEventsCommandTest
fakeClock.nowUtc(),
fakeClock.nowUtc().plusYears(2));
billingEventToCancel = createBillingEvent();
command.printStream = System.out;
}
@Test
@ -97,8 +99,10 @@ public class CreateCancellationsForBillingEventsCommandTest
@Test
void testAlreadyCancelled() throws Exception {
// multiple runs / cancellations should be a no-op
command.printStream = new PrintStream(tmpDir.resolve("test.txt").toFile());
runCommandForced(String.valueOf(billingEventToCancel.getId()));
assertBillingEventCancelled();
command.printStream = System.out;
runCommandForced(String.valueOf(billingEventToCancel.getId()));
assertBillingEventCancelled();
assertThat(DatabaseHelper.loadAllOf(BillingCancellation.class)).hasSize(1);