From 76d63b24a87e1cc9a5788e442d8cc535e33833dd Mon Sep 17 00:00:00 2001 From: Lai Jiang Date: Tue, 28 Jun 2022 14:59:21 -0400 Subject: [PATCH] Remove Ofy support from Cursor (#1672) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cursor was originally envisioned to support arbitary ImmutableObject scopes. However, in practice only the Registry scope is used. The SQL representation of Cursor assumes that and the schema uses a composite ID with a string column for the primary key of the scope object. Without a schema migration to persist the VKey of the scope, we cannot support any ImmutableObject other than those with a primitive string primary key. Given the complexity involved and the limited use case, the scope is now explictly limited to Registry only. Also removed mapreduces that depends on Ofy keys of Cursors, and made some code quality improvement based on IntelliJ suggestions on modified files. --- This change is [Reviewable](https://reviewable.io/reviews/google/nomulus/1672) --- .../java/google/registry/beam/rde/RdeIO.java | 4 +- .../registry/config/RegistryConfig.java | 5 +- .../google/registry/model/EntityClasses.java | 2 - .../google/registry/model/EppResource.java | 7 +- .../google/registry/model/common/Cursor.java | 203 ++++++------------ .../model/contact/ContactHistory.java | 1 + .../registry/model/domain/DomainHistory.java | 1 + .../model/domain/token/AllocationToken.java | 1 + .../registry/model/host/HostHistory.java | 1 + .../registry/model/registrar/Registrar.java | 1 + .../model/registrar/RegistrarPoc.java | 1 + .../registry/persistence/EppHistoryVKey.java | 1 + .../google/registry/rde/BrdaCopyAction.java | 5 +- .../google/registry/rde/EscrowTaskRunner.java | 6 +- .../registry/rde/PendingDepositChecker.java | 6 +- .../google/registry/rde/RdeReportAction.java | 7 +- .../google/registry/rde/RdeUploadAction.java | 13 +- .../icann/IcannReportingUploadAction.java | 6 +- .../registry/tools/ListCursorsCommand.java | 2 +- .../registry/tools/UpdateCursorsCommand.java | 2 +- .../tools/GenerateSqlSchemaCommand.java | 12 +- .../registry/tools/PostgresqlCommand.java | 6 +- .../registry/beam/rde/RdePipelineTest.java | 8 +- .../model/common/ClassPathManagerTest.java | 2 - .../registry/model/common/CursorTest.java | 110 +++------- .../registry/persistence/BillingVKeyTest.java | 1 + .../persistence/DomainHistoryVKeyTest.java | 1 + .../registry/rde/BrdaCopyActionTest.java | 4 +- .../registry/rde/EscrowTaskRunnerTest.java | 10 +- .../rde/PendingDepositCheckerTest.java | 13 +- .../registry/rde/RdeReportActionTest.java | 15 +- .../registry/rde/RdeStagingActionTest.java | 2 +- .../registry/rde/RdeUploadActionTest.java | 22 +- .../icann/IcannReportingUploadActionTest.java | 30 +-- .../registry/testing/DatabaseHelper.java | 22 +- .../testing/DatastoreEntityExtension.java | 2 + .../tools/ListCursorsCommandTest.java | 2 +- .../tools/UpdateCursorsCommandTest.java | 31 ++- .../google/registry/export/backup_kinds.txt | 1 - .../google/registry/export/crosstld_kinds.txt | 1 - .../google/registry/model/schema.txt | 6 - 41 files changed, 235 insertions(+), 341 deletions(-) diff --git a/core/src/main/java/google/registry/beam/rde/RdeIO.java b/core/src/main/java/google/registry/beam/rde/RdeIO.java index ff06237bf..1091ad09f 100644 --- a/core/src/main/java/google/registry/beam/rde/RdeIO.java +++ b/core/src/main/java/google/registry/beam/rde/RdeIO.java @@ -279,7 +279,7 @@ public class RdeIO { transactIfJpaTm( () -> tm().loadByKeyIfPresent( - Cursor.createVKey(key.cursor(), registry.getTldStr()))); + Cursor.createScopedVKey(key.cursor(), registry))); DateTime position = getCursorTimeOrStartOfTime(cursor); checkState(key.interval() != null, "Interval must be present"); DateTime newPosition = key.watermark().plus(key.interval()); @@ -292,7 +292,7 @@ public class RdeIO { "Partial ordering of RDE deposits broken: %s %s", position, key); - tm().put(Cursor.create(key.cursor(), newPosition, registry)); + tm().put(Cursor.createScoped(key.cursor(), newPosition, registry)); logger.atInfo().log( "Rolled forward %s on %s cursor to %s.", key.cursor(), key.tld(), newPosition); RdeRevision.saveRevision(key.tld(), key.watermark(), key.mode(), input.getValue()); diff --git a/core/src/main/java/google/registry/config/RegistryConfig.java b/core/src/main/java/google/registry/config/RegistryConfig.java index a50e69734..3fe8f8118 100644 --- a/core/src/main/java/google/registry/config/RegistryConfig.java +++ b/core/src/main/java/google/registry/config/RegistryConfig.java @@ -27,7 +27,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Ascii; import com.google.common.base.Splitter; import com.google.common.base.Strings; -import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedMap; @@ -42,7 +41,9 @@ import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; +import java.util.function.Supplier; import java.util.stream.Collectors; import javax.annotation.Nullable; import javax.inject.Named; @@ -1266,7 +1267,7 @@ public final class RegistryConfig { e.getKey().equals("START_OF_TIME") ? START_OF_TIME : DateTime.parse(e.getKey()), - e -> e.getValue())); + Entry::getValue)); } @Provides diff --git a/core/src/main/java/google/registry/model/EntityClasses.java b/core/src/main/java/google/registry/model/EntityClasses.java index 08280e8f5..dd7d91df8 100644 --- a/core/src/main/java/google/registry/model/EntityClasses.java +++ b/core/src/main/java/google/registry/model/EntityClasses.java @@ -17,7 +17,6 @@ package google.registry.model; import com.google.common.collect.ImmutableSet; import google.registry.model.annotations.DeleteAfterMigration; import google.registry.model.billing.BillingEvent; -import google.registry.model.common.Cursor; import google.registry.model.common.EntityGroupRoot; import google.registry.model.common.GaeUserIdConverter; import google.registry.model.contact.ContactHistory; @@ -54,7 +53,6 @@ public final class EntityClasses { BillingEvent.Recurring.class, ContactHistory.class, ContactResource.class, - Cursor.class, DomainBase.class, DomainHistory.class, EntityGroupRoot.class, diff --git a/core/src/main/java/google/registry/model/EppResource.java b/core/src/main/java/google/registry/model/EppResource.java index 4a3493d6e..16e316a65 100644 --- a/core/src/main/java/google/registry/model/EppResource.java +++ b/core/src/main/java/google/registry/model/EppResource.java @@ -57,6 +57,8 @@ import org.joda.time.DateTime; @Access(AccessType.FIELD) // otherwise it'll use the default if the repoId (property) public abstract class EppResource extends BackupGroupRoot implements Buildable { + private static final long serialVersionUID = -252782773382339534L; + /** * Unique identifier in the registry for this resource. * @@ -102,13 +104,13 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable { * The time when this resource was created. * *

Map the method to XML, not the field, because if we map the field (with an adaptor class) it - * will never be omitted from the xml even if the timestamp inside creationTime is null and we + * will never be omitted from the xml even if the timestamp inside creationTime is null, and we * return null from the adaptor (instead it gets written as an empty tag). * *

This can be null in the case of pre-Registry-3.0-migration history objects with null * resource fields. */ - @AttributeOverrides({@AttributeOverride(name = "creationTime", column = @Column())}) + @AttributeOverrides(@AttributeOverride(name = "creationTime", column = @Column)) @Index CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null); @@ -199,6 +201,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable { public abstract String getForeignKey(); /** Create the VKey for the specified EPP resource. */ + @Override public abstract VKey createVKey(); /** Override of {@link Buildable#asBuilder} so that the extra methods are visible. */ diff --git a/core/src/main/java/google/registry/model/common/Cursor.java b/core/src/main/java/google/registry/model/common/Cursor.java index 7f28adc54..a050590cd 100644 --- a/core/src/main/java/google/registry/model/common/Cursor.java +++ b/core/src/main/java/google/registry/model/common/Cursor.java @@ -16,60 +16,52 @@ package google.registry.model.common; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.util.DateTimeUtils.START_OF_TIME; -import com.google.common.base.Splitter; -import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Entity; -import com.googlecode.objectify.annotation.Id; -import com.googlecode.objectify.annotation.Ignore; -import com.googlecode.objectify.annotation.OnLoad; -import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.UnsafeSerializable; import google.registry.model.UpdateAutoTimestamp; -import google.registry.model.annotations.InCrossTld; import google.registry.model.common.Cursor.CursorId; import google.registry.model.tld.Registry; import google.registry.persistence.VKey; -import java.util.List; import java.util.Optional; import javax.persistence.Column; +import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.Id; import javax.persistence.IdClass; -import javax.persistence.PostLoad; -import javax.persistence.Transient; import org.joda.time.DateTime; /** - * Shared entity for date cursors. This type supports both "scoped" cursors (i.e. per resource of a - * given type, such as a TLD) and global (i.e. one per environment) cursors, defined internally as - * scoped on {@link EntityGroupRoot}. + * Shared entity for date cursors. + * + *

This type supports both "scoped" cursors (i.e. one per TLD) and global (i.e. one per + * environment) cursors. */ @Entity -@javax.persistence.Entity @IdClass(CursorId.class) -@InCrossTld public class Cursor extends ImmutableObject implements UnsafeSerializable { + private static final long serialVersionUID = 5777891565780594961L; + /** The scope of a global cursor. A global cursor is a cursor that is not specific to one tld. */ public static final String GLOBAL = "GLOBAL"; + /** The types of cursors, used as the string id field for each cursor in Datastore. */ public enum CursorType { /** Cursor for ensuring rolling transactional isolation of BRDA staging operation. */ - BRDA(Registry.class), + BRDA(true), /** Cursor for ensuring rolling transactional isolation of RDE report operation. */ - RDE_REPORT(Registry.class), + RDE_REPORT(true), /** Cursor for ensuring rolling transactional isolation of RDE staging operation. */ - RDE_STAGING(Registry.class), + RDE_STAGING(true), /** Cursor for ensuring rolling transactional isolation of RDE upload operation. */ - RDE_UPLOAD(Registry.class), + RDE_UPLOAD(true), /** * Cursor that tracks the last time we talked to the escrow provider's SFTP server for a given @@ -84,67 +76,47 @@ public class Cursor extends ImmutableObject implements UnsafeSerializable { * action will fail with a status code above 300 and App Engine will keep retrying the action * until it's ready. */ - RDE_UPLOAD_SFTP(Registry.class), + RDE_UPLOAD_SFTP(true), /** - * Cursor for ensuring rolling transactional isolation of recurring billing expansion. The - * value of this cursor represents the exclusive upper bound on the range of billing times - * for which Recurring billing events have been expanded (i.e. the inclusive first billing time - * for the next expansion job). + * Cursor for ensuring rolling transactional isolation of recurring billing expansion. The value + * of this cursor represents the exclusive upper bound on the range of billing times for which + * Recurring billing events have been expanded (i.e. the inclusive first billing time for the + * next expansion job). */ - RECURRING_BILLING(EntityGroupRoot.class), + RECURRING_BILLING(false), /** * Cursor for {@link google.registry.export.sheet.SyncRegistrarsSheetAction}. The DateTime * stored is the last time that registrar changes were successfully synced to the sheet. If * there were no changes since the last time the action run, the cursor is not updated. */ - SYNC_REGISTRAR_SHEET(EntityGroupRoot.class), + SYNC_REGISTRAR_SHEET(false), /** Cursor for tracking monthly uploads of ICANN transaction reports. */ - ICANN_UPLOAD_TX(Registry.class), + ICANN_UPLOAD_TX(true), /** Cursor for tracking monthly uploads of ICANN activity reports. */ - ICANN_UPLOAD_ACTIVITY(Registry.class), + ICANN_UPLOAD_ACTIVITY(true); - // TODO(sarahbot) Delete this cursor once all data in the database that refers to it is removed. - /** Cursor for tracking monthly uploads of MANIFEST.txt to ICANN. No longer used. */ - @Deprecated - ICANN_UPLOAD_MANIFEST(EntityGroupRoot.class); + private final boolean scoped; - /** See the definition of scope on {@link #getScopeClass}. */ - private final Class scope; - - CursorType(Class scope) { - this.scope = scope; + CursorType(boolean scoped) { + this.scoped = scoped; } - /** - * If there are multiple cursors for a given cursor type, a cursor must also have a scope - * defined (distinct from a parent, which is always the EntityGroupRoot key). For instance, for - * a cursor that is defined at the registry level, the scope type will be Registry.class. For a - * cursor (theoretically) defined for each EPP resource, the scope type will be - * EppResource.class. For a global cursor, i.e. one that applies per environment, this will be - * {@link EntityGroupRoot}. - */ - public Class getScopeClass() { - return scope; + public boolean isScoped() { + return scoped; } } - @Transient @Parent Key parent = getCrossTldKey(); - - @Transient @Id String id; - - @Ignore @Enumerated(EnumType.STRING) @Column(nullable = false) - @javax.persistence.Id + @Id CursorType type; - @Ignore @Column(nullable = false) - @javax.persistence.Id + @Id String scope; @Column(nullable = false) @@ -154,27 +126,7 @@ public class Cursor extends ImmutableObject implements UnsafeSerializable { @Column(nullable = false) UpdateAutoTimestamp lastUpdateTime = UpdateAutoTimestamp.create(null); - @OnLoad - void onLoad() { - scope = getScopeFromId(id); - type = getTypeFromId(id); - } - - @PostLoad - void postLoad() { - // "Generate" the ID based on the scope and type - Key scopeKey = - scope.equals(GLOBAL) - ? getCrossTldKey() - : Key.create(getCrossTldKey(), Registry.class, scope); - id = generateId(type, scopeKey); - } - - public static VKey createVKey(Key key) { - String id = key.getName(); - return VKey.create(Cursor.class, new CursorId(getTypeFromId(id), getScopeFromId(id)), key); - } - + @Override public VKey createVKey() { return createVKey(type, scope); } @@ -183,10 +135,13 @@ public class Cursor extends ImmutableObject implements UnsafeSerializable { return createVKey(type, GLOBAL); } - public static VKey createVKey(CursorType type, String scope) { - Key key = - scope.equals(GLOBAL) ? createGlobalKey(type) : createKey(type, Registry.get(scope)); - return VKey.create(Cursor.class, new CursorId(type, scope), key); + public static VKey createScopedVKey(CursorType type, Registry tld) { + return createVKey(type, tld.getTldStr()); + } + + private static VKey createVKey(CursorType type, String scope) { + checkValidCursorTypeForScope(type, scope); + return VKey.createSql(Cursor.class, new CursorId(type, scope)); } public DateTime getLastUpdateTime() { @@ -201,76 +156,42 @@ public class Cursor extends ImmutableObject implements UnsafeSerializable { return type; } - /** - * Checks that the type of the scoped object (or null) matches the required type for the specified - * cursor (or null, if the cursor is a global cursor). - */ - private static void checkValidCursorTypeForScope( - CursorType cursorType, Key scope) { + /** Checks that the specified scope matches the required type for the specified cursor. */ + private static void checkValidCursorTypeForScope(CursorType cursorType, String scope) { + checkNotNull(cursorType, "Cursor type cannot be null"); + checkNotNull(scope, "Cursor scope cannot be null"); checkArgument( - cursorType.getScopeClass().getSimpleName().equals(scope.getKind()), - "Class required for cursor does not match scope class"); - } - - /** Generates a unique ID for a given scope key and cursor type. */ - private static String generateId(CursorType cursorType, Key scope) { - return String.format("%s_%s", scope.getString(), cursorType.name()); - } - - private static String getScopeFromId(String id) { - List idSplit = Splitter.on('_').splitToList(id); - // The key is always either the cross-tld-key or the key of a TLD (whose parent is the - // cross-tld-key). - Key scopeKey = Key.valueOf(idSplit.get(0)); - return scopeKey.getParent() == null ? GLOBAL : scopeKey.getName(); - } - - private static CursorType getTypeFromId(String id) { - List idSplit = Splitter.on('_').splitToList(id); - // The cursor type is the second part of the ID string - return CursorType.valueOf(String.join("_", idSplit.subList(1, idSplit.size()))); - } - - /** Creates a unique key for a given scope and cursor type. */ - public static Key createKey(CursorType cursorType, ImmutableObject scope) { - Key scopeKey = Key.create(scope); - checkValidCursorTypeForScope(cursorType, scopeKey); - return Key.create(getCrossTldKey(), Cursor.class, generateId(cursorType, scopeKey)); - } - - /** Creates a unique key for a given global cursor type. */ - public static Key createGlobalKey(CursorType cursorType) { - checkArgument( - cursorType.getScopeClass().equals(EntityGroupRoot.class), - "Cursor type is not a global cursor."); - return Key.create(getCrossTldKey(), Cursor.class, generateId(cursorType, getCrossTldKey())); + cursorType.isScoped() != scope.equals(GLOBAL), + "Scope %s does not match cursor type %s", + scope, + cursorType); } /** Creates a new global cursor instance. */ public static Cursor createGlobal(CursorType cursorType, DateTime cursorTime) { - return create(cursorType, cursorTime, getCrossTldKey()); + return create(cursorType, cursorTime, GLOBAL); } - /** Creates a new cursor instance with a given {@link Key} scope. */ - private static Cursor create( - CursorType cursorType, DateTime cursorTime, Key scope) { + /** Creates a new cursor instance with a given {@link Registry} scope. */ + public static Cursor createScoped(CursorType cursorType, DateTime cursorTime, Registry scope) { + checkNotNull(scope, "Cursor scope cannot be null"); + return create(cursorType, cursorTime, scope.getTldStr()); + } + + /** + * Creates a new cursor instance with a given TLD scope, or global if the scope is {@link + * #GLOBAL}. + */ + private static Cursor create(CursorType cursorType, DateTime cursorTime, String scope) { + checkNotNull(cursorTime, "Cursor time cannot be null"); + checkValidCursorTypeForScope(cursorType, scope); Cursor instance = new Cursor(); instance.cursorTime = checkNotNull(cursorTime, "Cursor time cannot be null"); - checkNotNull(scope, "Cursor scope cannot be null"); - checkNotNull(cursorType, "Cursor type cannot be null"); - checkValidCursorTypeForScope(cursorType, scope); - instance.id = generateId(cursorType, scope); instance.type = cursorType; - instance.scope = scope.equals(getCrossTldKey()) ? GLOBAL : scope.getName(); + instance.scope = scope; return instance; } - /** Creates a new cursor instance with a given {@link ImmutableObject} scope. */ - public static Cursor create(CursorType cursorType, DateTime cursorTime, ImmutableObject scope) { - checkNotNull(scope, "Cursor scope cannot be null"); - return create(cursorType, cursorTime, Key.create(scope)); - } - /** * Returns the current time for a given cursor, or {@code START_OF_TIME} if the cursor is null. */ @@ -284,9 +205,13 @@ public class Cursor extends ImmutableObject implements UnsafeSerializable { public static class CursorId extends ImmutableObject implements UnsafeSerializable { + private static final long serialVersionUID = -6749584762913095437L; + public CursorType type; public String scope; + // Hibernate requires a no-arg constructor. + @SuppressWarnings("unused") private CursorId() {} public CursorId(CursorType type, String scope) { diff --git a/core/src/main/java/google/registry/model/contact/ContactHistory.java b/core/src/main/java/google/registry/model/contact/ContactHistory.java index 1683133fa..03f8ae351 100644 --- a/core/src/main/java/google/registry/model/contact/ContactHistory.java +++ b/core/src/main/java/google/registry/model/contact/ContactHistory.java @@ -101,6 +101,7 @@ public class ContactHistory extends HistoryEntry implements UnsafeSerializable { /** Creates a {@link VKey} instance for this entity. */ @SuppressWarnings("unchecked") + @Override public VKey createVKey() { return (VKey) createVKey(Key.create(this)); } diff --git a/core/src/main/java/google/registry/model/domain/DomainHistory.java b/core/src/main/java/google/registry/model/domain/DomainHistory.java index 34cb44fac..30b2c5b6c 100644 --- a/core/src/main/java/google/registry/model/domain/DomainHistory.java +++ b/core/src/main/java/google/registry/model/domain/DomainHistory.java @@ -252,6 +252,7 @@ public class DomainHistory extends HistoryEntry { /** Creates a {@link VKey} instance for this entity. */ @SuppressWarnings("unchecked") + @Override public VKey createVKey() { return (VKey) createVKey(Key.create(this)); } diff --git a/core/src/main/java/google/registry/model/domain/token/AllocationToken.java b/core/src/main/java/google/registry/model/domain/token/AllocationToken.java index 5c96f25b1..926b9ff7d 100644 --- a/core/src/main/java/google/registry/model/domain/token/AllocationToken.java +++ b/core/src/main/java/google/registry/model/domain/token/AllocationToken.java @@ -248,6 +248,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable { return renewalPriceBehavior; } + @Override public VKey createVKey() { return VKey.create(AllocationToken.class, getToken(), Key.create(this)); } diff --git a/core/src/main/java/google/registry/model/host/HostHistory.java b/core/src/main/java/google/registry/model/host/HostHistory.java index d7c3a879e..ea40fc322 100644 --- a/core/src/main/java/google/registry/model/host/HostHistory.java +++ b/core/src/main/java/google/registry/model/host/HostHistory.java @@ -102,6 +102,7 @@ public class HostHistory extends HistoryEntry implements UnsafeSerializable { /** Creates a {@link VKey} instance for this entity. */ @SuppressWarnings("unchecked") + @Override public VKey createVKey() { return (VKey) createVKey(Key.create(this)); } diff --git a/core/src/main/java/google/registry/model/registrar/Registrar.java b/core/src/main/java/google/registry/model/registrar/Registrar.java index 05444827c..58bad4722 100644 --- a/core/src/main/java/google/registry/model/registrar/Registrar.java +++ b/core/src/main/java/google/registry/model/registrar/Registrar.java @@ -730,6 +730,7 @@ public class Registrar extends ImmutableObject } /** Creates a {@link VKey} for this instance. */ + @Override public VKey createVKey() { return createVKey(Key.create(this)); } diff --git a/core/src/main/java/google/registry/model/registrar/RegistrarPoc.java b/core/src/main/java/google/registry/model/registrar/RegistrarPoc.java index 8c11d868d..fff09d7d5 100644 --- a/core/src/main/java/google/registry/model/registrar/RegistrarPoc.java +++ b/core/src/main/java/google/registry/model/registrar/RegistrarPoc.java @@ -317,6 +317,7 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe .build(); } + @Override public VKey createVKey() { return VKey.createSql(RegistrarPoc.class, new RegistrarPocId(emailAddress, registrarId)); } diff --git a/core/src/main/java/google/registry/persistence/EppHistoryVKey.java b/core/src/main/java/google/registry/persistence/EppHistoryVKey.java index c69087622..c71cf8b53 100644 --- a/core/src/main/java/google/registry/persistence/EppHistoryVKey.java +++ b/core/src/main/java/google/registry/persistence/EppHistoryVKey.java @@ -96,6 +96,7 @@ public abstract class EppHistoryVKey extends Immutable } /** Creates a {@link VKey} from this instance. */ + @Override public VKey createVKey() { Class vKeyType = new TypeInstantiator(getClass()) {}.getExactType(); return VKey.create(vKeyType, createSqlKey(), createOfyKey()); diff --git a/core/src/main/java/google/registry/rde/BrdaCopyAction.java b/core/src/main/java/google/registry/rde/BrdaCopyAction.java index 0e98a726a..3ad58d99f 100644 --- a/core/src/main/java/google/registry/rde/BrdaCopyAction.java +++ b/core/src/main/java/google/registry/rde/BrdaCopyAction.java @@ -18,7 +18,6 @@ import static google.registry.model.common.Cursor.CursorType.BRDA; import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime; import static google.registry.model.rde.RdeMode.THIN; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.request.Action.Method.POST; import static google.registry.util.DateTimeUtils.isBeforeOrAt; @@ -31,6 +30,7 @@ import google.registry.keyring.api.KeyModule.Key; import google.registry.model.common.Cursor; import google.registry.model.rde.RdeNamingUtils; import google.registry.model.rde.RdeRevision; +import google.registry.model.tld.Registry; import google.registry.request.Action; import google.registry.request.HttpException.NoContentException; import google.registry.request.Parameter; @@ -97,7 +97,8 @@ public final class BrdaCopyAction implements Runnable { // TODO(b/217772483): consider guarding this action with a lock and check if there is work. // Not urgent since file writes on GCS are atomic. Optional cursor = - transactIfJpaTm(() -> tm().loadByKeyIfPresent(Cursor.createVKey(BRDA, tld))); + tm().transact( + () -> tm().loadByKeyIfPresent(Cursor.createScopedVKey(BRDA, Registry.get(tld)))); DateTime brdaCursorTime = getCursorTimeOrStartOfTime(cursor); if (isBeforeOrAt(brdaCursorTime, watermark)) { throw new NoContentException( diff --git a/core/src/main/java/google/registry/rde/EscrowTaskRunner.java b/core/src/main/java/google/registry/rde/EscrowTaskRunner.java index 97643e805..ad3ff4a93 100644 --- a/core/src/main/java/google/registry/rde/EscrowTaskRunner.java +++ b/core/src/main/java/google/registry/rde/EscrowTaskRunner.java @@ -92,9 +92,7 @@ class EscrowTaskRunner { DateTime startOfToday = clock.nowUtc().withTimeAtStartOfDay(); DateTime nextRequiredRun = transactIfJpaTm( - () -> - tm().loadByKeyIfPresent( - Cursor.createVKey(cursorType, registry.getTldStr()))) + () -> tm().loadByKeyIfPresent(Cursor.createScopedVKey(cursorType, registry))) .map(Cursor::getCursorTime) .orElse(startOfToday); if (nextRequiredRun.isAfter(startOfToday)) { @@ -104,7 +102,7 @@ class EscrowTaskRunner { task.runWithLock(nextRequiredRun); DateTime nextRun = nextRequiredRun.plus(interval); logger.atInfo().log("Rolling cursor forward to %s.", nextRun); - tm().transact(() -> tm().put(Cursor.create(cursorType, nextRun, registry))); + tm().transact(() -> tm().put(Cursor.createScoped(cursorType, nextRun, registry))); return null; }; String lockName = String.format("EscrowTaskRunner %s", task.getClass().getSimpleName()); diff --git a/core/src/main/java/google/registry/rde/PendingDepositChecker.java b/core/src/main/java/google/registry/rde/PendingDepositChecker.java index 2df99f707..8fb0a4efe 100644 --- a/core/src/main/java/google/registry/rde/PendingDepositChecker.java +++ b/core/src/main/java/google/registry/rde/PendingDepositChecker.java @@ -92,7 +92,7 @@ public final class PendingDepositChecker { // Avoid creating a transaction unless absolutely necessary. Optional maybeCursor = transactIfJpaTm( - () -> tm().loadByKeyIfPresent(Cursor.createVKey(cursorType, registry.getTldStr()))); + () -> tm().loadByKeyIfPresent(Cursor.createScopedVKey(cursorType, registry))); DateTime cursorValue = maybeCursor.map(Cursor::getCursorTime).orElse(startingPoint); if (isBeforeOrAt(cursorValue, now)) { DateTime watermark = @@ -112,11 +112,11 @@ public final class PendingDepositChecker { return tm().transact( () -> { Optional maybeCursor = - tm().loadByKeyIfPresent(Cursor.createVKey(cursorType, registry.getTldStr())); + tm().loadByKeyIfPresent(Cursor.createScopedVKey(cursorType, registry)); if (maybeCursor.isPresent()) { return maybeCursor.get().getCursorTime(); } - tm().put(Cursor.create(cursorType, initialValue, registry)); + tm().put(Cursor.createScoped(cursorType, initialValue, registry)); return initialValue; }); } diff --git a/core/src/main/java/google/registry/rde/RdeReportAction.java b/core/src/main/java/google/registry/rde/RdeReportAction.java index c906b3503..230479f14 100644 --- a/core/src/main/java/google/registry/rde/RdeReportAction.java +++ b/core/src/main/java/google/registry/rde/RdeReportAction.java @@ -19,7 +19,6 @@ import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8; import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime; import static google.registry.model.rde.RdeMode.FULL; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.request.Action.Method.POST; import static google.registry.util.DateTimeUtils.isBeforeOrAt; @@ -83,8 +82,10 @@ public final class RdeReportAction implements Runnable, EscrowTask { @Override public void runWithLock(DateTime watermark) throws Exception { Optional cursor = - transactIfJpaTm( - () -> tm().loadByKeyIfPresent(Cursor.createVKey(CursorType.RDE_UPLOAD, tld))); + tm().transact( + () -> + tm().loadByKeyIfPresent( + Cursor.createScopedVKey(CursorType.RDE_UPLOAD, Registry.get(tld)))); DateTime cursorTime = getCursorTimeOrStartOfTime(cursor); if (isBeforeOrAt(cursorTime, watermark)) { throw new NoContentException( diff --git a/core/src/main/java/google/registry/rde/RdeUploadAction.java b/core/src/main/java/google/registry/rde/RdeUploadAction.java index f1c6c9af5..2ec0b1565 100644 --- a/core/src/main/java/google/registry/rde/RdeUploadAction.java +++ b/core/src/main/java/google/registry/rde/RdeUploadAction.java @@ -22,7 +22,6 @@ import static google.registry.model.common.Cursor.CursorType.RDE_UPLOAD_SFTP; import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime; import static google.registry.model.rde.RdeMode.FULL; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.rde.RdeModule.RDE_REPORT_QUEUE; import static google.registry.request.Action.Method.POST; import static google.registry.util.DateTimeUtils.START_OF_TIME; @@ -163,7 +162,10 @@ public final class RdeUploadAction implements Runnable, EscrowTask { } logger.atInfo().log("Verifying readiness to upload the RDE deposit."); Optional cursor = - transactIfJpaTm(() -> tm().loadByKeyIfPresent(Cursor.createVKey(RDE_STAGING, tld))); + tm().transact( + () -> + tm().loadByKeyIfPresent( + Cursor.createScopedVKey(RDE_STAGING, Registry.get(tld)))); DateTime stagingCursorTime = getCursorTimeOrStartOfTime(cursor); if (isBeforeOrAt(stagingCursorTime, watermark)) { throw new NoContentException( @@ -173,7 +175,10 @@ public final class RdeUploadAction implements Runnable, EscrowTask { tld, watermark, stagingCursorTime)); } DateTime sftpCursorTime = - transactIfJpaTm(() -> tm().loadByKeyIfPresent(Cursor.createVKey(RDE_UPLOAD_SFTP, tld))) + tm().transact( + () -> + tm().loadByKeyIfPresent( + Cursor.createScopedVKey(RDE_UPLOAD_SFTP, Registry.get(tld)))) .map(Cursor::getCursorTime) .orElse(START_OF_TIME); Duration timeSinceLastSftp = new Duration(sftpCursorTime, clock.nowUtc()); @@ -211,7 +216,7 @@ public final class RdeUploadAction implements Runnable, EscrowTask { tm().transact( () -> tm().put( - Cursor.create( + Cursor.createScoped( RDE_UPLOAD_SFTP, tm().getTransactionTime(), Registry.get(tld)))); response.setContentType(PLAIN_TEXT_UTF_8); response.setPayload(String.format("OK %s %s\n", tld, watermark)); diff --git a/core/src/main/java/google/registry/reporting/icann/IcannReportingUploadAction.java b/core/src/main/java/google/registry/reporting/icann/IcannReportingUploadAction.java index 0db1b8345..2e49849ac 100644 --- a/core/src/main/java/google/registry/reporting/icann/IcannReportingUploadAction.java +++ b/core/src/main/java/google/registry/reporting/icann/IcannReportingUploadAction.java @@ -166,7 +166,7 @@ public final class IcannReportingUploadAction implements Runnable { // Set cursor to first day of next month if the upload succeeded if (success) { Cursor newCursor = - Cursor.create( + Cursor.createScoped( cursorType, cursorTime.withTimeAtStartOfDay().withDayOfMonth(1).plusMonths(1), Registry.get(tldStr)); @@ -227,7 +227,7 @@ public final class IcannReportingUploadAction implements Runnable { private ImmutableMap, Registry> loadKeyMap( ImmutableSet registries, CursorType type) { - return Maps.uniqueIndex(registries, r -> Cursor.createVKey(type, r.getTldStr())); + return Maps.uniqueIndex(registries, r -> Cursor.createScopedVKey(type, r)); } /** @@ -247,7 +247,7 @@ public final class IcannReportingUploadAction implements Runnable { Cursor cursor = cursorMap.getOrDefault( key, - Cursor.create( + Cursor.createScoped( type, clock.nowUtc().withDayOfMonth(1).withTimeAtStartOfDay().plusMonths(1), registry)); diff --git a/core/src/main/java/google/registry/tools/ListCursorsCommand.java b/core/src/main/java/google/registry/tools/ListCursorsCommand.java index c157382c1..0528771db 100644 --- a/core/src/main/java/google/registry/tools/ListCursorsCommand.java +++ b/core/src/main/java/google/registry/tools/ListCursorsCommand.java @@ -57,7 +57,7 @@ final class ListCursorsCommand implements CommandWithRemoteApi { .map(Registry::get) .filter(r -> r.getTldType() == filterTldType) .filter(r -> !filterEscrowEnabled || r.getEscrowEnabled()) - .collect(toImmutableMap(r -> r, r -> Cursor.createVKey(cursorType, r.getTldStr()))); + .collect(toImmutableMap(r -> r, r -> Cursor.createScopedVKey(cursorType, r))); ImmutableMap, Cursor> cursors = transactIfJpaTm(() -> tm().loadByKeysIfPresent(registries.values())); if (!registries.isEmpty()) { diff --git a/core/src/main/java/google/registry/tools/UpdateCursorsCommand.java b/core/src/main/java/google/registry/tools/UpdateCursorsCommand.java index e53d57152..6a6688e04 100644 --- a/core/src/main/java/google/registry/tools/UpdateCursorsCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateCursorsCommand.java @@ -54,7 +54,7 @@ final class UpdateCursorsCommand extends ConfirmingCommand implements CommandWit } else { for (String tld : tlds) { Registry registry = Registry.get(tld); - result.add(Cursor.create(cursorType, newTimestamp, registry)); + result.add(Cursor.createScoped(cursorType, newTimestamp, registry)); } } cursorsToUpdate = result.build(); diff --git a/core/src/nonprod/java/google/registry/tools/GenerateSqlSchemaCommand.java b/core/src/nonprod/java/google/registry/tools/GenerateSqlSchemaCommand.java index 14c440372..dea597191 100644 --- a/core/src/nonprod/java/google/registry/tools/GenerateSqlSchemaCommand.java +++ b/core/src/nonprod/java/google/registry/tools/GenerateSqlSchemaCommand.java @@ -30,9 +30,9 @@ import org.testcontainers.containers.PostgreSQLContainer; /** * Generates a schema for JPA annotated classes using Hibernate. * - *

Note that this isn't complete yet, as all of the persistent classes have not yet been - * converted. After converting a class, a call to "addAnnotatedClass()" for the new class must be - * added to the code below. + *

Note that this isn't complete yet, as all the persistent classes have not yet been converted. + * After converting a class, a call to "addAnnotatedClass()" for the new class must be added to the + * code below. */ @Parameters(separators = " =", commandDescription = "Generate PostgreSQL schema.") public class GenerateSqlSchemaCommand implements Command { @@ -49,7 +49,7 @@ public class GenerateSqlSchemaCommand implements Command { @VisibleForTesting public static final int POSTGRESQL_PORT = 5432; - private PostgreSQLContainer postgresContainer = null; + private PostgreSQLContainer postgresContainer = null; @Parameter( names = {"-o", "--out_file"}, @@ -85,12 +85,12 @@ public class GenerateSqlSchemaCommand implements Command { // Start the container and store the address information. postgresContainer = - new PostgreSQLContainer(NomulusPostgreSql.getDockerTag()) + new PostgreSQLContainer<>(NomulusPostgreSql.getDockerTag()) .withDatabaseName(DB_NAME) .withUsername(DB_USERNAME) .withPassword(DB_PASSWORD); postgresContainer.start(); - databaseHost = postgresContainer.getContainerIpAddress(); + databaseHost = postgresContainer.getHost(); databasePort = postgresContainer.getMappedPort(POSTGRESQL_PORT); } else if (databaseHost == null) { System.err.println( diff --git a/core/src/nonprod/java/google/registry/tools/PostgresqlCommand.java b/core/src/nonprod/java/google/registry/tools/PostgresqlCommand.java index 7a898ab04..f7d81c12b 100644 --- a/core/src/nonprod/java/google/registry/tools/PostgresqlCommand.java +++ b/core/src/nonprod/java/google/registry/tools/PostgresqlCommand.java @@ -34,7 +34,7 @@ public abstract class PostgresqlCommand implements Command { @VisibleForTesting public static final int POSTGRESQL_PORT = 5432; - protected PostgreSQLContainer postgresContainer = null; + protected PostgreSQLContainer postgresContainer = null; @Parameter( names = {"-s", "--start_postgresql"}, @@ -68,7 +68,7 @@ public abstract class PostgresqlCommand implements Command { // Start the container and store the address information. postgresContainer = - new PostgreSQLContainer(NomulusPostgreSql.getDockerTag()) + new PostgreSQLContainer<>(NomulusPostgreSql.getDockerTag()) .withDatabaseName(DB_NAME) .withUsername(DB_USERNAME) .withPassword(DB_PASSWORD); @@ -79,7 +79,7 @@ public abstract class PostgresqlCommand implements Command { return false; } postgresContainer.start(); - databaseHost = postgresContainer.getContainerIpAddress(); + databaseHost = postgresContainer.getHost(); databasePort = postgresContainer.getMappedPort(POSTGRESQL_PORT); } else if (databaseHost == null) { System.err.println( diff --git a/core/src/test/java/google/registry/beam/rde/RdePipelineTest.java b/core/src/test/java/google/registry/beam/rde/RdePipelineTest.java index 29f7a32d3..60f134a0c 100644 --- a/core/src/test/java/google/registry/beam/rde/RdePipelineTest.java +++ b/core/src/test/java/google/registry/beam/rde/RdePipelineTest.java @@ -257,8 +257,8 @@ public class RdePipelineTest { tm().transact( () -> { - tm().put(Cursor.create(CursorType.BRDA, now, Registry.get("soy"))); - tm().put(Cursor.create(RDE_STAGING, now, Registry.get("soy"))); + tm().put(Cursor.createScoped(CursorType.BRDA, now, Registry.get("soy"))); + tm().put(Cursor.createScoped(RDE_STAGING, now, Registry.get("soy"))); RdeRevision.saveRevision("soy", now, THIN, 0); RdeRevision.saveRevision("soy", now, FULL, 0); }); @@ -567,7 +567,9 @@ public class RdePipelineTest { } private static DateTime loadCursorTime(CursorType type) { - return tm().transact(() -> tm().loadByKey(Cursor.createVKey(type, "soy")).getCursorTime()); + return tm().transact( + () -> + tm().loadByKey(Cursor.createScopedVKey(type, Registry.get("soy"))).getCursorTime()); } private static Function getXmlElement(String pattern) { diff --git a/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java b/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java index 9ccc544c1..b6ad69aab 100644 --- a/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java +++ b/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java @@ -61,7 +61,6 @@ public class ClassPathManagerTest { assertThat(ClassPathManager.getClass("Modification")).isEqualTo(Modification.class); assertThat(ClassPathManager.getClass("AllocationToken")).isEqualTo(AllocationToken.class); assertThat(ClassPathManager.getClass("OneTime")).isEqualTo(OneTime.class); - assertThat(ClassPathManager.getClass("Cursor")).isEqualTo(Cursor.class); assertThat(ClassPathManager.getClass("RdeRevision")).isEqualTo(RdeRevision.class); assertThat(ClassPathManager.getClass("HostResource")).isEqualTo(HostResource.class); assertThat(ClassPathManager.getClass("Recurring")).isEqualTo(Recurring.class); @@ -120,7 +119,6 @@ public class ClassPathManagerTest { assertThat(ClassPathManager.getClassName(Modification.class)).isEqualTo("Modification"); assertThat(ClassPathManager.getClassName(AllocationToken.class)).isEqualTo("AllocationToken"); assertThat(ClassPathManager.getClassName(OneTime.class)).isEqualTo("OneTime"); - assertThat(ClassPathManager.getClassName(Cursor.class)).isEqualTo("Cursor"); assertThat(ClassPathManager.getClassName(RdeRevision.class)).isEqualTo("RdeRevision"); assertThat(ClassPathManager.getClassName(HostResource.class)).isEqualTo("HostResource"); assertThat(ClassPathManager.getClassName(Recurring.class)).isEqualTo("Recurring"); diff --git a/core/src/test/java/google/registry/model/common/CursorTest.java b/core/src/test/java/google/registry/model/common/CursorTest.java index a61cdd663..648cac1e2 100644 --- a/core/src/test/java/google/registry/model/common/CursorTest.java +++ b/core/src/test/java/google/registry/model/common/CursorTest.java @@ -19,24 +19,18 @@ import static google.registry.model.common.Cursor.CursorType.BRDA; import static google.registry.model.common.Cursor.CursorType.RDE_UPLOAD; import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; -import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.testing.DatabaseHelper.createTld; -import static google.registry.testing.DatabaseHelper.persistActiveDomain; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static org.junit.jupiter.api.Assertions.assertThrows; import google.registry.model.EntityTestCase; -import google.registry.model.domain.DomainBase; import google.registry.model.tld.Registry; -import google.registry.testing.DualDatabaseTest; -import google.registry.testing.TestOfyAndSql; -import google.registry.testing.TestSqlOnly; import google.registry.util.SerializeUtils; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** Unit tests for {@link Cursor}. */ -@DualDatabaseTest public class CursorTest extends EntityTestCase { public CursorTest() { @@ -48,7 +42,7 @@ public class CursorTest extends EntityTestCase { fakeClock.setTo(DateTime.parse("2010-10-17TZ")); } - @TestSqlOnly + @Test void testSerializable() { final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); tm().transact(() -> tm().put(Cursor.createGlobal(RECURRING_BILLING, time))); @@ -57,22 +51,23 @@ public class CursorTest extends EntityTestCase { assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted); } - @TestOfyAndSql + @Test void testSuccess_persistScopedCursor() { - createTld("tld"); + Registry tld = createTld("tld"); this.fakeClock.advanceOneMilli(); final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); - Cursor cursor = Cursor.create(RDE_UPLOAD, time, Registry.get("tld")); + Cursor cursor = Cursor.createScoped(RDE_UPLOAD, time, tld); tm().transact(() -> tm().put(cursor)); - transactIfJpaTm( - () -> { - assertThat(tm().loadByKeyIfPresent(Cursor.createVKey(BRDA, "tld")).isPresent()).isFalse(); - assertThat(tm().loadByKey(Cursor.createVKey(RDE_UPLOAD, "tld")).getCursorTime()) - .isEqualTo(time); - }); + tm().transact( + () -> { + assertThat(tm().loadByKeyIfPresent(Cursor.createScopedVKey(BRDA, tld)).isPresent()) + .isFalse(); + assertThat(tm().loadByKey(Cursor.createScopedVKey(RDE_UPLOAD, tld)).getCursorTime()) + .isEqualTo(time); + }); } - @TestOfyAndSql + @Test void testSuccess_persistGlobalCursor() { final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); Cursor cursor = Cursor.createGlobal(RECURRING_BILLING, time); @@ -81,86 +76,47 @@ public class CursorTest extends EntityTestCase { .isEqualTo(time); } - @TestOfyAndSql - void testIndexing() throws Exception { - final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); - tm().transact(() -> tm().put(Cursor.createGlobal(RECURRING_BILLING, time))); - Cursor cursor = tm().transact(() -> tm().loadByKey(Cursor.createGlobalVKey(RECURRING_BILLING))); - verifyDatastoreIndexing(cursor); + @Test + void testFailure_VKeyWrongScope() { + Registry tld = createTld("tld"); + assertThrows( + IllegalArgumentException.class, + () -> Cursor.createGlobalVKey(RDE_UPLOAD), + "Scope GLOBAL does not match cursor type RDE_UPLOAD"); + assertThrows( + IllegalArgumentException.class, + () -> Cursor.createScopedVKey(RECURRING_BILLING, tld), + "Scope tld does not match cursor type RECURRING_BILLING"); + assertThrows( + NullPointerException.class, () -> Cursor.createScopedVKey(RECURRING_BILLING, null)); } - @TestOfyAndSql - void testFailure_invalidScopeOnCreate() { - createTld("tld"); - this.fakeClock.advanceOneMilli(); - final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); - final DomainBase domain = persistActiveDomain("notaregistry.tld"); - IllegalArgumentException thrown = - assertThrows( - IllegalArgumentException.class, - () -> Cursor.create(RDE_UPLOAD, time, domain), - domain.getTld()); - assertThat(thrown) - .hasMessageThat() - .contains("Class required for cursor does not match scope class"); - } - - @TestOfyAndSql - void testFailure_invalidScopeOnKeyCreate() { - createTld("tld"); - IllegalArgumentException thrown = - assertThrows( - IllegalArgumentException.class, - () -> Cursor.createKey(RDE_UPLOAD, persistActiveDomain("notaregistry.tld"))); - assertThat(thrown) - .hasMessageThat() - .contains("Class required for cursor does not match scope class"); - } - - @TestOfyAndSql - void testFailure_createGlobalKeyForScopedCursorType() { - IllegalArgumentException thrown = - assertThrows(IllegalArgumentException.class, () -> Cursor.createGlobalKey(RDE_UPLOAD)); - assertThat(thrown).hasMessageThat().contains("Cursor type is not a global cursor"); - } - - @TestOfyAndSql - void testFailure_invalidScopeOnGlobalKeyCreate() { - createTld("tld"); - IllegalArgumentException thrown = - assertThrows( - IllegalArgumentException.class, - () -> Cursor.createKey(RECURRING_BILLING, persistActiveDomain("notaregistry.tld"))); - assertThat(thrown) - .hasMessageThat() - .contains("Class required for cursor does not match scope class"); - } - - @TestOfyAndSql + @Test void testFailure_nullScope() { NullPointerException thrown = assertThrows( NullPointerException.class, - () -> Cursor.create(RECURRING_BILLING, START_OF_TIME, null)); + () -> Cursor.createScoped(RECURRING_BILLING, START_OF_TIME, null)); assertThat(thrown).hasMessageThat().contains("Cursor scope cannot be null"); } - @TestOfyAndSql + @Test void testFailure_nullCursorType() { createTld("tld"); NullPointerException thrown = assertThrows( NullPointerException.class, - () -> Cursor.create(null, START_OF_TIME, Registry.get("tld"))); + () -> Cursor.createScoped(null, START_OF_TIME, Registry.get("tld"))); assertThat(thrown).hasMessageThat().contains("Cursor type cannot be null"); } - @TestOfyAndSql + @Test void testFailure_nullTime() { createTld("tld"); NullPointerException thrown = assertThrows( - NullPointerException.class, () -> Cursor.create(RDE_UPLOAD, null, Registry.get("tld"))); + NullPointerException.class, + () -> Cursor.createScoped(RDE_UPLOAD, null, Registry.get("tld"))); assertThat(thrown).hasMessageThat().contains("Cursor time cannot be null"); } } diff --git a/core/src/test/java/google/registry/persistence/BillingVKeyTest.java b/core/src/test/java/google/registry/persistence/BillingVKeyTest.java index bb915220f..95024b539 100644 --- a/core/src/test/java/google/registry/persistence/BillingVKeyTest.java +++ b/core/src/test/java/google/registry/persistence/BillingVKeyTest.java @@ -106,6 +106,7 @@ class BillingVKeyTest { return billingRecurrenceVKey.createVKey(); } + @Override public VKey createVKey() { return VKey.createSql(BillingVKeyTestEntity.class, id); } diff --git a/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java b/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java index d3199c686..5590f974e 100644 --- a/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java +++ b/core/src/test/java/google/registry/persistence/DomainHistoryVKeyTest.java @@ -96,6 +96,7 @@ class DomainHistoryVKeyTest { this.domainHistoryVKey = domainHistoryVKey; } + @Override public VKey createVKey() { return VKey.createSql(TestEntity.class, id); } diff --git a/core/src/test/java/google/registry/rde/BrdaCopyActionTest.java b/core/src/test/java/google/registry/rde/BrdaCopyActionTest.java index 3e35fa299..ef05f7f74 100644 --- a/core/src/test/java/google/registry/rde/BrdaCopyActionTest.java +++ b/core/src/test/java/google/registry/rde/BrdaCopyActionTest.java @@ -125,13 +125,13 @@ public class BrdaCopyActionTest { () -> { RdeRevision.saveRevision("lol", DateTime.parse("2010-10-17TZ"), RdeMode.THIN, 0); }); - persistResource(Cursor.create(BRDA, action.watermark.plusDays(1), Registry.get("lol"))); + persistResource(Cursor.createScoped(BRDA, action.watermark.plusDays(1), Registry.get("lol"))); } @ParameterizedTest @ValueSource(strings = {"", "job-name/"}) void testRun_stagingNotFinished_throws204(String prefix) throws Exception { - persistResource(Cursor.create(BRDA, action.watermark, Registry.get("lol"))); + persistResource(Cursor.createScoped(BRDA, action.watermark, Registry.get("lol"))); NoContentException thrown = assertThrows(NoContentException.class, () -> runAction(prefix)); assertThat(thrown) .hasMessageThat() diff --git a/core/src/test/java/google/registry/rde/EscrowTaskRunnerTest.java b/core/src/test/java/google/registry/rde/EscrowTaskRunnerTest.java index eb4ad7d69..fd06eecf3 100644 --- a/core/src/test/java/google/registry/rde/EscrowTaskRunnerTest.java +++ b/core/src/test/java/google/registry/rde/EscrowTaskRunnerTest.java @@ -77,12 +77,12 @@ public class EscrowTaskRunnerTest { void testRun_cursorIsToday_advancesCursorToTomorrow() throws Exception { clock.setTo(DateTime.parse("2006-06-06T00:30:00Z")); persistResource( - Cursor.create(CursorType.RDE_STAGING, DateTime.parse("2006-06-06TZ"), registry)); + Cursor.createScoped(CursorType.RDE_STAGING, DateTime.parse("2006-06-06TZ"), registry)); runner.lockRunAndRollForward( task, registry, standardSeconds(30), CursorType.RDE_STAGING, standardDays(1)); verify(task).runWithLock(DateTime.parse("2006-06-06TZ")); tm().clearSessionCache(); - Cursor cursor = loadByKey(Cursor.createVKey(CursorType.RDE_STAGING, registry.getTldStr())); + Cursor cursor = loadByKey(Cursor.createScopedVKey(CursorType.RDE_STAGING, registry)); assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-06-07TZ")); } @@ -92,7 +92,7 @@ public class EscrowTaskRunnerTest { runner.lockRunAndRollForward( task, registry, standardSeconds(30), CursorType.RDE_STAGING, standardDays(1)); verify(task).runWithLock(DateTime.parse("2006-06-06TZ")); - Cursor cursor = loadByKey(Cursor.createVKey(CursorType.RDE_STAGING, "lol")); + Cursor cursor = loadByKey(Cursor.createScopedVKey(CursorType.RDE_STAGING, registry)); assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-06-07TZ")); } @@ -100,7 +100,7 @@ public class EscrowTaskRunnerTest { void testRun_cursorInTheFuture_doesNothing() { clock.setTo(DateTime.parse("2006-06-06T00:30:00Z")); persistResource( - Cursor.create(CursorType.RDE_STAGING, DateTime.parse("2006-06-07TZ"), registry)); + Cursor.createScoped(CursorType.RDE_STAGING, DateTime.parse("2006-06-07TZ"), registry)); NoContentException thrown = assertThrows( NoContentException.class, @@ -115,7 +115,7 @@ public class EscrowTaskRunnerTest { String lockName = "EscrowTaskRunner " + task.getClass().getSimpleName(); clock.setTo(DateTime.parse("2006-06-06T00:30:00Z")); persistResource( - Cursor.create(CursorType.RDE_STAGING, DateTime.parse("2006-06-06TZ"), registry)); + Cursor.createScoped(CursorType.RDE_STAGING, DateTime.parse("2006-06-06TZ"), registry)); runner.lockHandler = new FakeLockHandler(false); ServiceUnavailableException thrown = assertThrows( diff --git a/core/src/test/java/google/registry/rde/PendingDepositCheckerTest.java b/core/src/test/java/google/registry/rde/PendingDepositCheckerTest.java index 14d1b6e64..6dcf7af53 100644 --- a/core/src/test/java/google/registry/rde/PendingDepositCheckerTest.java +++ b/core/src/test/java/google/registry/rde/PendingDepositCheckerTest.java @@ -101,10 +101,9 @@ public class PendingDepositCheckerTest { createTldWithEscrowEnabled("lol"); clock.advanceOneMilli(); Registry registry = Registry.get("lol"); - Truth8.assertThat(loadByKeyIfPresent(Cursor.createVKey(RDE_STAGING, registry.getTldStr()))) - .isEmpty(); + Truth8.assertThat(loadByKeyIfPresent(Cursor.createScopedVKey(RDE_STAGING, registry))).isEmpty(); checker.getTldsAndWatermarksPendingDepositForRdeAndBrda(); - assertThat(loadByKey(Cursor.createVKey(RDE_STAGING, registry.getTldStr())).getCursorTime()) + assertThat(loadByKey(Cursor.createScopedVKey(RDE_STAGING, registry)).getCursorTime()) .isEqualTo(DateTime.parse("2000-01-01TZ")); } @@ -117,7 +116,7 @@ public class PendingDepositCheckerTest { setCursor(Registry.get("lol"), RDE_STAGING, yesterday); clock.advanceOneMilli(); checker.getTldsAndWatermarksPendingDepositForRdeAndBrda(); - Cursor cursor = loadByKey(Cursor.createVKey(RDE_STAGING, "lol")); + Cursor cursor = loadByKey(Cursor.createScopedVKey(RDE_STAGING, Registry.get("lol"))); assertThat(cursor.getCursorTime()).isEqualTo(yesterday); } @@ -129,9 +128,9 @@ public class PendingDepositCheckerTest { clock.advanceOneMilli(); setCursor(registry, RDE_STAGING, DateTime.parse("2000-01-02TZ")); // assume rde is already done clock.advanceOneMilli(); - Truth8.assertThat(loadByKeyIfPresent(Cursor.createVKey(BRDA, registry.getTldStr()))).isEmpty(); + Truth8.assertThat(loadByKeyIfPresent(Cursor.createScopedVKey(BRDA, registry))).isEmpty(); assertThat(checker.getTldsAndWatermarksPendingDepositForRdeAndBrda()).isEmpty(); - Truth8.assertThat(loadByKeyIfPresent(Cursor.createVKey(BRDA, registry.getTldStr()))).isEmpty(); + Truth8.assertThat(loadByKeyIfPresent(Cursor.createScopedVKey(BRDA, registry))).isEmpty(); } @TestOfyAndSql @@ -171,7 +170,7 @@ public class PendingDepositCheckerTest { private static void setCursor( final Registry registry, final CursorType cursorType, final DateTime value) { - tm().transact(() -> tm().put(Cursor.create(cursorType, value, registry))); + tm().transact(() -> tm().put(Cursor.createScoped(cursorType, value, registry))); } private static void createTldWithEscrowEnabled(final String tld) { diff --git a/core/src/test/java/google/registry/rde/RdeReportActionTest.java b/core/src/test/java/google/registry/rde/RdeReportActionTest.java index b672ee4c1..2b290feef 100644 --- a/core/src/test/java/google/registry/rde/RdeReportActionTest.java +++ b/core/src/test/java/google/registry/rde/RdeReportActionTest.java @@ -97,6 +97,7 @@ public class RdeReportActionTest { private final GcsUtils gcsUtils = new GcsUtils(LocalStorageHelper.getOptions()); private final BlobId reportFile = BlobId.of("tub", "test_2006-06-06_full_S1_R0-report.xml.ghostryde"); + private Registry registry; private RdeReportAction createAction() { RdeReporter reporter = new RdeReporter(); @@ -120,11 +121,9 @@ public class RdeReportActionTest { @BeforeEach void beforeEach() throws Exception { - createTld("test"); - persistResource( - Cursor.create(RDE_REPORT, DateTime.parse("2006-06-06TZ"), Registry.get("test"))); - persistResource( - Cursor.create(RDE_UPLOAD, DateTime.parse("2006-06-07TZ"), Registry.get("test"))); + registry = createTld("test"); + persistResource(Cursor.createScoped(RDE_REPORT, DateTime.parse("2006-06-06TZ"), registry)); + persistResource(Cursor.createScoped(RDE_UPLOAD, DateTime.parse("2006-06-07TZ"), registry)); gcsUtils.createFromBytes(reportFile, Ghostryde.encode(REPORT_XML.read(), encryptKey)); tm().transact(() -> RdeRevision.saveRevision("test", DateTime.parse("2006-06-06TZ"), FULL, 0)); } @@ -211,7 +210,7 @@ public class RdeReportActionTest { } void testRunWithLock_nonexistentCursor_throws204() { - tm().transact(() -> tm().delete(Cursor.createVKey(RDE_UPLOAD, "test"))); + tm().transact(() -> tm().delete(Cursor.createScopedVKey(RDE_UPLOAD, Registry.get("test")))); NoContentException thrown = assertThrows( NoContentException.class, () -> createAction().runWithLock(loadRdeReportCursor())); @@ -225,7 +224,7 @@ public class RdeReportActionTest { @TestOfyAndSql void testRunWithLock_uploadNotFinished_throws204() { persistResource( - Cursor.create(RDE_UPLOAD, DateTime.parse("2006-06-06TZ"), Registry.get("test"))); + Cursor.createScoped(RDE_UPLOAD, DateTime.parse("2006-06-06TZ"), Registry.get("test"))); NoContentException thrown = assertThrows( NoContentException.class, () -> createAction().runWithLock(loadRdeReportCursor())); @@ -270,7 +269,7 @@ public class RdeReportActionTest { } private DateTime loadRdeReportCursor() { - return loadByKey(Cursor.createVKey(RDE_REPORT, "test")).getCursorTime(); + return loadByKey(Cursor.createScopedVKey(RDE_REPORT, registry)).getCursorTime(); } private static ImmutableMap mapifyHeaders(Iterable headers) { diff --git a/core/src/test/java/google/registry/rde/RdeStagingActionTest.java b/core/src/test/java/google/registry/rde/RdeStagingActionTest.java index 6f2666ef3..dbf060217 100644 --- a/core/src/test/java/google/registry/rde/RdeStagingActionTest.java +++ b/core/src/test/java/google/registry/rde/RdeStagingActionTest.java @@ -43,7 +43,7 @@ import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.RegisterExtension; -/** Unit tests for {@link RdeStagingAction} in Cloud SQL. */ +/** Unit tests for {@link RdeStagingAction}. */ @DualDatabaseTest public class RdeStagingActionTest extends BeamActionTestBase { diff --git a/core/src/test/java/google/registry/rde/RdeUploadActionTest.java b/core/src/test/java/google/registry/rde/RdeUploadActionTest.java index 5c53a5f3a..00c87b889 100644 --- a/core/src/test/java/google/registry/rde/RdeUploadActionTest.java +++ b/core/src/test/java/google/registry/rde/RdeUploadActionTest.java @@ -267,7 +267,7 @@ public class RdeUploadActionTest { URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); RdeUploadAction action = createAction(uploadUrl); action.lazyJsch = Lazies.of(createThrowingJSchSpy(action.lazyJsch.get(), 2)); action.runWithLock(uploadCursor); @@ -286,7 +286,7 @@ public class RdeUploadActionTest { URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); RdeUploadAction action = createAction(uploadUrl); action.lazyJsch = Lazies.of(createThrowingJSchSpy(action.lazyJsch.get(), 3)); RuntimeException thrown = @@ -300,7 +300,7 @@ public class RdeUploadActionTest { URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); gcsUtils.delete(GHOSTRYDE_FILE_WITH_PREFIX); gcsUtils.delete(LENGTH_FILE_WITH_PREFIX); gcsUtils.delete(REPORT_FILE_WITH_PREFIX); @@ -320,7 +320,7 @@ public class RdeUploadActionTest { URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); gcsUtils.delete(GHOSTRYDE_FILE_WITH_PREFIX); gcsUtils.delete(LENGTH_FILE_WITH_PREFIX); gcsUtils.delete(REPORT_FILE_WITH_PREFIX); @@ -345,7 +345,7 @@ public class RdeUploadActionTest { URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); RdeUploadAction action = createAction(uploadUrl); action.prefix = Optional.of(JOB_PREFIX + "-job-name/"); gcsUtils.delete(GHOSTRYDE_FILE); @@ -374,7 +374,7 @@ public class RdeUploadActionTest { URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); RdeUploadAction action = createAction(uploadUrl); gcsUtils.delete(GHOSTRYDE_FILE); gcsUtils.delete(LENGTH_FILE); @@ -415,7 +415,7 @@ public class RdeUploadActionTest { URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistSimpleResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistSimpleResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); BlobId ghostrydeR1FileWithPrefix = BlobId.of("bucket", JOB_PREFIX + "-job-name/tld_2010-10-17_full_S1_R1.xml.ghostryde"); BlobId lengthR1FileWithPrefix = @@ -446,7 +446,7 @@ public class RdeUploadActionTest { URI uploadUrl = URI.create(String.format("sftp://user:password@localhost:%d/", port)); DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); createAction(uploadUrl).runWithLock(uploadCursor); // Only verify signature for SFTP versions, since we check elsewhere that the GCS files are // identical to the ones sent over SFTP. @@ -484,7 +484,7 @@ public class RdeUploadActionTest { URI url = URI.create("sftp://user:password@localhost:32323/"); DateTime stagingCursor = DateTime.parse("2010-10-17TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); NoContentException thrown = assertThrows(NoContentException.class, () -> createAction(url).runWithLock(uploadCursor)); assertThat(thrown) @@ -501,8 +501,8 @@ public class RdeUploadActionTest { DateTime stagingCursor = DateTime.parse("2010-10-18TZ"); DateTime uploadCursor = DateTime.parse("2010-10-17TZ"); DateTime sftpCursor = uploadCursor.minusMinutes(97); // Within the 2 hour cooldown period. - persistResource(Cursor.create(RDE_STAGING, stagingCursor, Registry.get("tld"))); - persistResource(Cursor.create(RDE_UPLOAD_SFTP, sftpCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_STAGING, stagingCursor, Registry.get("tld"))); + persistResource(Cursor.createScoped(RDE_UPLOAD_SFTP, sftpCursor, Registry.get("tld"))); NoContentException thrown = assertThrows(NoContentException.class, () -> action.runWithLock(uploadCursor)); assertThat(thrown) diff --git a/core/src/test/java/google/registry/reporting/icann/IcannReportingUploadActionTest.java b/core/src/test/java/google/registry/reporting/icann/IcannReportingUploadActionTest.java index ccbb93c19..3bef1d004 100644 --- a/core/src/test/java/google/registry/reporting/icann/IcannReportingUploadActionTest.java +++ b/core/src/test/java/google/registry/reporting/icann/IcannReportingUploadActionTest.java @@ -105,16 +105,16 @@ class IcannReportingUploadActionTest { when(mockReporter.send(PAYLOAD_SUCCESS, "foo-activity-200606.csv")).thenReturn(true); clock.setTo(DateTime.parse("2006-07-05T00:30:00Z")); persistResource( - Cursor.create( + Cursor.createScoped( CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-07-01TZ"), Registry.get("tld"))); persistResource( - Cursor.create( + Cursor.createScoped( CursorType.ICANN_UPLOAD_TX, DateTime.parse("2006-07-01TZ"), Registry.get("tld"))); persistResource( - Cursor.create( + Cursor.createScoped( CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-07-01TZ"), Registry.get("foo"))); persistResource( - Cursor.create( + Cursor.createScoped( CursorType.ICANN_UPLOAD_TX, DateTime.parse("2006-07-01TZ"), Registry.get("foo"))); loggerToIntercept.addHandler(logHandler); } @@ -146,10 +146,10 @@ class IcannReportingUploadActionTest { void testSuccess_january() throws Exception { clock.setTo(DateTime.parse("2006-01-22T00:30:00Z")); persistResource( - Cursor.create( + Cursor.createScoped( CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-01-01TZ"), Registry.get("tld"))); persistResource( - Cursor.create( + Cursor.createScoped( CursorType.ICANN_UPLOAD_TX, DateTime.parse("2006-01-01TZ"), Registry.get("tld"))); gcsUtils.createFromBytes( BlobId.of("basin/icann/monthly/2005-12", "tld-transactions-200512.csv"), PAYLOAD_SUCCESS); @@ -183,7 +183,8 @@ class IcannReportingUploadActionTest { IcannReportingUploadAction action = createAction(); action.run(); tm().clearSessionCache(); - Cursor cursor = loadByKey(Cursor.createVKey(CursorType.ICANN_UPLOAD_ACTIVITY, "tld")); + Cursor cursor = + loadByKey(Cursor.createScopedVKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("tld"))); assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-08-01TZ")); } @@ -241,7 +242,8 @@ class IcannReportingUploadActionTest { runTest_nonRetryableException( new IOException("Your IP address 25.147.130.158 is not allowed to connect")); tm().clearSessionCache(); - Cursor cursor = loadByKey(Cursor.createVKey(CursorType.ICANN_UPLOAD_ACTIVITY, "tld")); + Cursor cursor = + loadByKey(Cursor.createScopedVKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("tld"))); assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ")); } @@ -251,7 +253,8 @@ class IcannReportingUploadActionTest { IcannReportingUploadAction action = createAction(); action.run(); tm().clearSessionCache(); - Cursor cursor = loadByKey(Cursor.createVKey(CursorType.ICANN_UPLOAD_ACTIVITY, "foo")); + Cursor cursor = + loadByKey(Cursor.createScopedVKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("foo"))); assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ")); verifyNoMoreInteractions(mockReporter); } @@ -286,7 +289,7 @@ class IcannReportingUploadActionTest { void testFail_fileNotFound() throws Exception { clock.setTo(DateTime.parse("2006-01-22T00:30:00Z")); persistResource( - Cursor.create( + Cursor.createScoped( CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-01-01TZ"), Registry.get("tld"))); IcannReportingUploadAction action = createAction(); action.run(); @@ -302,7 +305,7 @@ class IcannReportingUploadActionTest { @TestOfyAndSql void testWarning_fileNotStagedYet() throws Exception { persistResource( - Cursor.create( + Cursor.createScoped( CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-08-01TZ"), Registry.get("foo"))); clock.setTo(DateTime.parse("2006-08-01T00:30:00Z")); IcannReportingUploadAction action = createAction(); @@ -352,9 +355,10 @@ class IcannReportingUploadActionTest { new InternetAddress("sender@example.com"))); Cursor newActivityCursor = - loadByKey(Cursor.createVKey(CursorType.ICANN_UPLOAD_ACTIVITY, "new")); + loadByKey(Cursor.createScopedVKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("new"))); assertThat(newActivityCursor.getCursorTime()).isEqualTo(DateTime.parse("2006-08-01TZ")); - Cursor newTransactionCursor = loadByKey(Cursor.createVKey(CursorType.ICANN_UPLOAD_TX, "new")); + Cursor newTransactionCursor = + loadByKey(Cursor.createScopedVKey(CursorType.ICANN_UPLOAD_TX, Registry.get("new"))); assertThat(newTransactionCursor.getCursorTime()).isEqualTo(DateTime.parse("2006-08-01TZ")); } } diff --git a/core/src/test/java/google/registry/testing/DatabaseHelper.java b/core/src/test/java/google/registry/testing/DatabaseHelper.java index 77ef9263d..ec356cd57 100644 --- a/core/src/test/java/google/registry/testing/DatabaseHelper.java +++ b/core/src/test/java/google/registry/testing/DatabaseHelper.java @@ -388,12 +388,12 @@ public class DatabaseHelper { } /** Creates and persists a tld. */ - public static void createTld(String tld) { - createTld(tld, GENERAL_AVAILABILITY); + public static Registry createTld(String tld) { + return createTld(tld, GENERAL_AVAILABILITY); } - public static void createTld(String tld, String roidSuffix) { - createTld(tld, roidSuffix, ImmutableSortedMap.of(START_OF_TIME, GENERAL_AVAILABILITY)); + public static Registry createTld(String tld, String roidSuffix) { + return createTld(tld, roidSuffix, ImmutableSortedMap.of(START_OF_TIME, GENERAL_AVAILABILITY)); } /** Creates and persists the given TLDs. */ @@ -403,23 +403,25 @@ public class DatabaseHelper { } } - public static void createTld(String tld, TldState tldState) { - createTld(tld, ImmutableSortedMap.of(START_OF_TIME, tldState)); + public static Registry createTld(String tld, TldState tldState) { + return createTld(tld, ImmutableSortedMap.of(START_OF_TIME, tldState)); } - public static void createTld(String tld, ImmutableSortedMap tldStates) { + public static Registry createTld(String tld, ImmutableSortedMap tldStates) { // Coerce the TLD string into a valid ROID suffix. String roidSuffix = Ascii.toUpperCase(tld.replaceFirst(ACE_PREFIX_REGEX, "").replace('.', '_')) .replace('-', '_'); - createTld(tld, roidSuffix.length() > 8 ? roidSuffix.substring(0, 8) : roidSuffix, tldStates); + return createTld( + tld, roidSuffix.length() > 8 ? roidSuffix.substring(0, 8) : roidSuffix, tldStates); } - public static void createTld( + public static Registry createTld( String tld, String roidSuffix, ImmutableSortedMap tldStates) { - persistResource(newRegistry(tld, roidSuffix, tldStates)); + Registry registry = persistResource(newRegistry(tld, roidSuffix, tldStates)); allowRegistrarAccess("TheRegistrar", tld); allowRegistrarAccess("NewRegistrar", tld); + return registry; } public static void deleteTld(String tld) { diff --git a/core/src/test/java/google/registry/testing/DatastoreEntityExtension.java b/core/src/test/java/google/registry/testing/DatastoreEntityExtension.java index fd82019b2..292946e07 100644 --- a/core/src/test/java/google/registry/testing/DatastoreEntityExtension.java +++ b/core/src/test/java/google/registry/testing/DatastoreEntityExtension.java @@ -15,6 +15,7 @@ package google.registry.testing; import google.registry.model.AppEngineEnvironment; +import google.registry.model.annotations.DeleteAfterMigration; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; @@ -37,6 +38,7 @@ import org.junit.jupiter.api.extension.ExtensionContext; * * @see AppEngineEnvironment */ +@DeleteAfterMigration public class DatastoreEntityExtension implements BeforeEachCallback, AfterEachCallback { private final AppEngineEnvironment environment; diff --git a/core/src/test/java/google/registry/tools/ListCursorsCommandTest.java b/core/src/test/java/google/registry/tools/ListCursorsCommandTest.java index 770026564..708c950ab 100644 --- a/core/src/test/java/google/registry/tools/ListCursorsCommandTest.java +++ b/core/src/test/java/google/registry/tools/ListCursorsCommandTest.java @@ -59,7 +59,7 @@ public class ListCursorsCommandTest extends CommandTestCase void testListCursors_twoTldsOneAbsent_printsAbsentAndTimestampSorted() throws Exception { createTlds("foo", "bar"); persistResource( - Cursor.create(CursorType.BRDA, DateTime.parse("1984-12-18TZ"), Registry.get("bar"))); + Cursor.createScoped(CursorType.BRDA, DateTime.parse("1984-12-18TZ"), Registry.get("bar"))); runCommand("--type=BRDA"); assertThat(getStdoutAsLines()) .containsExactly( diff --git a/core/src/test/java/google/registry/tools/UpdateCursorsCommandTest.java b/core/src/test/java/google/registry/tools/UpdateCursorsCommandTest.java index 6c42f12e5..b673b4309 100644 --- a/core/src/test/java/google/registry/tools/UpdateCursorsCommandTest.java +++ b/core/src/test/java/google/registry/tools/UpdateCursorsCommandTest.java @@ -40,13 +40,12 @@ class UpdateCursorsCommandTest extends CommandTestCase { @BeforeEach void beforeEach() { - createTld("foo"); - registry = Registry.get("foo"); + registry = createTld("foo"); } void doUpdateTest() throws Exception { runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo"); - assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "foo")).getCursorTime()) + assertThat(loadByKey(Cursor.createScopedVKey(CursorType.BRDA, registry)).getCursorTime()) .isEqualTo(DateTime.parse("1984-12-18TZ")); String changes = command.prompt(); assertThat(changes) @@ -66,14 +65,13 @@ class UpdateCursorsCommandTest extends CommandTestCase { @TestOfyAndSql void testSuccess_oldValueisEmpty() throws Exception { - assertThat(loadByKeyIfPresent(Cursor.createVKey(CursorType.BRDA, registry.getTldStr()))) - .isEmpty(); + assertThat(loadByKeyIfPresent(Cursor.createScopedVKey(CursorType.BRDA, registry))).isEmpty(); doUpdateTest(); } @TestOfyAndSql void testSuccess_hasOldValue() throws Exception { - persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry)); + persistResource(Cursor.createScoped(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry)); doUpdateTest(); } @@ -92,14 +90,15 @@ class UpdateCursorsCommandTest extends CommandTestCase { @TestOfyAndSql void testSuccess_multipleTlds_hasOldValue() throws Exception { - createTld("bar"); + Registry barRegistry = createTld("bar"); Registry registry2 = Registry.get("bar"); - persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry)); - persistResource(Cursor.create(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry2)); + persistResource(Cursor.createScoped(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry)); + persistResource( + Cursor.createScoped(CursorType.BRDA, DateTime.parse("1950-12-18TZ"), registry2)); runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo", "bar"); - assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "foo")).getCursorTime()) + assertThat(loadByKey(Cursor.createScopedVKey(CursorType.BRDA, registry)).getCursorTime()) .isEqualTo(DateTime.parse("1984-12-18TZ")); - assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "bar")).getCursorTime()) + assertThat(loadByKey(Cursor.createScopedVKey(CursorType.BRDA, barRegistry)).getCursorTime()) .isEqualTo(DateTime.parse("1984-12-18TZ")); String changes = command.prompt(); assertThat(changes) @@ -110,13 +109,13 @@ class UpdateCursorsCommandTest extends CommandTestCase { @TestOfyAndSql void testSuccess_multipleTlds_oldValueisEmpty() throws Exception { - createTld("bar"); - assertThat(loadByKeyIfPresent(Cursor.createVKey(CursorType.BRDA, "foo"))).isEmpty(); - assertThat(loadByKeyIfPresent(Cursor.createVKey(CursorType.BRDA, "bar"))).isEmpty(); + Registry barRegistry = createTld("bar"); + assertThat(loadByKeyIfPresent(Cursor.createScopedVKey(CursorType.BRDA, registry))).isEmpty(); + assertThat(loadByKeyIfPresent(Cursor.createScopedVKey(CursorType.BRDA, barRegistry))).isEmpty(); runCommandForced("--type=brda", "--timestamp=1984-12-18T00:00:00Z", "foo", "bar"); - assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "foo")).getCursorTime()) + assertThat(loadByKey(Cursor.createScopedVKey(CursorType.BRDA, registry)).getCursorTime()) .isEqualTo(DateTime.parse("1984-12-18TZ")); - assertThat(loadByKey(Cursor.createVKey(CursorType.BRDA, "bar")).getCursorTime()) + assertThat(loadByKey(Cursor.createScopedVKey(CursorType.BRDA, barRegistry)).getCursorTime()) .isEqualTo(DateTime.parse("1984-12-18TZ")); String changes = command.prompt(); assertThat(changes) diff --git a/core/src/test/resources/google/registry/export/backup_kinds.txt b/core/src/test/resources/google/registry/export/backup_kinds.txt index 2aa3bb93d..6f4e7dd25 100644 --- a/core/src/test/resources/google/registry/export/backup_kinds.txt +++ b/core/src/test/resources/google/registry/export/backup_kinds.txt @@ -1,7 +1,6 @@ AllocationToken Cancellation ContactResource -Cursor DomainBase EntityGroupRoot EppResourceIndex diff --git a/core/src/test/resources/google/registry/export/crosstld_kinds.txt b/core/src/test/resources/google/registry/export/crosstld_kinds.txt index 54330cf6e..9e8d82286 100644 --- a/core/src/test/resources/google/registry/export/crosstld_kinds.txt +++ b/core/src/test/resources/google/registry/export/crosstld_kinds.txt @@ -1,4 +1,3 @@ -Cursor Registrar Registry ServerSecret diff --git a/core/src/test/resources/google/registry/model/schema.txt b/core/src/test/resources/google/registry/model/schema.txt index 661d81419..399f7b75c 100644 --- a/core/src/test/resources/google/registry/model/schema.txt +++ b/core/src/test/resources/google/registry/model/schema.txt @@ -79,12 +79,6 @@ enum google.registry.model.billing.BillingEvent$RenewalPriceBehavior { NONPREMIUM; SPECIFIED; } -class google.registry.model.common.Cursor { - @Id java.lang.String id; - @Parent com.googlecode.objectify.Key parent; - google.registry.model.UpdateAutoTimestamp lastUpdateTime; - org.joda.time.DateTime cursorTime; -} class google.registry.model.common.EntityGroupRoot { @Id java.lang.String id; google.registry.model.UpdateAutoTimestamp updateTimestamp;