mirror of
https://github.com/google/nomulus.git
synced 2025-07-08 20:23:24 +02:00
Allow class-specific creation of symmetric VKeys (#625)
* Allow class-specific creation of symmetrict VKeys When translating from a datastore Key to a VKey, see if the "kind" class contains a createVKey(com.googlecode.objectify.Key) static method and if it does, use it to construct a symmetric VKey instead of simply creating an objectify-sided asymmetric VKey. As a test case for this, implement the createVKey() static function for DomainBase. Also, create unit tests for VKeyTranslatorFactory, which continues to house the functionality.
This commit is contained in:
parent
80e6f8ffb7
commit
3a3adcde0c
3 changed files with 114 additions and 8 deletions
|
@ -625,8 +625,11 @@ public class DomainBase extends EppResource
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VKey<DomainBase> createVKey() {
|
public VKey<DomainBase> createVKey() {
|
||||||
// TODO(mmuller): create symmetric keys if we can ever reload both sides.
|
return VKey.create(DomainBase.class, getRepoId(), Key.create(this));
|
||||||
return VKey.createOfy(DomainBase.class, Key.create(this));
|
}
|
||||||
|
|
||||||
|
public static VKey<DomainBase> createVKey(Key key) {
|
||||||
|
return VKey.create(DomainBase.class, key.getName(), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Predicate to determine if a given {@link DesignatedContact} is the registrant. */
|
/** Predicate to determine if a given {@link DesignatedContact} is the registrant. */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package google.registry.model.translators;
|
package google.registry.model.translators;
|
||||||
|
|
||||||
import static com.google.common.base.Functions.identity;
|
import static com.google.common.base.Functions.identity;
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||||
import static google.registry.model.EntityClasses.ALL_CLASSES;
|
import static google.registry.model.EntityClasses.ALL_CLASSES;
|
||||||
|
|
||||||
|
@ -22,6 +23,8 @@ import com.google.appengine.api.datastore.Key;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translator factory for VKey.
|
* Translator factory for VKey.
|
||||||
|
@ -45,17 +48,46 @@ public class VKeyTranslatorFactory extends AbstractSimpleTranslatorFactory<VKey,
|
||||||
super(VKey.class);
|
super(VKey.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create a VKey from a raw datastore key. */
|
||||||
|
public static VKey<?> createVKey(Key datastoreKey) {
|
||||||
|
return createVKey(com.googlecode.objectify.Key.create(datastoreKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a VKey from an objectify Key. */
|
||||||
|
public static <T> VKey<T> createVKey(com.googlecode.objectify.Key<T> key) {
|
||||||
|
if (key == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to create the VKey from its reference type.
|
||||||
|
Class clazz = CLASS_REGISTRY.get(key.getKind());
|
||||||
|
checkArgument(clazz != null, "Unknown Key type: %s", key.getKind());
|
||||||
|
try {
|
||||||
|
Method createVKeyMethod =
|
||||||
|
clazz.getDeclaredMethod("createVKey", com.googlecode.objectify.Key.class);
|
||||||
|
return (VKey<T>) createVKeyMethod.invoke(null, new Object[] {key});
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// Revert to an ofy vkey for now. TODO(mmuller): remove this when all classes with VKeys have
|
||||||
|
// converters.
|
||||||
|
return VKey.createOfy(clazz, key);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
// If we have a createVKey(Key) method with incorrect permissions or that is non-static, this
|
||||||
|
// is probably an error so let's reported.
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a VKey from a URL-safe string representation. */
|
||||||
|
public static VKey<?> createVKey(String urlSafe) {
|
||||||
|
return createVKey(com.googlecode.objectify.Key.create(urlSafe));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SimpleTranslator<VKey, Key> createTranslator() {
|
public SimpleTranslator<VKey, Key> createTranslator() {
|
||||||
return new SimpleTranslator<VKey, Key>() {
|
return new SimpleTranslator<VKey, Key>() {
|
||||||
@Override
|
@Override
|
||||||
public VKey loadValue(Key datastoreValue) {
|
public VKey loadValue(Key datastoreValue) {
|
||||||
// TODO(mmuller): we need to call a method on refClass to also reconstitute the SQL key.
|
return createVKey(datastoreValue);
|
||||||
return datastoreValue == null
|
|
||||||
? null
|
|
||||||
: VKey.createOfy(
|
|
||||||
CLASS_REGISTRY.get(datastoreValue.getKind()),
|
|
||||||
com.googlecode.objectify.Key.create(datastoreValue));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package google.registry.model.translators;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static google.registry.testing.DatastoreHelper.newDomainBase;
|
||||||
|
import static google.registry.testing.DatastoreHelper.persistActiveContact;
|
||||||
|
|
||||||
|
import com.googlecode.objectify.Key;
|
||||||
|
import google.registry.model.domain.DomainBase;
|
||||||
|
import google.registry.model.ofy.CommitLogBucket;
|
||||||
|
import google.registry.persistence.VKey;
|
||||||
|
import google.registry.testing.AppEngineRule;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
public class VKeyTranslatorFactoryTest {
|
||||||
|
|
||||||
|
@RegisterExtension public final AppEngineRule appEngine =
|
||||||
|
AppEngineRule.builder()
|
||||||
|
.withDatastore()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public VKeyTranslatorFactoryTest() {}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEntityWithVKeyCreate() {
|
||||||
|
// Creating an objectify key instead of a datastore key as this should get a correctly formatted
|
||||||
|
// key path.
|
||||||
|
DomainBase domain = newDomainBase("example.com", "ROID-1", persistActiveContact("contact-1"));
|
||||||
|
Key<DomainBase> key = Key.create(domain);
|
||||||
|
VKey<DomainBase> vkey = VKeyTranslatorFactory.createVKey(key);
|
||||||
|
assertThat(vkey.getKind()).isEqualTo(DomainBase.class);
|
||||||
|
assertThat(vkey.getOfyKey()).isEqualTo(key);
|
||||||
|
assertThat(vkey.getSqlKey()).isEqualTo("ROID-1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEntityWithoutVKeyCreate() {
|
||||||
|
CommitLogBucket bucket = new CommitLogBucket.Builder().build();
|
||||||
|
Key<CommitLogBucket> key = Key.create(bucket);
|
||||||
|
VKey<CommitLogBucket> vkey = VKeyTranslatorFactory.createVKey(key);
|
||||||
|
assertThat(vkey.getKind()).isEqualTo(CommitLogBucket.class);
|
||||||
|
assertThat(vkey.getOfyKey()).isEqualTo(key);
|
||||||
|
assertThat(vkey.maybeGetSqlKey().isPresent()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUrlSafeKey() {
|
||||||
|
// Creating an objectify key instead of a datastore key as this should get a correctly formatted
|
||||||
|
// key path.
|
||||||
|
DomainBase domain = newDomainBase("example.com", "ROID-1", persistActiveContact("contact-1"));
|
||||||
|
Key<DomainBase> key = Key.create(domain);
|
||||||
|
VKey<DomainBase> vkey = (VKey<DomainBase>) VKeyTranslatorFactory.createVKey(key.getString());
|
||||||
|
assertThat(vkey.getKind()).isEqualTo(DomainBase.class);
|
||||||
|
assertThat(vkey.getOfyKey()).isEqualTo(key);
|
||||||
|
assertThat(vkey.getSqlKey()).isEqualTo("ROID-1");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue