Dual-read RegistryCursor prior to Cursor cutover

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=125057857
This commit is contained in:
ctingue 2016-06-16 07:15:49 -07:00 committed by Ben McIlwain
parent 5a4877805b
commit 3e0963dfdb
2 changed files with 55 additions and 2 deletions

View file

@ -73,8 +73,21 @@ public class RegistryCursor extends ImmutableObject {
DateTime date; DateTime date;
/** Convenience shortcut to load a cursor for a given registry and cursor type. */ /**
* Convenience shortcut to load a cursor (as an {@link Optional}) for a given registry and cursor
* type. Note that this currently reads the new cursor style first, then fails back to the old
* RegistryCursor if the corresponding new style cursor does not exist.
*/
public static Optional<DateTime> load(Registry registry, CursorType cursorType) { public static Optional<DateTime> load(Registry registry, CursorType cursorType) {
Cursor newStyleCursor =
ofy()
.load()
.key(Cursor.createKey(Cursor.CursorType.valueOf(cursorType.name()), registry))
.now();
if (newStyleCursor != null) {
return Optional.of(newStyleCursor.getCursorTime());
}
// New cursor style wasn't found for this TLD and cursor type, so load the old style.
Key<RegistryCursor> key = Key<RegistryCursor> key =
Key.create(Key.create(registry), RegistryCursor.class, cursorType.name()); Key.create(Key.create(registry), RegistryCursor.class, cursorType.name());
RegistryCursor cursor = ofy().load().key(key).now(); RegistryCursor cursor = ofy().load().key(key).now();

View file

@ -23,6 +23,7 @@ import static google.registry.testing.DatastoreHelper.createTld;
import com.googlecode.objectify.VoidWork; import com.googlecode.objectify.VoidWork;
import google.registry.model.EntityTestCase; import google.registry.model.EntityTestCase;
import google.registry.model.common.Cursor;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.Test; import org.junit.Test;
@ -31,7 +32,7 @@ import org.junit.Test;
public class RegistryCursorTest extends EntityTestCase { public class RegistryCursorTest extends EntityTestCase {
@Test @Test
public void test_persistence() { public void testPersistence() {
createTld("tld"); createTld("tld");
clock.advanceOneMilli(); clock.advanceOneMilli();
final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z"); final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z");
@ -43,4 +44,43 @@ public class RegistryCursorTest extends EntityTestCase {
assertThat(RegistryCursor.load(Registry.get("tld"), BRDA)).isAbsent(); assertThat(RegistryCursor.load(Registry.get("tld"), BRDA)).isAbsent();
assertThat(RegistryCursor.load(Registry.get("tld"), RDE_UPLOAD)).hasValue(time); assertThat(RegistryCursor.load(Registry.get("tld"), RDE_UPLOAD)).hasValue(time);
} }
@Test
public void testSuccess_dualRead_newOverOld() {
createTld("tld");
final DateTime newCursorTime = DateTime.parse("2012-07-12T03:30:00.000Z");
final DateTime oldCursorTime = DateTime.parse("2012-07-11T03:30:00.000Z");
ofy().transact(
new VoidWork() {
@Override
public void vrun() {
ofy()
.save()
.entities(
// We can't use RegistryCursor.save() since dual-writing happens there.
RegistryCursor.create(Registry.get("tld"), RDE_UPLOAD, oldCursorTime),
Cursor.create(
Cursor.CursorType.RDE_UPLOAD, newCursorTime, Registry.get("tld")))
.now();
}
});
assertThat(RegistryCursor.load(Registry.get("tld"), RDE_UPLOAD)).hasValue(newCursorTime);
}
@Test
public void testSuccess_dualRead_onlyOld() {
createTld("tld");
final DateTime oldCursorTime = DateTime.parse("2012-07-11T03:30:00.000Z");
ofy().transact(
new VoidWork() {
@Override
public void vrun() {
ofy()
.save()
.entity(RegistryCursor.create(Registry.get("tld"), RDE_UPLOAD, oldCursorTime))
.now();
}
});
assertThat(RegistryCursor.load(Registry.get("tld"), RDE_UPLOAD)).hasValue(oldCursorTime);
}
} }