mirror of
https://github.com/google/nomulus.git
synced 2025-05-22 20:29:36 +02:00
Add a SQL schema to AllocationToken (#763)
* Add a SQL schema to AllocationToken * Respond to CR - rename field in tests - rename allowed_registrar_ids field - remove unnecessary db load in GATC * Add TODO for HistoryEntry vkeys * Run autoformat * V48 -> V49
This commit is contained in:
parent
8ac30a42ed
commit
876d65e232
23 changed files with 352 additions and 45 deletions
|
@ -370,7 +370,8 @@ public class DomainCreateFlow implements TransactionalFlow {
|
|||
if (allocationToken.isPresent()
|
||||
&& TokenType.SINGLE_USE.equals(allocationToken.get().getTokenType())) {
|
||||
entitiesToSave.add(
|
||||
allocationTokenFlowUtils.redeemToken(allocationToken.get(), Key.create(historyEntry)));
|
||||
allocationTokenFlowUtils.redeemToken(
|
||||
allocationToken.get(), HistoryEntry.createVKey(Key.create(historyEntry))));
|
||||
}
|
||||
enqueueTasks(newDomain, hasSignedMarks, hasClaimsNotice);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import google.registry.model.domain.token.AllocationToken.TokenStatus;
|
|||
import google.registry.model.domain.token.AllocationToken.TokenType;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
|
@ -107,7 +108,7 @@ public class AllocationTokenFlowUtils {
|
|||
|
||||
/** Redeems a SINGLE_USE {@link AllocationToken}, returning the redeemed copy. */
|
||||
public AllocationToken redeemToken(
|
||||
AllocationToken token, Key<HistoryEntry> redemptionHistoryEntry) {
|
||||
AllocationToken token, VKey<HistoryEntry> redemptionHistoryEntry) {
|
||||
checkArgument(
|
||||
TokenType.SINGLE_USE.equals(token.getTokenType()),
|
||||
"Only SINGLE_USE tokens can be marked as redeemed");
|
||||
|
@ -124,7 +125,8 @@ public class AllocationTokenFlowUtils {
|
|||
private void validateToken(
|
||||
InternetDomainName domainName, AllocationToken token, String clientId, DateTime now)
|
||||
throws EppException {
|
||||
if (!token.getAllowedClientIds().isEmpty() && !token.getAllowedClientIds().contains(clientId)) {
|
||||
if (!token.getAllowedRegistrarIds().isEmpty()
|
||||
&& !token.getAllowedRegistrarIds().contains(clientId)) {
|
||||
throw new AllocationTokenNotValidForRegistrarException();
|
||||
}
|
||||
if (!token.getAllowedTlds().isEmpty()
|
||||
|
|
|
@ -49,16 +49,32 @@ import google.registry.model.common.TimedTransitionProperty.TimedTransition;
|
|||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithStringVKey;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.Table;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** An entity representing an allocation token. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@WithStringVKey
|
||||
public class AllocationToken extends BackupGroupRoot implements Buildable {
|
||||
@javax.persistence.Entity
|
||||
@Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(
|
||||
columnList = "token",
|
||||
name = "allocation_token_token_idx",
|
||||
unique = true),
|
||||
@javax.persistence.Index(
|
||||
columnList = "domainName",
|
||||
name = "allocation_token_domain_name_idx"),
|
||||
})
|
||||
public class AllocationToken extends BackupGroupRoot implements Buildable, DatastoreAndSqlEntity {
|
||||
|
||||
// Promotions should only move forward, and ENDED / CANCELLED are terminal states.
|
||||
private static final ImmutableMultimap<TokenStatus, TokenStatus> VALID_TOKEN_STATUS_TRANSITIONS =
|
||||
|
@ -86,19 +102,22 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
|||
}
|
||||
|
||||
/** The allocation token string. */
|
||||
@Id String token;
|
||||
@javax.persistence.Id @Id String token;
|
||||
|
||||
/** The key of the history entry for which the token was used. Null if not yet used. */
|
||||
@Nullable @Index Key<HistoryEntry> redemptionHistoryEntry;
|
||||
@Nullable @Index VKey<HistoryEntry> redemptionHistoryEntry;
|
||||
|
||||
/** The fully-qualified domain name that this token is limited to, if any. */
|
||||
@Nullable @Index String domainName;
|
||||
|
||||
/** When this token was created. */
|
||||
@Column(nullable = false)
|
||||
CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
||||
|
||||
/** Allowed registrar client IDs for this token, or null if all registrars are allowed. */
|
||||
@Nullable Set<String> allowedClientIds;
|
||||
@Column(name = "allowedRegistrarIds")
|
||||
@Nullable
|
||||
Set<String> allowedClientIds;
|
||||
|
||||
/** Allowed TLDs for this token, or null if all TLDs are allowed. */
|
||||
@Nullable Set<String> allowedTlds;
|
||||
|
@ -117,6 +136,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
|||
int discountYears = 1;
|
||||
|
||||
/** The type of the token, either single-use or unlimited-use. */
|
||||
@Enumerated(EnumType.STRING)
|
||||
TokenType tokenType;
|
||||
|
||||
// TODO: Remove onLoad once all allocation tokens are migrated to have a discountYears of 1.
|
||||
|
@ -161,7 +181,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
|||
return token;
|
||||
}
|
||||
|
||||
public Optional<Key<HistoryEntry>> getRedemptionHistoryEntry() {
|
||||
public Optional<VKey<HistoryEntry>> getRedemptionHistoryEntry() {
|
||||
return Optional.ofNullable(redemptionHistoryEntry);
|
||||
}
|
||||
|
||||
|
@ -177,7 +197,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
|||
return Optional.ofNullable(creationTime.getTimestamp());
|
||||
}
|
||||
|
||||
public ImmutableSet<String> getAllowedClientIds() {
|
||||
public ImmutableSet<String> getAllowedRegistrarIds() {
|
||||
return nullToEmptyImmutableCopy(allowedClientIds);
|
||||
}
|
||||
|
||||
|
@ -260,7 +280,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setRedemptionHistoryEntry(Key<HistoryEntry> redemptionHistoryEntry) {
|
||||
public Builder setRedemptionHistoryEntry(VKey<HistoryEntry> redemptionHistoryEntry) {
|
||||
getInstance().redemptionHistoryEntry =
|
||||
checkArgumentNotNull(redemptionHistoryEntry, "Redemption history entry must not be null");
|
||||
return this;
|
||||
|
@ -279,8 +299,8 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setAllowedClientIds(Set<String> allowedClientIds) {
|
||||
getInstance().allowedClientIds = forceEmptyToNull(allowedClientIds);
|
||||
public Builder setAllowedRegistrarIds(Set<String> allowedRegistrarIds) {
|
||||
getInstance().allowedClientIds = forceEmptyToNull(allowedRegistrarIds);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import google.registry.model.annotations.ReportedOn;
|
|||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithStringVKey;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.AttributeOverride;
|
||||
|
@ -49,6 +50,7 @@ import org.joda.time.DateTime;
|
|||
@ReportedOn
|
||||
@Entity
|
||||
@MappedSuperclass
|
||||
@WithStringVKey // TODO(b/162229294): This should be resolved during the course of that bug
|
||||
public class HistoryEntry extends ImmutableObject implements Buildable {
|
||||
|
||||
/** Represents the type of history entry. */
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// 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.persistence.converter;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import google.registry.model.common.TimedTransitionProperty;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatus;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatusTransition;
|
||||
import java.util.Map;
|
||||
import javax.persistence.Converter;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* JPA converter for storing/retrieving {@link TimedTransitionProperty} maps referring to {@link
|
||||
* TokenStatus}es.
|
||||
*/
|
||||
@Converter(autoApply = true)
|
||||
public class AllocationTokenStatusTransitionConverter
|
||||
extends TimedTransitionPropertyConverterBase<TokenStatus, TokenStatusTransition> {
|
||||
|
||||
@Override
|
||||
Map.Entry<String, String> convertToDatabaseMapEntry(
|
||||
Map.Entry<DateTime, TokenStatusTransition> entry) {
|
||||
return Maps.immutableEntry(entry.getKey().toString(), entry.getValue().getValue().name());
|
||||
}
|
||||
|
||||
@Override
|
||||
Map.Entry<DateTime, TokenStatus> convertToEntityMapEntry(Map.Entry<String, String> entry) {
|
||||
return Maps.immutableEntry(
|
||||
DateTime.parse(entry.getKey()), TokenStatus.valueOf(entry.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<TokenStatusTransition> getTimedTransitionSubclass() {
|
||||
return TokenStatusTransition.class;
|
||||
}
|
||||
}
|
|
@ -182,7 +182,8 @@ class GenerateAllocationTokensCommand implements CommandWithRemoteApi {
|
|||
new AllocationToken.Builder()
|
||||
.setToken(t)
|
||||
.setTokenType(tokenType == null ? SINGLE_USE : tokenType)
|
||||
.setAllowedClientIds(ImmutableSet.copyOf(nullToEmpty(allowedClientIds)))
|
||||
.setAllowedRegistrarIds(
|
||||
ImmutableSet.copyOf(nullToEmpty(allowedClientIds)))
|
||||
.setAllowedTlds(ImmutableSet.copyOf(nullToEmpty(allowedTlds)));
|
||||
Optional.ofNullable(discountFraction).ifPresent(token::setDiscountFraction);
|
||||
Optional.ofNullable(discountPremiums).ifPresent(token::setDiscountPremiums);
|
||||
|
|
|
@ -16,6 +16,7 @@ package google.registry.tools;
|
|||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
|
@ -59,7 +60,7 @@ final class GetAllocationTokenCommand implements CommandWithRemoteApi {
|
|||
System.out.printf("Token %s was not redeemed.\n", token);
|
||||
} else {
|
||||
DomainBase domain =
|
||||
domains.get(loadedToken.getRedemptionHistoryEntry().get().<DomainBase>getParent());
|
||||
domains.get(loadedToken.getRedemptionHistoryEntry().get().getOfyKey().getParent());
|
||||
if (domain == null) {
|
||||
System.out.printf("ERROR: Token %s was redeemed but domain can't be loaded.\n", token);
|
||||
} else {
|
||||
|
@ -82,7 +83,8 @@ final class GetAllocationTokenCommand implements CommandWithRemoteApi {
|
|||
.map(AllocationToken::getRedemptionHistoryEntry)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.map(Key::<DomainBase>getParent)
|
||||
.map(key -> tm().load(key))
|
||||
.map(he -> (Key<DomainBase>) he.getParent())
|
||||
.collect(toImmutableList());
|
||||
ImmutableMap.Builder<Key<DomainBase>, DomainBase> domainsBuilder = new ImmutableMap.Builder<>();
|
||||
for (List<Key<DomainBase>> keys : Lists.partition(domainKeys, BATCH_SIZE)) {
|
||||
|
|
|
@ -131,7 +131,7 @@ final class UpdateAllocationTokensCommand extends UpdateOrDeleteAllocationTokens
|
|||
private AllocationToken updateToken(AllocationToken original) {
|
||||
AllocationToken.Builder builder = original.asBuilder();
|
||||
Optional.ofNullable(allowedClientIds)
|
||||
.ifPresent(clientIds -> builder.setAllowedClientIds(ImmutableSet.copyOf(clientIds)));
|
||||
.ifPresent(clientIds -> builder.setAllowedRegistrarIds(ImmutableSet.copyOf(clientIds)));
|
||||
Optional.ofNullable(allowedTlds)
|
||||
.ifPresent(tlds -> builder.setAllowedTlds(ImmutableSet.copyOf(tlds)));
|
||||
Optional.ofNullable(discountFraction).ifPresent(builder::setDiscountFraction);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
<class>google.registry.model.contact.ContactResource</class>
|
||||
<class>google.registry.model.domain.DomainBase</class>
|
||||
<class>google.registry.model.domain.DomainHistory</class>
|
||||
<class>google.registry.model.domain.token.AllocationToken</class>
|
||||
<class>google.registry.model.host.HostHistory</class>
|
||||
<class>google.registry.model.host.HostResource</class>
|
||||
<class>google.registry.model.registrar.Registrar</class>
|
||||
|
@ -46,6 +47,7 @@
|
|||
<class>google.registry.model.registry.label.ReservedList</class>
|
||||
|
||||
<!-- Customized type converters -->
|
||||
<class>google.registry.persistence.converter.AllocationTokenStatusTransitionConverter</class>
|
||||
<class>google.registry.persistence.converter.BillingCostTransitionConverter</class>
|
||||
<class>google.registry.persistence.converter.BillingEventFlagSetConverter</class>
|
||||
<class>google.registry.persistence.converter.BloomFilterConverter</class>
|
||||
|
@ -76,6 +78,7 @@
|
|||
<class>google.registry.model.host.VKeyConverter_HostResource</class>
|
||||
<class>google.registry.model.poll.VKeyConverter_Autorenew</class>
|
||||
<class>google.registry.model.poll.VKeyConverter_OneTime</class>
|
||||
<class>google.registry.model.reporting.VKeyConverter_HistoryEntry</class>
|
||||
|
||||
<!-- TODO(weiminyu): check out application-layer validation. -->
|
||||
<validation-mode>NONE</validation-mode>
|
||||
|
|
|
@ -71,6 +71,7 @@ import google.registry.model.registry.Registry;
|
|||
import google.registry.model.registry.Registry.TldState;
|
||||
import google.registry.model.registry.label.ReservedList;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
|
@ -162,12 +163,13 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
|
|||
@Test
|
||||
void testSuccess_oneExists_allocationTokenIsRedeemed() throws Exception {
|
||||
setEppInput("domain_check_allocationtoken.xml");
|
||||
persistActiveDomain("example1.tld");
|
||||
DomainBase domain = persistActiveDomain("example1.tld");
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1L);
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123")
|
||||
.setTokenType(SINGLE_USE)
|
||||
.setRedemptionHistoryEntry(Key.create(HistoryEntry.class, 1L))
|
||||
.setRedemptionHistoryEntry(VKey.create(HistoryEntry.class, 1L, historyEntryKey))
|
||||
.build());
|
||||
doCheckTest(
|
||||
create(false, "example1.tld", "In use"),
|
||||
|
@ -417,7 +419,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
|
|||
.setToken("abc123")
|
||||
.setTokenType(UNLIMITED_USE)
|
||||
.setDiscountFraction(0.5)
|
||||
.setAllowedClientIds(ImmutableSet.of("someOtherClient"))
|
||||
.setAllowedRegistrarIds(ImmutableSet.of("someOtherClient"))
|
||||
.setTokenStatusTransitions(
|
||||
ImmutableSortedMap.<DateTime, TokenStatus>naturalOrder()
|
||||
.put(START_OF_TIME, TokenStatus.NOT_STARTED)
|
||||
|
|
|
@ -162,6 +162,7 @@ import google.registry.model.reporting.DomainTransactionRecord;
|
|||
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.monitoring.whitebox.EppMetric;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
@ -492,11 +493,13 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
|||
"domain_create_allocationtoken.xml",
|
||||
ImmutableMap.of("DOMAIN", "example.tld", "YEARS", "2"));
|
||||
persistContactsAndHosts();
|
||||
DomainBase domain = persistActiveDomain("foo.tld");
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 505L);
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123")
|
||||
.setTokenType(SINGLE_USE)
|
||||
.setRedemptionHistoryEntry(Key.create(HistoryEntry.class, 505L))
|
||||
.setRedemptionHistoryEntry(VKey.create(HistoryEntry.class, 505L, historyEntryKey))
|
||||
.build());
|
||||
clock.advanceOneMilli();
|
||||
EppException thrown =
|
||||
|
@ -519,7 +522,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
|||
HistoryEntry historyEntry =
|
||||
ofy().load().type(HistoryEntry.class).ancestor(reloadResourceByForeignKey()).first().now();
|
||||
assertThat(ofy().load().entity(token).now().getRedemptionHistoryEntry())
|
||||
.hasValue(Key.create(historyEntry));
|
||||
.hasValue(HistoryEntry.createVKey(Key.create(historyEntry)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1263,7 +1266,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
|||
ofy().load().key(Key.create(AllocationToken.class, token)).now();
|
||||
assertThat(reloadedToken.isRedeemed()).isTrue();
|
||||
assertThat(reloadedToken.getRedemptionHistoryEntry())
|
||||
.hasValue(Key.create(getHistoryEntries(reloadResourceByForeignKey()).get(0)));
|
||||
.hasValue(
|
||||
HistoryEntry.createVKey(
|
||||
Key.create(getHistoryEntries(reloadResourceByForeignKey()).get(0))));
|
||||
}
|
||||
|
||||
private void assertAllocationTokenWasNotRedeemed(String token) {
|
||||
|
@ -1498,7 +1503,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
|||
new AllocationToken.Builder()
|
||||
.setToken("abc123")
|
||||
.setTokenType(UNLIMITED_USE)
|
||||
.setAllowedClientIds(ImmutableSet.of("someClientId"))
|
||||
.setAllowedRegistrarIds(ImmutableSet.of("someClientId"))
|
||||
.setDiscountFraction(0.5)
|
||||
.setTokenStatusTransitions(
|
||||
ImmutableSortedMap.<DateTime, TokenStatus>naturalOrder()
|
||||
|
|
|
@ -22,6 +22,7 @@ import static google.registry.model.domain.token.AllocationToken.TokenStatus.VAL
|
|||
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
@ -42,11 +43,13 @@ import google.registry.flows.domain.token.AllocationTokenFlowUtils.AllocationTok
|
|||
import google.registry.flows.domain.token.AllocationTokenFlowUtils.AllocationTokenNotValidForRegistrarException;
|
||||
import google.registry.flows.domain.token.AllocationTokenFlowUtils.AllocationTokenNotValidForTldException;
|
||||
import google.registry.flows.domain.token.AllocationTokenFlowUtils.InvalidAllocationTokenException;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainCommand;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatus;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -127,7 +130,7 @@ class AllocationTokenFlowUtilsTest {
|
|||
void test_validateToken_invalidForClientId() {
|
||||
persistResource(
|
||||
createOneMonthPromoTokenBuilder(DateTime.now(UTC).minusDays(1))
|
||||
.setAllowedClientIds(ImmutableSet.of("NewRegistrar"))
|
||||
.setAllowedRegistrarIds(ImmutableSet.of("NewRegistrar"))
|
||||
.build());
|
||||
assertValidateThrowsEppException(AllocationTokenNotValidForRegistrarException.class);
|
||||
}
|
||||
|
@ -189,11 +192,13 @@ class AllocationTokenFlowUtilsTest {
|
|||
|
||||
@Test
|
||||
void test_checkDomainsWithToken_showsFailureMessageForRedeemedToken() {
|
||||
DomainBase domain = persistActiveDomain("example.tld");
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1051L);
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("tokeN")
|
||||
.setTokenType(SINGLE_USE)
|
||||
.setRedemptionHistoryEntry(Key.create(HistoryEntry.class, 101L))
|
||||
.setRedemptionHistoryEntry(VKey.create(HistoryEntry.class, 101L, historyEntryKey))
|
||||
.build());
|
||||
assertThat(
|
||||
flowUtils
|
||||
|
|
|
@ -16,6 +16,7 @@ package google.registry.model.domain.token;
|
|||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth8.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenStatus.CANCELLED;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenStatus.ENDED;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenStatus.NOT_STARTED;
|
||||
|
@ -23,7 +24,9 @@ import static google.registry.model.domain.token.AllocationToken.TokenStatus.VAL
|
|||
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
|
@ -33,15 +36,21 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatus;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenType;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link AllocationToken}. */
|
||||
class AllocationTokenTest extends EntityTestCase {
|
||||
public class AllocationTokenTest extends EntityTestCase {
|
||||
|
||||
public AllocationTokenTest() {
|
||||
super(JpaEntityCoverageCheck.ENABLED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
|
@ -53,11 +62,11 @@ class AllocationTokenTest extends EntityTestCase {
|
|||
AllocationToken unlimitedUseToken =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123")
|
||||
.setToken("abc123Unlimited")
|
||||
.setTokenType(UNLIMITED_USE)
|
||||
.setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z"))
|
||||
.setAllowedTlds(ImmutableSet.of("dev", "app"))
|
||||
.setAllowedClientIds(ImmutableSet.of("TheRegistrar, NewRegistrar"))
|
||||
.setAllowedRegistrarIds(ImmutableSet.of("TheRegistrar, NewRegistrar"))
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountPremiums(true)
|
||||
.setDiscountYears(3)
|
||||
|
@ -70,26 +79,52 @@ class AllocationTokenTest extends EntityTestCase {
|
|||
.build());
|
||||
assertThat(ofy().load().entity(unlimitedUseToken).now()).isEqualTo(unlimitedUseToken);
|
||||
|
||||
DomainBase domain = persistActiveDomain("example.foo");
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1);
|
||||
AllocationToken singleUseToken =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123")
|
||||
.setRedemptionHistoryEntry(Key.create(HistoryEntry.class, 1L))
|
||||
.setToken("abc123Single")
|
||||
.setRedemptionHistoryEntry(HistoryEntry.createVKey(historyEntryKey))
|
||||
.setDomainName("example.foo")
|
||||
.setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z"))
|
||||
.setTokenType(SINGLE_USE)
|
||||
.build());
|
||||
assertThat(ofy().load().entity(singleUseToken).now()).isEqualTo(singleUseToken);
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().saveNew(unlimitedUseToken);
|
||||
jpaTm().saveNew(singleUseToken);
|
||||
});
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
assertAboutImmutableObjects()
|
||||
.that(jpaTm().load(VKey.createSql(AllocationToken.class, "abc123Unlimited")))
|
||||
.isEqualExceptFields(
|
||||
unlimitedUseToken,
|
||||
"creationTime",
|
||||
"updateTimestamp",
|
||||
"redemptionHistoryEntry");
|
||||
assertAboutImmutableObjects()
|
||||
.that(jpaTm().load(VKey.createSql(AllocationToken.class, "abc123Single")))
|
||||
.isEqualExceptFields(
|
||||
singleUseToken, "creationTime", "updateTimestamp", "redemptionHistoryEntry");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndexing() throws Exception {
|
||||
DomainBase domain = persistActiveDomain("blahdomain.foo");
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1);
|
||||
verifyIndexing(
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123")
|
||||
.setTokenType(SINGLE_USE)
|
||||
.setRedemptionHistoryEntry(Key.create(HistoryEntry.class, 1L))
|
||||
.setRedemptionHistoryEntry(VKey.create(HistoryEntry.class, 1L, historyEntryKey))
|
||||
.setDomainName("blahdomain.foo")
|
||||
.setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z"))
|
||||
.build()),
|
||||
|
@ -193,7 +228,7 @@ class AllocationTokenTest extends EntityTestCase {
|
|||
new AllocationToken.Builder()
|
||||
.setToken("foobar")
|
||||
.setTokenType(TokenType.UNLIMITED_USE)
|
||||
.setRedemptionHistoryEntry(Key.create(HistoryEntry.class, "hi"));
|
||||
.setRedemptionHistoryEntry(VKey.create(HistoryEntry.class, 1L));
|
||||
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, builder::build);
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// 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.persistence.converter;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenStatus.ENDED;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenStatus.NOT_STARTED;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenStatus.VALID;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.common.TimedTransitionProperty;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatus;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatusTransition;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
/** Unit tests for {@link AllocationTokenStatusTransitionConverter}. */
|
||||
public class AllocationTokenStatusTransitionConverterTest {
|
||||
|
||||
@RegisterExtension
|
||||
public final JpaUnitTestExtension jpa =
|
||||
new JpaTestRules.Builder()
|
||||
.withInitScript("sql/flyway/V14__load_extension_for_hstore.sql")
|
||||
.withEntityClass(AllocationTokenStatusTransitionConverterTestEntity.class)
|
||||
.buildUnitTestRule();
|
||||
|
||||
private static final ImmutableSortedMap<DateTime, TokenStatus> values =
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
NOT_STARTED,
|
||||
DateTime.parse("2001-01-01T00:00:00.0Z"),
|
||||
VALID,
|
||||
DateTime.parse("2002-01-01T00:00:00.0Z"),
|
||||
ENDED);
|
||||
|
||||
@Test
|
||||
void roundTripConversion_returnsSameTimedTransitionProperty() {
|
||||
TimedTransitionProperty<TokenStatus, TokenStatusTransition> timedTransitionProperty =
|
||||
TimedTransitionProperty.fromValueMap(values, TokenStatusTransition.class);
|
||||
AllocationTokenStatusTransitionConverterTestEntity testEntity =
|
||||
new AllocationTokenStatusTransitionConverterTestEntity(timedTransitionProperty);
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
|
||||
AllocationTokenStatusTransitionConverterTestEntity persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() ->
|
||||
jpaTm()
|
||||
.getEntityManager()
|
||||
.find(AllocationTokenStatusTransitionConverterTestEntity.class, "id"));
|
||||
assertThat(persisted.timedTransitionProperty).containsExactlyEntriesIn(timedTransitionProperty);
|
||||
}
|
||||
|
||||
@Entity
|
||||
private static class AllocationTokenStatusTransitionConverterTestEntity extends ImmutableObject {
|
||||
|
||||
@Id String name = "id";
|
||||
|
||||
TimedTransitionProperty<TokenStatus, TokenStatusTransition> timedTransitionProperty;
|
||||
|
||||
private AllocationTokenStatusTransitionConverterTestEntity() {}
|
||||
|
||||
private AllocationTokenStatusTransitionConverterTestEntity(
|
||||
TimedTransitionProperty<TokenStatus, TokenStatusTransition> timedTransitionProperty) {
|
||||
this.timedTransitionProperty = timedTransitionProperty;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assert_;
|
|||
import google.registry.model.billing.BillingEventTest;
|
||||
import google.registry.model.contact.ContactResourceTest;
|
||||
import google.registry.model.domain.DomainBaseSqlTest;
|
||||
import google.registry.model.domain.token.AllocationTokenTest;
|
||||
import google.registry.model.history.ContactHistoryTest;
|
||||
import google.registry.model.history.DomainHistoryTest;
|
||||
import google.registry.model.history.HostHistoryTest;
|
||||
|
@ -72,6 +73,7 @@ import org.junit.runner.RunWith;
|
|||
@SelectClasses({
|
||||
// BeforeSuiteTest must be the first entry. See class javadoc for details.
|
||||
BeforeSuiteTest.class,
|
||||
AllocationTokenTest.class,
|
||||
BillingEventTest.class,
|
||||
ClaimsListDaoTest.class,
|
||||
ContactHistoryTest.class,
|
||||
|
|
|
@ -18,13 +18,16 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.testing.DatastoreHelper.createTlds;
|
||||
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenType;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.Collection;
|
||||
import javax.annotation.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -167,12 +170,15 @@ class DeleteAllocationTokensCommandTest extends CommandTestCase<DeleteAllocation
|
|||
.setTokenType(SINGLE_USE)
|
||||
.setDomainName(domainName);
|
||||
if (redeemed) {
|
||||
builder.setRedemptionHistoryEntry(Key.create(HistoryEntry.class, 1051L));
|
||||
String domainToPersist = domainName != null ? domainName : "example.foo";
|
||||
DomainBase domain = persistActiveDomain(domainToPersist);
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1051L);
|
||||
builder.setRedemptionHistoryEntry(VKey.create(HistoryEntry.class, 1051L, historyEntryKey));
|
||||
}
|
||||
return persistResource(builder.build());
|
||||
}
|
||||
|
||||
private static Collection<AllocationToken> reloadTokens(AllocationToken ... tokens) {
|
||||
private static Collection<AllocationToken> reloadTokens(AllocationToken... tokens) {
|
||||
return ofy().load().entities(tokens).values();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,10 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.io.Files;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatus;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DeterministicStringGenerator;
|
||||
import google.registry.testing.DeterministicStringGenerator.Rule;
|
||||
import google.registry.testing.FakeClock;
|
||||
|
@ -168,7 +168,7 @@ class GenerateAllocationTokensCommandTest extends CommandTestCase<GenerateAlloca
|
|||
new AllocationToken.Builder()
|
||||
.setToken("promo123456789ABCDEFG")
|
||||
.setTokenType(UNLIMITED_USE)
|
||||
.setAllowedClientIds(ImmutableSet.of("TheRegistrar", "NewRegistrar"))
|
||||
.setAllowedRegistrarIds(ImmutableSet.of("TheRegistrar", "NewRegistrar"))
|
||||
.setAllowedTlds(ImmutableSet.of("tld", "example"))
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountPremiums(true)
|
||||
|
@ -314,7 +314,7 @@ class GenerateAllocationTokensCommandTest extends CommandTestCase<GenerateAlloca
|
|||
|
||||
private AllocationToken createToken(
|
||||
String token,
|
||||
@Nullable Key<HistoryEntry> redemptionHistoryEntry,
|
||||
@Nullable VKey<HistoryEntry> redemptionHistoryEntry,
|
||||
@Nullable String domainName) {
|
||||
AllocationToken.Builder builder =
|
||||
new AllocationToken.Builder().setToken(token).setTokenType(SINGLE_USE);
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -83,7 +84,8 @@ class GetAllocationTokenCommandTest extends CommandTestCase<GetAllocationTokenCo
|
|||
.setToken("foo")
|
||||
.setTokenType(SINGLE_USE)
|
||||
.setDomainName("fqqdn.tld")
|
||||
.setRedemptionHistoryEntry(Key.create(createHistoryEntryForEppResource(domain)))
|
||||
.setRedemptionHistoryEntry(
|
||||
HistoryEntry.createVKey(Key.create(createHistoryEntryForEppResource(domain))))
|
||||
.build());
|
||||
runCommand("foo");
|
||||
assertInStdout(
|
||||
|
|
|
@ -55,9 +55,9 @@ class UpdateAllocationTokensCommandTest extends CommandTestCase<UpdateAllocation
|
|||
void testUpdateClientIds_setClientIds() throws Exception {
|
||||
AllocationToken token =
|
||||
persistResource(
|
||||
builderWithPromo().setAllowedClientIds(ImmutableSet.of("toRemove")).build());
|
||||
builderWithPromo().setAllowedRegistrarIds(ImmutableSet.of("toRemove")).build());
|
||||
runCommandForced("--prefix", "token", "--allowed_client_ids", "clientone,clienttwo");
|
||||
assertThat(reloadResource(token).getAllowedClientIds())
|
||||
assertThat(reloadResource(token).getAllowedRegistrarIds())
|
||||
.containsExactly("clientone", "clienttwo");
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,9 @@ class UpdateAllocationTokensCommandTest extends CommandTestCase<UpdateAllocation
|
|||
void testUpdateClientIds_clearClientIds() throws Exception {
|
||||
AllocationToken token =
|
||||
persistResource(
|
||||
builderWithPromo().setAllowedClientIds(ImmutableSet.of("toRemove")).build());
|
||||
builderWithPromo().setAllowedRegistrarIds(ImmutableSet.of("toRemove")).build());
|
||||
runCommandForced("--prefix", "token", "--allowed_client_ids", "");
|
||||
assertThat(reloadResource(token).getAllowedClientIds()).isEmpty();
|
||||
assertThat(reloadResource(token).getAllowedRegistrarIds()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -175,14 +175,14 @@ class UpdateAllocationTokensCommandTest extends CommandTestCase<UpdateAllocation
|
|||
AllocationToken token =
|
||||
persistResource(
|
||||
builderWithPromo()
|
||||
.setAllowedClientIds(ImmutableSet.of("clientid"))
|
||||
.setAllowedRegistrarIds(ImmutableSet.of("clientid"))
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.setDiscountFraction(0.15)
|
||||
.build());
|
||||
runCommandForced("--prefix", "token");
|
||||
AllocationToken reloaded = reloadResource(token);
|
||||
assertThat(reloaded.getAllowedTlds()).isEqualTo(token.getAllowedTlds());
|
||||
assertThat(reloaded.getAllowedClientIds()).isEqualTo(token.getAllowedClientIds());
|
||||
assertThat(reloaded.getAllowedRegistrarIds()).isEqualTo(token.getAllowedRegistrarIds());
|
||||
assertThat(reloaded.getDiscountFraction()).isEqualTo(token.getDiscountFraction());
|
||||
}
|
||||
|
||||
|
|
|
@ -233,12 +233,12 @@ class google.registry.model.domain.secdns.DelegationSignerData {
|
|||
class google.registry.model.domain.token.AllocationToken {
|
||||
@Id java.lang.String token;
|
||||
boolean discountPremiums;
|
||||
com.googlecode.objectify.Key<google.registry.model.reporting.HistoryEntry> redemptionHistoryEntry;
|
||||
double discountFraction;
|
||||
google.registry.model.CreateAutoTimestamp creationTime;
|
||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
||||
google.registry.model.common.TimedTransitionProperty<google.registry.model.domain.token.AllocationToken$TokenStatus, google.registry.model.domain.token.AllocationToken$TokenStatusTransition> tokenStatusTransitions;
|
||||
google.registry.model.domain.token.AllocationToken$TokenType tokenType;
|
||||
google.registry.persistence.VKey<google.registry.model.reporting.HistoryEntry> redemptionHistoryEntry;
|
||||
int discountYears;
|
||||
java.lang.String domainName;
|
||||
java.util.Set<java.lang.String> allowedClientIds;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
-- 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.
|
||||
|
||||
CREATE TABLE "AllocationToken" (
|
||||
token text NOT NULL,
|
||||
update_timestamp timestamptz,
|
||||
allowed_registrar_ids text[],
|
||||
allowed_tlds text[],
|
||||
creation_time timestamptz NOT NULL,
|
||||
discount_fraction float8 NOT NULL,
|
||||
discount_premiums boolean NOT NULL,
|
||||
discount_years int4 NOT NULL,
|
||||
domain_name text,
|
||||
redemption_history_entry text,
|
||||
token_status_transitions hstore,
|
||||
token_type text,
|
||||
PRIMARY KEY (token)
|
||||
);
|
||||
|
||||
CREATE INDEX allocation_token_domain_name_idx ON "AllocationToken" (domain_name);
|
|
@ -13,6 +13,22 @@
|
|||
-- limitations under the License.
|
||||
create sequence history_id_sequence start 1 increment 1;
|
||||
|
||||
create table "AllocationToken" (
|
||||
token text not null,
|
||||
update_timestamp timestamptz,
|
||||
allowed_registrar_ids text[],
|
||||
allowed_tlds text[],
|
||||
creation_time timestamptz not null,
|
||||
discount_fraction float8 not null,
|
||||
discount_premiums boolean not null,
|
||||
discount_years int4 not null,
|
||||
domain_name text,
|
||||
redemption_history_entry text,
|
||||
token_status_transitions hstore,
|
||||
token_type text,
|
||||
primary key (token)
|
||||
);
|
||||
|
||||
create table "BillingCancellation" (
|
||||
billing_cancellation_id bigserial not null,
|
||||
registrar_id text not null,
|
||||
|
@ -567,6 +583,7 @@ create sequence history_id_sequence start 1 increment 1;
|
|||
contents bytea,
|
||||
primary key (id)
|
||||
);
|
||||
create index allocation_token_domain_name_idx on "AllocationToken" (domain_name);
|
||||
create index IDXih4b2tea127p5rb61gje6e1y2 on "BillingCancellation" (registrar_id);
|
||||
create index IDX2exdfbx6oiiwnhr8j6gjpqt2j on "BillingCancellation" (event_time);
|
||||
create index IDXqa3g92jc17e8dtiaviy4fet4x on "BillingCancellation" (billing_time);
|
||||
|
|
|
@ -34,6 +34,26 @@ SET default_tablespace = '';
|
|||
|
||||
SET default_with_oids = false;
|
||||
|
||||
--
|
||||
-- Name: AllocationToken; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."AllocationToken" (
|
||||
token text NOT NULL,
|
||||
update_timestamp timestamp with time zone,
|
||||
allowed_registrar_ids text[],
|
||||
allowed_tlds text[],
|
||||
creation_time timestamp with time zone NOT NULL,
|
||||
discount_fraction double precision NOT NULL,
|
||||
discount_premiums boolean NOT NULL,
|
||||
discount_years integer NOT NULL,
|
||||
domain_name text,
|
||||
redemption_history_entry text,
|
||||
token_status_transitions public.hstore,
|
||||
token_type text
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingCancellation; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -985,6 +1005,14 @@ ALTER TABLE ONLY public."Spec11ThreatMatch" ALTER COLUMN id SET DEFAULT nextval(
|
|||
ALTER TABLE ONLY public."Transaction" ALTER COLUMN id SET DEFAULT nextval('public."Transaction_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: AllocationToken AllocationToken_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."AllocationToken"
|
||||
ADD CONSTRAINT "AllocationToken_pkey" PRIMARY KEY (token);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingCancellation BillingCancellation_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1185,6 +1213,13 @@ ALTER TABLE ONLY public."RegistryLock"
|
|||
ADD CONSTRAINT idx_registry_lock_repo_id_revision_id UNIQUE (repo_id, revision_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: allocation_token_domain_name_idx; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX allocation_token_domain_name_idx ON public."AllocationToken" USING btree (domain_name);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx1iy7njgb7wjmj9piml4l2g0qi; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue