Add entity for reserved list (#381)

This PR added the Cloud SQL entity for reserved list.
This commit is contained in:
Shicong Huang 2019-11-26 16:51:41 -05:00 committed by GitHub
parent 28499d23a0
commit 9be5091c84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 340 additions and 0 deletions

View file

@ -0,0 +1,147 @@
// Copyright 2019 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.schema.tld;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.collect.ImmutableMap;
import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ImmutableObject;
import google.registry.model.registry.label.ReservationType;
import java.util.Map;
import javax.annotation.Nullable;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.MapKeyColumn;
import javax.persistence.Table;
import org.joda.time.DateTime;
/**
* A list of reserved domain labels that are blocked from being registered for various reasons.
*
* <p>Note that the primary key of this entity is {@link #revisionId}, which is auto-generated by
* the database. So, if a retry of insertion happens after the previous attempt unexpectedly
* succeeds, we will end up with having two exact same reserved lists that differ only by
* revisionId. This is fine though, because we only use the list with the highest revisionId.
*/
@Entity
@Table(indexes = {@Index(columnList = "name", name = "reservedlist_name_idx")})
public class ReservedList extends ImmutableObject {
@Column(nullable = false)
private String name;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
private Long revisionId;
@Column(nullable = false)
private CreateAutoTimestamp creationTimestamp = CreateAutoTimestamp.create(null);
@Column(nullable = false)
private Boolean shouldPublish;
@ElementCollection
@CollectionTable(
name = "ReservedEntry",
joinColumns = @JoinColumn(name = "revisionId", referencedColumnName = "revisionId"))
@MapKeyColumn(name = "domainLabel")
private Map<String, ReservedEntry> labelsToReservations;
@Embeddable
public static class ReservedEntry extends ImmutableObject {
@Column(nullable = false)
private ReservationType reservationType;
@Column(nullable = true)
private String comment;
private ReservedEntry(ReservationType reservationType, @Nullable String comment) {
this.reservationType = reservationType;
this.comment = comment;
}
// Hibernate requires this default constructor.
private ReservedEntry() {}
/** Constructs a {@link ReservedEntry} object. */
public static ReservedEntry create(ReservationType reservationType, @Nullable String comment) {
return new ReservedEntry(reservationType, comment);
}
/** Returns the reservation type for this entry. */
public ReservationType getReservationType() {
return reservationType;
}
/** Returns the comment for this entry. Retruns null if there is no comment. */
public String getComment() {
return comment;
}
}
private ReservedList(
String name, Boolean shouldPublish, Map<String, ReservedEntry> labelsToReservations) {
this.name = name;
this.shouldPublish = shouldPublish;
this.labelsToReservations = labelsToReservations;
}
// Hibernate requires this default constructor.
private ReservedList() {}
/** Constructs a {@link ReservedList} object. */
public static ReservedList create(
String name, Boolean shouldPublish, Map<String, ReservedEntry> labelsToReservations) {
return new ReservedList(name, shouldPublish, labelsToReservations);
}
/** Returns the name of the reserved list. */
public String getName() {
return name;
}
/** Returns the ID of this revision, or throws if null. */
public Long getRevisionId() {
checkState(
revisionId != null,
"revisionId is null because this object has not been persisted to the database yet");
return revisionId;
}
/** Returns the creation time of this revision of the reserved list. */
public DateTime getCreationTimestamp() {
return creationTimestamp.getTimestamp();
}
/** Returns a {@link Map} of domain labels to {@link ReservedEntry}. */
public ImmutableMap<String, ReservedEntry> getLabelsToReservations() {
return ImmutableMap.copyOf(labelsToReservations);
}
/** Returns true if the reserved list should be published. */
public Boolean getShouldPublish() {
return shouldPublish;
}
}

View file

@ -24,6 +24,7 @@
<class>google.registry.schema.tmch.ClaimsList</class> <class>google.registry.schema.tmch.ClaimsList</class>
<class>google.registry.model.transfer.BaseTransferObject</class> <class>google.registry.model.transfer.BaseTransferObject</class>
<class>google.registry.schema.tld.PremiumList</class> <class>google.registry.schema.tld.PremiumList</class>
<class>google.registry.schema.tld.ReservedList</class>
<class>google.registry.model.domain.secdns.DelegationSignerData</class> <class>google.registry.model.domain.secdns.DelegationSignerData</class>
<class>google.registry.model.domain.DesignatedContact</class> <class>google.registry.model.domain.DesignatedContact</class>
<class>google.registry.model.domain.DomainBase</class> <class>google.registry.model.domain.DomainBase</class>

View file

@ -0,0 +1,53 @@
// Copyright 2019 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.schema.tld;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableMap;
import google.registry.model.registry.label.ReservationType;
import google.registry.schema.tld.ReservedList.ReservedEntry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link ReservedList} */
@RunWith(JUnit4.class)
public class ReservedListTest {
@Test
public void verifyConstructorAndGetters_workCorrectly() {
ReservedList reservedList =
ReservedList.create(
"app",
false,
ImmutableMap.of(
"book",
ReservedEntry.create(ReservationType.ALLOWED_IN_SUNRISE, null),
"music",
ReservedEntry.create(
ReservationType.RESERVED_FOR_ANCHOR_TENANT, "reserved for anchor tenant")));
assertThat(reservedList.getName()).isEqualTo("app");
assertThat(reservedList.getShouldPublish()).isFalse();
assertThat(reservedList.getLabelsToReservations())
.containsExactly(
"book",
ReservedEntry.create(ReservationType.ALLOWED_IN_SUNRISE, null),
"music",
ReservedEntry.create(
ReservationType.RESERVED_FOR_ANCHOR_TENANT, "reserved for anchor tenant"));
}
}

View file

@ -0,0 +1,36 @@
-- Copyright 2019 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 "ReservedEntry" (
revision_id int8 not null,
comment text,
reservation_type int4 not null,
domain_label text not null,
primary key (revision_id, domain_label)
);
create table "ReservedList" (
revision_id bigserial not null,
creation_timestamp timestamptz not null,
name text not null,
should_publish boolean not null,
primary key (revision_id)
);
create index reservedlist_name_idx on "ReservedList" (name);
alter table if exists "ReservedEntry"
add constraint FKgq03rk0bt1hb915dnyvd3vnfc
foreign key (revision_id)
references "ReservedList";

View file

@ -152,6 +152,22 @@
primary key (revision_id) primary key (revision_id)
); );
create table "ReservedEntry" (
revision_id int8 not null,
comment text,
reservation_type int4 not null,
domain_label text not null,
primary key (revision_id, domain_label)
);
create table "ReservedList" (
revision_id bigserial not null,
creation_timestamp timestamptz not null,
name text not null,
should_publish boolean not null,
primary key (revision_id)
);
alter table if exists "Domain_DelegationSignerData" alter table if exists "Domain_DelegationSignerData"
add constraint UK_2yp55erx1i51pa7gnb8bu7tjn unique (ds_data_key_tag); add constraint UK_2yp55erx1i51pa7gnb8bu7tjn unique (ds_data_key_tag);
@ -166,6 +182,7 @@ create index idx_registry_lock_registrar_id on "RegistryLock" (registrar_id);
alter table if exists "RegistryLock" alter table if exists "RegistryLock"
add constraint idx_registry_lock_repo_id_revision_id unique (repo_id, revision_id); add constraint idx_registry_lock_repo_id_revision_id unique (repo_id, revision_id);
create index reservedlist_name_idx on "ReservedList" (name);
alter table if exists "ClaimsEntry" alter table if exists "ClaimsEntry"
add constraint FK6sc6at5hedffc0nhdcab6ivuq add constraint FK6sc6at5hedffc0nhdcab6ivuq
@ -221,3 +238,8 @@ create index idx_registry_lock_registrar_id on "RegistryLock" (registrar_id);
add constraint FKo0gw90lpo1tuee56l0nb6y6g5 add constraint FKo0gw90lpo1tuee56l0nb6y6g5
foreign key (revision_id) foreign key (revision_id)
references "PremiumList"; references "PremiumList";
alter table if exists "ReservedEntry"
add constraint FKgq03rk0bt1hb915dnyvd3vnfc
foreign key (revision_id)
references "ReservedList";

View file

@ -141,6 +141,49 @@ CREATE SEQUENCE public."RegistryLock_revision_id_seq"
ALTER SEQUENCE public."RegistryLock_revision_id_seq" OWNED BY public."RegistryLock".revision_id; ALTER SEQUENCE public."RegistryLock_revision_id_seq" OWNED BY public."RegistryLock".revision_id;
--
-- Name: ReservedEntry; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."ReservedEntry" (
revision_id bigint NOT NULL,
comment text,
reservation_type integer NOT NULL,
domain_label text NOT NULL
);
--
-- Name: ReservedList; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."ReservedList" (
revision_id bigint NOT NULL,
creation_timestamp timestamp with time zone NOT NULL,
name text NOT NULL,
should_publish boolean NOT NULL
);
--
-- Name: ReservedList_revision_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public."ReservedList_revision_id_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: ReservedList_revision_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public."ReservedList_revision_id_seq" OWNED BY public."ReservedList".revision_id;
-- --
-- Name: ClaimsList revision_id; Type: DEFAULT; Schema: public; Owner: - -- Name: ClaimsList revision_id; Type: DEFAULT; Schema: public; Owner: -
-- --
@ -162,6 +205,13 @@ ALTER TABLE ONLY public."PremiumList" ALTER COLUMN revision_id SET DEFAULT nextv
ALTER TABLE ONLY public."RegistryLock" ALTER COLUMN revision_id SET DEFAULT nextval('public."RegistryLock_revision_id_seq"'::regclass); ALTER TABLE ONLY public."RegistryLock" ALTER COLUMN revision_id SET DEFAULT nextval('public."RegistryLock_revision_id_seq"'::regclass);
--
-- Name: ReservedList revision_id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."ReservedList" ALTER COLUMN revision_id SET DEFAULT nextval('public."ReservedList_revision_id_seq"'::regclass);
-- --
-- Name: ClaimsEntry ClaimsEntry_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- Name: ClaimsEntry ClaimsEntry_pkey; Type: CONSTRAINT; Schema: public; Owner: -
-- --
@ -202,6 +252,22 @@ ALTER TABLE ONLY public."RegistryLock"
ADD CONSTRAINT "RegistryLock_pkey" PRIMARY KEY (revision_id); ADD CONSTRAINT "RegistryLock_pkey" PRIMARY KEY (revision_id);
--
-- Name: ReservedEntry ReservedEntry_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."ReservedEntry"
ADD CONSTRAINT "ReservedEntry_pkey" PRIMARY KEY (revision_id, domain_label);
--
-- Name: ReservedList ReservedList_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."ReservedList"
ADD CONSTRAINT "ReservedList_pkey" PRIMARY KEY (revision_id);
-- --
-- Name: RegistryLock idx_registry_lock_repo_id_revision_id; Type: CONSTRAINT; Schema: public; Owner: - -- Name: RegistryLock idx_registry_lock_repo_id_revision_id; Type: CONSTRAINT; Schema: public; Owner: -
-- --
@ -231,6 +297,13 @@ CREATE INDEX idx_registry_lock_verification_code ON public."RegistryLock" USING
CREATE INDEX premiumlist_name_idx ON public."PremiumList" USING btree (name); CREATE INDEX premiumlist_name_idx ON public."PremiumList" USING btree (name);
--
-- Name: reservedlist_name_idx; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX reservedlist_name_idx ON public."ReservedList" USING btree (name);
-- --
-- Name: ClaimsEntry fk6sc6at5hedffc0nhdcab6ivuq; Type: FK CONSTRAINT; Schema: public; Owner: - -- Name: ClaimsEntry fk6sc6at5hedffc0nhdcab6ivuq; Type: FK CONSTRAINT; Schema: public; Owner: -
-- --
@ -239,6 +312,14 @@ ALTER TABLE ONLY public."ClaimsEntry"
ADD CONSTRAINT fk6sc6at5hedffc0nhdcab6ivuq FOREIGN KEY (revision_id) REFERENCES public."ClaimsList"(revision_id); ADD CONSTRAINT fk6sc6at5hedffc0nhdcab6ivuq FOREIGN KEY (revision_id) REFERENCES public."ClaimsList"(revision_id);
--
-- Name: ReservedEntry fkgq03rk0bt1hb915dnyvd3vnfc; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."ReservedEntry"
ADD CONSTRAINT fkgq03rk0bt1hb915dnyvd3vnfc FOREIGN KEY (revision_id) REFERENCES public."ReservedList"(revision_id);
-- --
-- Name: PremiumEntry fko0gw90lpo1tuee56l0nb6y6g5; Type: FK CONSTRAINT; Schema: public; Owner: - -- Name: PremiumEntry fko0gw90lpo1tuee56l0nb6y6g5; Type: FK CONSTRAINT; Schema: public; Owner: -
-- --