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;