Modify DeleteReservedListCommand to delete from both databases (#1025)

* Modify DeleteReservedListCommand to use both databases

* switch to confirming command

* fix typo
This commit is contained in:
sarahcaseybot 2021-03-19 18:49:15 -04:00 committed by GitHub
parent 4ed23f6813
commit 0b6a5aec96
8 changed files with 92 additions and 8 deletions

View file

@ -31,6 +31,11 @@ public class ReservedListDatastoreDao {
ofyTm().transact(() -> ofyTm().put(reservedList)); ofyTm().transact(() -> ofyTm().put(reservedList));
} }
/** Delete a reserved list from Datastore. */
public static void delete(ReservedList reservedList) {
ofyTm().transact(() -> ofyTm().delete(reservedList));
}
/** /**
* Returns the most recent revision of the {@link ReservedList} with the specified name, if it * Returns the most recent revision of the {@link ReservedList} with the specified name, if it
* exists. * exists.

View file

@ -51,6 +51,21 @@ public class ReservedListDualDatabaseDao {
} }
} }
/** Delete a reserved list from both databases. */
public static void delete(ReservedList reservedList) {
if (isDatastore(TransitionId.DOMAIN_LABEL_LISTS)) {
ReservedListDatastoreDao.delete(reservedList);
DatabaseMigrationUtils.suppressExceptionUnlessInTest(
() -> ReservedListSqlDao.delete(reservedList),
"Error deleting the reserved list from Cloud SQL.");
} else {
ReservedListSqlDao.delete(reservedList);
DatabaseMigrationUtils.suppressExceptionUnlessInTest(
() -> ReservedListDatastoreDao.delete(reservedList),
"Error deleting the reserved list from Datastore.");
}
}
/** /**
* Returns the most recent revision of the {@link ReservedList} with the specified name, if it * Returns the most recent revision of the {@link ReservedList} with the specified name, if it
* exists. * exists.

View file

@ -41,6 +41,11 @@ public class ReservedListSqlDao {
reservedList.getName(), reservedList.getReservedListEntries().size()); reservedList.getName(), reservedList.getReservedListEntries().size());
} }
/** Deletes a reserved list from Cloud SQL. */
public static void delete(ReservedList reservedList) {
jpaTm().transact(() -> jpaTm().delete(reservedList));
}
/** /**
* Returns the most recent revision of the {@link ReservedList} with the specified name, if it * Returns the most recent revision of the {@link ReservedList} with the specified name, if it
* exists. * exists.

View file

@ -21,13 +21,14 @@ import com.beust.jcommander.Parameters;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import google.registry.model.registry.label.ReservedList; import google.registry.model.registry.label.ReservedList;
import google.registry.model.registry.label.ReservedListDualDatabaseDao;
/** /**
* Command to delete a {@link ReservedList} in Datastore. This command will fail if the reserved * Command to delete a {@link ReservedList} from the database. This command will fail if the
* list is currently in use on a tld. * reserved list is currently in use on a tld.
*/ */
@Parameters(separators = " =", commandDescription = "Deletes a ReservedList in Datastore.") @Parameters(separators = " =", commandDescription = "Deletes a ReservedList from the database.")
final class DeleteReservedListCommand extends MutatingCommand { final class DeleteReservedListCommand extends ConfirmingCommand {
@Parameter( @Parameter(
names = {"-n", "--name"}, names = {"-n", "--name"},
@ -47,6 +48,12 @@ final class DeleteReservedListCommand extends MutatingCommand {
tldsUsedOn.isEmpty(), tldsUsedOn.isEmpty(),
"Cannot delete reserved list because it is used on these tld(s): %s", "Cannot delete reserved list because it is used on these tld(s): %s",
Joiner.on(", ").join(tldsUsedOn)); Joiner.on(", ").join(tldsUsedOn));
stageEntityChange(existing, null); }
@Override
protected String execute() {
ReservedList existing = ReservedList.get(name).get();
ReservedListDualDatabaseDao.delete(existing);
return String.format("Deleted reserved list: %s", name);
} }
} }

View file

@ -72,6 +72,21 @@ public class ReservedListDatastoreDaoTest {
assertThat(savedList.get()).isEqualTo(reservedList); assertThat(savedList.get()).isEqualTo(reservedList);
} }
@Test
void delete_worksSuccessfully() {
ReservedListDatastoreDao.save(reservedList);
assertThat(ReservedListDatastoreDao.getLatestRevision("testlist").isPresent()).isTrue();
ReservedListDatastoreDao.delete(reservedList);
assertThat(ReservedListDatastoreDao.getLatestRevision("testlist").isPresent()).isFalse();
}
@Test
void delete_listNotInDatastore() {
assertThat(ReservedListDatastoreDao.getLatestRevision("testlist").isPresent()).isFalse();
ReservedListDatastoreDao.delete(reservedList);
assertThat(ReservedListDatastoreDao.getLatestRevision("testlist").isPresent()).isFalse();
}
@Test @Test
void getLatestRevision_worksSuccessfully() { void getLatestRevision_worksSuccessfully() {
assertThat(ReservedListDatastoreDao.getLatestRevision("testlist").isPresent()).isFalse(); assertThat(ReservedListDatastoreDao.getLatestRevision("testlist").isPresent()).isFalse();

View file

@ -90,7 +90,7 @@ public class ReservedListDualDatabaseDaoTest extends EntityTestCase {
} }
@TestOfyAndSql @TestOfyAndSql
void testSave_CloudSqlPrimary_success() { void testSave_cloudSqlPrimary_success() {
fakeClock.advanceBy(Duration.standardDays(5)); fakeClock.advanceBy(Duration.standardDays(5));
ReservedListDualDatabaseDao.save(reservedList); ReservedListDualDatabaseDao.save(reservedList);
Optional<ReservedList> savedList = Optional<ReservedList> savedList =
@ -98,6 +98,27 @@ public class ReservedListDualDatabaseDaoTest extends EntityTestCase {
assertThat(savedList.get()).isEqualTo(reservedList); assertThat(savedList.get()).isEqualTo(reservedList);
} }
@TestOfyAndSql
void testDelete_datastorePrimary_success() {
ReservedListDualDatabaseDao.save(reservedList);
assertThat(ReservedListDualDatabaseDao.getLatestRevision(reservedList.getName()).isPresent())
.isTrue();
ReservedListDualDatabaseDao.delete(reservedList);
assertThat(ReservedListDualDatabaseDao.getLatestRevision(reservedList.getName()).isPresent())
.isFalse();
}
@TestOfyAndSql
void testDelete_cloudSqlPrimary_success() {
fakeClock.advanceBy(Duration.standardDays(5));
ReservedListDualDatabaseDao.save(reservedList);
assertThat(ReservedListDualDatabaseDao.getLatestRevision(reservedList.getName()).isPresent())
.isTrue();
ReservedListDualDatabaseDao.delete(reservedList);
assertThat(ReservedListDualDatabaseDao.getLatestRevision(reservedList.getName()).isPresent())
.isFalse();
}
@TestOfyAndSql @TestOfyAndSql
void testSaveAndLoad_datastorePrimary_emptyList() { void testSaveAndLoad_datastorePrimary_emptyList() {
ReservedList list = ReservedList list =

View file

@ -80,6 +80,21 @@ public class ReservedListSqlDaoTest {
}); });
} }
@Test
void delete_worksSuccessfully() {
ReservedListSqlDao.save(testReservedList);
assertThat(ReservedListSqlDao.checkExists("testlist")).isTrue();
ReservedListSqlDao.delete(testReservedList);
assertThat(ReservedListSqlDao.checkExists("testlist")).isFalse();
}
@Test
void delete_listNotInDatabase() {
assertThat(ReservedListSqlDao.checkExists("testlist")).isFalse();
ReservedListSqlDao.delete(testReservedList);
assertThat(ReservedListSqlDao.checkExists("testlist")).isFalse();
}
@Test @Test
void checkExists_worksSuccessfully() { void checkExists_worksSuccessfully() {
assertThat(ReservedListSqlDao.checkExists("testlist")).isFalse(); assertThat(ReservedListSqlDao.checkExists("testlist")).isFalse();

View file

@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
import google.registry.model.registry.label.ReservedList; import google.registry.model.registry.label.ReservedList;
import google.registry.model.registry.label.ReservedListDualDatabaseDao;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -40,7 +41,7 @@ class DeleteReservedListCommandTest extends CommandTestCase<DeleteReservedListCo
void testSuccess() throws Exception { void testSuccess() throws Exception {
assertThat(reservedList.getReservedListEntries()).hasSize(1); assertThat(reservedList.getReservedListEntries()).hasSize(1);
runCommandForced("--name=common"); runCommandForced("--name=common");
assertThat(ReservedList.get("common")).isEmpty(); assertThat(ReservedListDualDatabaseDao.getLatestRevision(reservedList.getName())).isEmpty();
} }
@Test @Test
@ -62,7 +63,7 @@ class DeleteReservedListCommandTest extends CommandTestCase<DeleteReservedListCo
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
() -> runCommandForced("--name=" + reservedList.getName())); () -> runCommandForced("--name=" + reservedList.getName()));
assertThat(ReservedList.get(reservedList.getName())).isPresent(); assertThat(ReservedListDualDatabaseDao.getLatestRevision(reservedList.getName())).isPresent();
assertThat(thrown) assertThat(thrown)
.hasMessageThat() .hasMessageThat()
.isEqualTo("Cannot delete reserved list because it is used on these tld(s): xn--q9jyb4c"); .isEqualTo("Cannot delete reserved list because it is used on these tld(s): xn--q9jyb4c");