1
0
mirror of https://github.com/google/nomulus synced 2026-07-07 00:27:12 +00:00

Compare commits

..

7 Commits

Author SHA1 Message Date
gbrodman c21b66f0fb Add reset-EPP-password frontend component (#2786) 2025-08-01 19:53:20 +00:00
gbrodman b070c46231 Allow superuser status to override EPP resource delete prohibited status (#2789) 2025-08-01 19:51:44 +00:00
Weimin Yu a20eb8d1e9 Fix failures in retries when inserting new objects (#2788)
Given an entity with auto-filled id fields (annotated with
@GeneratedValue, with null as initial value), when inserting it
using Hibernate, the id fields will be filled with non-nulls even
if the transaction fails.

If the same entity instance is used again in a retry, Hibernate mistakes
it as a detached entity and raises an error.

The work around is to make a new copy of the entity in each transaction.
This PR applies this pattern to affected entity types.

We considered applying this pattern to JpaTransactionManagerImpl's insert
method so that individual call sites do not have to change. However, we
decided against it because:

- It is unnecessary for entity types that do not have auto-filled id

- The JpaTransactionManager cannot tell if copying is cheap or
  expensive. It is better exposing this to the user.

- The JpaTransactionManager needs to know how to clone entities. A new
  interface may need to be introduced just for a handful of use cases.
2025-08-01 18:53:50 +00:00
Ben McIlwain 338b8edb97 Make the contacts prohibited feature flag for min reg data set more lenient (#2787)
It will now only throw errors on domain updates if a new contact/registrant has
been specified where none was previously present. This means that domain updates
on unrelated fields (e.g. nameserver changes) will succeed even if there is
existing contact data that the update is not removing.

This is a follow-up to #2781.

BUG=http://b/434958659
2025-07-29 20:54:58 +00:00
gbrodman 9f191e9392 Add Registry Lock password reset on front end (#2785)
This is only enabled for admins, for now at least. It sends an email to
the registry lock email address to reset it.
2025-07-28 20:23:39 +00:00
gbrodman 39c2a79898 Remove superfluous DatabaseHelper db methods (#2784)
Some of these have been around since the Datastore days and are no
longer relevant (dealing with things like Datastore foreign keys). Let's
simplify things.
2025-07-25 17:00:24 +00:00
Pavlo Tkach e2e9d4cfc7 Add console history api (#2782) 2025-07-18 18:46:21 +00:00
122 changed files with 1602 additions and 730 deletions
@@ -77,4 +77,17 @@
Save
</button>
</form>
@if(userDataService.userData()?.isAdmin) {
<div class="settings-security__reset-password-field">
<h2>Need to reset your EPP password?</h2>
<button
mat-flat-button
color="primary"
aria-label="Reset EPP password via email"
(click)="requestEppPasswordReset()"
>
Reset EPP password via email
</button>
</div>
}
</div>
@@ -1,16 +1,35 @@
.settings-security__edit-password {
max-width: 616px;
&-field {
width: 100%;
mat-form-field {
margin-bottom: 20px;
// Copyright 2025 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.
.settings-security {
&__edit-password {
max-width: 616px;
&-field {
width: 100%;
mat-form-field {
margin-bottom: 20px;
width: 100%;
}
}
&-form {
margin-top: 30px;
}
&-save {
margin-top: 30px;
}
}
&-form {
margin-top: 30px;
}
&-save {
margin-top: 30px;
&__reset-password-field {
margin-top: 60px;
}
}
@@ -24,11 +24,43 @@ import {
import { MatSnackBar } from '@angular/material/snack-bar';
import { RegistrarService } from 'src/app/registrar/registrar.service';
import { SecurityService } from './security.service';
import { UserDataService } from 'src/app/shared/services/userData.service';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { CommonModule } from '@angular/common';
import { MaterialModule } from 'src/app/material.module';
import { filter, switchMap, take } from 'rxjs';
import { BackendService } from 'src/app/shared/services/backend.service';
type errorCode = 'required' | 'maxlength' | 'minlength' | 'passwordsDontMatch';
type errorFriendlyText = { [type in errorCode]: String };
@Component({
selector: 'app-reset-epp-password-dialog',
template: `
<h2 mat-dialog-title>Please confirm the password reset:</h2>
<mat-dialog-content>
This will send an EPP password reset email to the admin POC.
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button (click)="onCancel()">Cancel</button>
<button mat-button color="warn" (click)="onSave()">Confirm</button>
</mat-dialog-actions>
`,
imports: [CommonModule, MaterialModule],
})
export class ResetEppPasswordComponent {
constructor(public dialogRef: MatDialogRef<ResetEppPasswordComponent>) {}
onSave(): void {
this.dialogRef.close(true);
}
onCancel(): void {
this.dialogRef.close(false);
}
}
@Component({
selector: 'app-epp-password-edit',
templateUrl: './eppPasswordEdit.component.html',
@@ -48,9 +80,12 @@ export default class EppPasswordEditComponent {
};
constructor(
public registrarService: RegistrarService,
public securityService: SecurityService,
private _snackBar: MatSnackBar,
public registrarService: RegistrarService
protected userDataService: UserDataService,
private backendService: BackendService,
private resetPasswordDialog: MatDialog,
private _snackBar: MatSnackBar
) {}
hasError(controlName: string) {
@@ -120,4 +155,26 @@ export default class EppPasswordEditComponent {
goBack() {
this.securityService.isEditingPassword = false;
}
sendEppPasswordResetRequest() {
return this.backendService.requestEppPasswordReset(
this.registrarService.registrarId()
);
}
requestEppPasswordReset() {
const dialogRef = this.resetPasswordDialog.open(ResetEppPasswordComponent);
dialogRef
.afterClosed()
.pipe(
take(1),
filter((result) => !!result)
)
.pipe(switchMap((_) => this.sendEppPasswordResetRequest()))
.subscribe({
next: (_) => this.goBack(),
error: (err: HttpErrorResponse) =>
this._snackBar.open(err.error || err.message),
});
}
}
@@ -280,4 +280,22 @@ export class BackendService {
`/console-api/registry-lock-verify?lockVerificationCode=${lockVerificationCode}`
);
}
requestRegistryLockPasswordReset(
registrarId: string,
registryLockEmail: string
) {
return this.http.post('/console-api/password-reset-request', {
type: 'REGISTRY_LOCK',
registrarId,
registryLockEmail,
});
}
requestEppPasswordReset(registrarId: string) {
return this.http.post('/console-api/password-reset-request', {
type: 'EPP',
registrarId,
});
}
}
@@ -80,7 +80,15 @@
roleToDescription(userDetails().role)
}}</span>
</mat-list-item>
@if (userDetails().password) {
@if (userDetails().registryLockEmailAddress) {
<mat-divider></mat-divider>
<mat-list-item role="listitem">
<span class="console-app__list-key">Registry Lock email</span>
<span class="console-app__list-value">{{
userDetails().registryLockEmailAddress
}}</span>
</mat-list-item>
} @if (userDetails().password) {
<mat-divider></mat-divider>
<mat-list-item role="listitem">
<span class="console-app__list-key">Password</span>
@@ -35,5 +35,8 @@
border: 1px solid #ddd;
border-radius: 10px;
}
.console-app__list-key {
width: 160px;
}
}
}
@@ -1,45 +1,57 @@
<form (ngSubmit)="saveEdit($event)" #form>
<p *ngIf="isNew()">
<mat-form-field appearance="outline">
<mat-label
>User name prefix:
<mat-icon
matTooltip="Prefix will be combined with registrar ID to create a unique user name - {prefix}.{registrarId}@registry.google"
>help_outline</mat-icon
></mat-label
>
<input
matInput
minlength="3"
maxlength="3"
[required]="true"
[(ngModel)]="user().emailAddress"
[ngModelOptions]="{ standalone: true }"
/>
</mat-form-field>
</p>
<p>
<mat-form-field appearance="outline">
<mat-label
>User Role:
<mat-icon
matTooltip="Viewer role doesn't allow making updates; Editor role allows updates, like Contacts delete or SSL certificate change"
>help_outline</mat-icon
></mat-label
>
<mat-select [(ngModel)]="user().role" name="userRole">
<mat-option value="PRIMARY_CONTACT">Editor</mat-option>
<mat-option value="ACCOUNT_MANAGER">Viewer</mat-option>
</mat-select>
</mat-form-field>
</p>
<div class="console-app__user-edit">
<form (ngSubmit)="saveEdit($event)" #form>
<p *ngIf="isNew()">
<mat-form-field appearance="outline">
<mat-label
>User name prefix:
<mat-icon
matTooltip="Prefix will be combined with registrar ID to create a unique user name - {prefix}.{registrarId}@registry.google"
>help_outline</mat-icon
></mat-label
>
<input
matInput
minlength="3"
maxlength="3"
[required]="true"
[(ngModel)]="user().emailAddress"
[ngModelOptions]="{ standalone: true }"
/>
</mat-form-field>
</p>
<p>
<mat-form-field appearance="outline">
<mat-label
>User Role:
<mat-icon
matTooltip="Viewer role doesn't allow making updates; Editor role allows updates, like Contacts delete or SSL certificate change"
>help_outline</mat-icon
></mat-label
>
<mat-select [(ngModel)]="user().role" name="userRole">
<mat-option value="PRIMARY_CONTACT">Editor</mat-option>
<mat-option value="ACCOUNT_MANAGER">Viewer</mat-option>
</mat-select>
</mat-form-field>
</p>
<button
mat-flat-button
color="primary"
aria-label="Save user"
type="submit"
aria-label="Save changes to the user"
>
Save
</button>
</form>
@if(userDataService.userData()?.isAdmin) {
<button
mat-flat-button
color="primary"
aria-label="Save user"
type="submit"
aria-label="Save changes to the user"
aria-label="Reset registry lock password"
(click)="requestRegistryLockPasswordReset()"
>
Save
Reset registry lock password
</button>
</form>
}
</div>
@@ -0,0 +1,20 @@
// Copyright 2025 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.
.console-app__user-edit {
button {
display: block;
margin-bottom: 5px;
}
}
@@ -17,13 +17,56 @@ import {
Component,
ElementRef,
EventEmitter,
Inject,
input,
Output,
ViewChild,
} from '@angular/core';
import { MaterialModule } from '../material.module';
import { FormsModule } from '@angular/forms';
import { User } from './users.service';
import { User, UsersService } from './users.service';
import { UserDataService } from '../shared/services/userData.service';
import { BackendService } from '../shared/services/backend.service';
import { RegistrarService } from '../registrar/registrar.service';
import {
MAT_DIALOG_DATA,
MatDialog,
MatDialogRef,
} from '@angular/material/dialog';
import { filter, switchMap, take } from 'rxjs';
import { MatSnackBar } from '@angular/material/snack-bar';
import { HttpErrorResponse } from '@angular/common/http';
@Component({
selector: 'app-reset-lock-password-dialog',
template: `
<h2 mat-dialog-title>Please confirm the password reset:</h2>
<mat-dialog-content>
This will send a registry lock password reset email to
{{ data.registryLockEmailAddress }}.
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button (click)="onCancel()">Cancel</button>
<button mat-button color="warn" (click)="onSave()">Confirm</button>
</mat-dialog-actions>
`,
imports: [CommonModule, MaterialModule],
})
export class ResetRegistryLockPasswordComponent {
constructor(
public dialogRef: MatDialogRef<ResetRegistryLockPasswordComponent>,
@Inject(MAT_DIALOG_DATA)
public data: { registryLockEmailAddress: string }
) {}
onSave(): void {
this.dialogRef.close(true);
}
onCancel(): void {
this.dialogRef.close(false);
}
}
@Component({
selector: 'app-user-edit-form',
@@ -39,12 +82,22 @@ export class UserEditFormComponent {
{
emailAddress: '',
role: 'ACCOUNT_MANAGER',
registryLockEmailAddress: '',
},
{ transform: (user: User) => structuredClone(user) }
);
@Output() onEditComplete = new EventEmitter<User>();
constructor(
protected userDataService: UserDataService,
private backendService: BackendService,
private resetRegistryLockPasswordDialog: MatDialog,
private registrarService: RegistrarService,
private usersService: UsersService,
private _snackBar: MatSnackBar
) {}
saveEdit(e: SubmitEvent) {
e.preventDefault();
if (this.form.nativeElement.checkValidity()) {
@@ -53,4 +106,34 @@ export class UserEditFormComponent {
this.form.nativeElement.reportValidity();
}
}
sendRegistryLockPasswordResetRequest() {
return this.backendService.requestRegistryLockPasswordReset(
this.registrarService.registrarId(),
this.user().registryLockEmailAddress!
);
}
requestRegistryLockPasswordReset() {
const dialogRef = this.resetRegistryLockPasswordDialog.open(
ResetRegistryLockPasswordComponent,
{
data: {
registryLockEmailAddress: this.user().registryLockEmailAddress,
},
}
);
dialogRef
.afterClosed()
.pipe(
take(1),
filter((result) => !!result)
)
.pipe(switchMap((_) => this.sendRegistryLockPasswordResetRequest()))
.subscribe({
next: (_) => this.usersService.currentlyOpenUserEmail.set(''),
error: (err: HttpErrorResponse) =>
this._snackBar.open(err.error || err.message),
});
}
}
@@ -33,6 +33,7 @@ export interface User {
emailAddress: string;
role: string;
password?: string;
registryLockEmailAddress?: string;
}
@Injectable()
@@ -21,6 +21,7 @@ import static google.registry.xml.ValidationMode.STRICT;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import google.registry.flows.EppException.CommandUseErrorException;
import google.registry.flows.EppException.ParameterValueRangeErrorException;
@@ -30,6 +31,7 @@ import google.registry.flows.custom.EntityChanges;
import google.registry.model.EppResource;
import google.registry.model.adapters.CurrencyUnitAdapter.UnknownCurrencyException;
import google.registry.model.eppcommon.EppXmlTransformer;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppinput.EppInput.WrongProtocolVersionException;
import google.registry.model.eppoutput.EppOutput;
import google.registry.model.host.InetAddressAdapter.IpVersionMismatchException;
@@ -40,6 +42,9 @@ import java.util.List;
/** Static utility functions for flows. */
public final class FlowUtils {
public static final ImmutableSet<StatusValue> DELETE_PROHIBITED_STATUSES =
ImmutableSet.of(StatusValue.CLIENT_DELETE_PROHIBITED, StatusValue.SERVER_DELETE_PROHIBITED);
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private FlowUtils() {}
@@ -14,6 +14,7 @@
package google.registry.flows.contact;
import static google.registry.flows.FlowUtils.DELETE_PROHIBITED_STATUSES;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.checkLinkedDomains;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
@@ -65,12 +66,6 @@ import org.joda.time.DateTime;
@ReportingSpec(ActivityReportField.CONTACT_DELETE)
public final class ContactDeleteFlow implements MutatingFlow {
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES =
ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED,
StatusValue.PENDING_DELETE,
StatusValue.SERVER_DELETE_PROHIBITED);
@Inject ExtensionManager extensionManager;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@@ -91,9 +86,10 @@ public final class ContactDeleteFlow implements MutatingFlow {
DateTime now = tm().getTransactionTime();
checkLinkedDomains(targetId, now, Contact.class);
Contact existingContact = loadAndVerifyExistence(Contact.class, targetId, now);
verifyNoDisallowedStatuses(existingContact, DISALLOWED_STATUSES);
verifyOptionalAuthInfo(authInfo, existingContact);
verifyNoDisallowedStatuses(existingContact, ImmutableSet.of(StatusValue.PENDING_DELETE));
if (!isSuperuser) {
verifyNoDisallowedStatuses(existingContact, DELETE_PROHIBITED_STATUSES);
verifyResourceOwnership(registrarId, existingContact);
}
// Handle pending transfers on contact deletion.
@@ -17,6 +17,7 @@ package google.registry.flows.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static google.registry.dns.DnsUtils.requestDomainDnsRefresh;
import static google.registry.flows.FlowUtils.DELETE_PROHIBITED_STATUSES;
import static google.registry.flows.FlowUtils.createHistoryEntryId;
import static google.registry.flows.FlowUtils.persistEntityChanges;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
@@ -122,11 +123,6 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED,
StatusValue.PENDING_DELETE,
StatusValue.SERVER_DELETE_PROHIBITED);
@Inject ExtensionManager extensionManager;
@Inject EppInput eppInput;
@Inject SessionMetadata sessionMetadata;
@@ -304,9 +300,10 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
private void verifyDeleteAllowed(Domain existingDomain, Tld tld, DateTime now)
throws EppException {
verifyNoDisallowedStatuses(existingDomain, DISALLOWED_STATUSES);
verifyOptionalAuthInfo(authInfo, existingDomain);
verifyNoDisallowedStatuses(existingDomain, ImmutableSet.of(StatusValue.PENDING_DELETE));
if (!isSuperuser) {
verifyNoDisallowedStatuses(existingDomain, DELETE_PROHIBITED_STATUSES);
verifyResourceOwnership(registrarId, existingDomain);
verifyNotInPredelegation(tld, now);
checkAllowedAccessToTld(registrarId, tld.getTld().toString());
@@ -481,10 +481,10 @@ public class DomainFlowUtils {
}
/**
* Enforces the presence/absence of contact data depending on the minimum data set migration
* schedule.
* Enforces the presence/absence of contact data on domain creates depending on the minimum data
* set migration schedule.
*/
static void validateContactDataPresence(
static void validateCreateContactData(
Optional<VKey<Contact>> registrant, Set<DesignatedContact> contacts)
throws RequiredParameterMissingException, ParameterValuePolicyErrorException {
// TODO(b/353347632): Change these flag checks to a registry config check once minimum data set
@@ -514,6 +514,45 @@ public class DomainFlowUtils {
}
}
/**
* Enforces the presence/absence of contact data on domain updates depending on the minimum data
* set migration schedule.
*/
static void validateUpdateContactData(
Optional<VKey<Contact>> existingRegistrant,
Optional<VKey<Contact>> newRegistrant,
Set<DesignatedContact> existingContacts,
Set<DesignatedContact> newContacts)
throws RequiredParameterMissingException, ParameterValuePolicyErrorException {
// TODO(b/353347632): Change these flag checks to a registry config check once minimum data set
// migration is completed.
if (FeatureFlag.isActiveNow(MINIMUM_DATASET_CONTACTS_PROHIBITED)) {
// Throw if the update specifies a new registrant that is different from the existing one.
if (newRegistrant.isPresent() && !newRegistrant.equals(existingRegistrant)) {
throw new RegistrantProhibitedException();
}
// Throw if the update specifies any new contacts that weren't already present on the domain.
if (!Sets.difference(newContacts, existingContacts).isEmpty()) {
throw new ContactsProhibitedException();
}
} else if (!FeatureFlag.isActiveNow(MINIMUM_DATASET_CONTACTS_OPTIONAL)) {
// Throw if the update empties out a registrant that had been present.
if (newRegistrant.isEmpty() && existingRegistrant.isPresent()) {
throw new MissingRegistrantException();
}
// Throw if the update contains no admin contact when one had been present.
if (existingContacts.stream().anyMatch(c -> c.getType().equals(Type.ADMIN))
&& newContacts.stream().noneMatch(c -> c.getType().equals(Type.ADMIN))) {
throw new MissingAdminContactException();
}
// Throw if the update contains no tech contact when one had been present.
if (existingContacts.stream().anyMatch(c -> c.getType().equals(Type.TECH))
&& newContacts.stream().noneMatch(c -> c.getType().equals(Type.TECH))) {
throw new MissingTechnicalContactException();
}
}
}
static void validateRegistrantAllowedOnTld(String tld, Optional<String> registrantContactId)
throws RegistrantNotAllowedException {
ImmutableSet<String> allowedRegistrants = Tld.get(tld).getAllowedRegistrantContactIds();
@@ -1054,7 +1093,7 @@ public class DomainFlowUtils {
String tldStr = tld.getTldStr();
validateRegistrantAllowedOnTld(tldStr, command.getRegistrantContactId());
validateNoDuplicateContacts(command.getContacts());
validateContactDataPresence(command.getRegistrant(), command.getContacts());
validateCreateContactData(command.getRegistrant(), command.getContacts());
ImmutableSet<String> hostNames = command.getNameserverHostNames();
validateNameserversCountForTld(tldStr, domainName, hostNames.size());
validateNameserversAllowedOnTld(tldStr, hostNames);
@@ -30,7 +30,6 @@ import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences;
import static google.registry.flows.domain.DomainFlowUtils.updateDsData;
import static google.registry.flows.domain.DomainFlowUtils.validateContactDataPresence;
import static google.registry.flows.domain.DomainFlowUtils.validateContactsHaveTypes;
import static google.registry.flows.domain.DomainFlowUtils.validateDsData;
import static google.registry.flows.domain.DomainFlowUtils.validateFeesAckedIfPresent;
@@ -38,6 +37,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAl
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversCountForTld;
import static google.registry.flows.domain.DomainFlowUtils.validateNoDuplicateContacts;
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrantAllowedOnTld;
import static google.registry.flows.domain.DomainFlowUtils.validateUpdateContactData;
import static google.registry.flows.domain.DomainFlowUtils.verifyClientUpdateNotProhibited;
import static google.registry.flows.domain.DomainFlowUtils.verifyNotInPendingDelete;
import static google.registry.model.common.FeatureFlag.FeatureName.MINIMUM_DATASET_CONTACTS_OPTIONAL;
@@ -186,7 +186,7 @@ public final class DomainUpdateFlow implements MutatingFlow {
Domain newDomain = performUpdate(command, existingDomain, now);
DomainHistory domainHistory =
historyBuilder.setType(DOMAIN_UPDATE).setDomain(newDomain).build();
validateNewState(newDomain);
validateNewState(existingDomain, newDomain);
if (requiresDnsUpdate(existingDomain, newDomain)) {
requestDomainDnsRefresh(targetId);
}
@@ -328,8 +328,13 @@ public final class DomainUpdateFlow implements MutatingFlow {
* compliant with the additions or amendments, otherwise existing data can become invalid and
* cause Domain update failure.
*/
private static void validateNewState(Domain newDomain) throws EppException {
validateContactDataPresence(newDomain.getRegistrant(), newDomain.getContacts());
private static void validateNewState(Domain existingDomain, Domain newDomain)
throws EppException {
validateUpdateContactData(
existingDomain.getRegistrant(),
newDomain.getRegistrant(),
existingDomain.getContacts(),
newDomain.getContacts());
validateDsData(newDomain.getDsData());
validateNameserversCountForTld(
newDomain.getTld(),
@@ -15,6 +15,7 @@
package google.registry.flows.host;
import static google.registry.dns.DnsUtils.requestHostDnsRefresh;
import static google.registry.flows.FlowUtils.DELETE_PROHIBITED_STATUSES;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.checkLinkedDomains;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
@@ -65,12 +66,6 @@ import org.joda.time.DateTime;
@ReportingSpec(ActivityReportField.HOST_DELETE)
public final class HostDeleteFlow implements MutatingFlow {
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES =
ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED,
StatusValue.PENDING_DELETE,
StatusValue.SERVER_DELETE_PROHIBITED);
@Inject ExtensionManager extensionManager;
@Inject @RegistrarId String registrarId;
@Inject @TargetId String targetId;
@@ -91,8 +86,9 @@ public final class HostDeleteFlow implements MutatingFlow {
validateHostName(targetId);
checkLinkedDomains(targetId, now, Host.class);
Host existingHost = loadAndVerifyExistence(Host.class, targetId, now);
verifyNoDisallowedStatuses(existingHost, DISALLOWED_STATUSES);
verifyNoDisallowedStatuses(existingHost, ImmutableSet.of(StatusValue.PENDING_DELETE));
if (!isSuperuser) {
verifyNoDisallowedStatuses(existingHost, DELETE_PROHIBITED_STATUSES);
// Hosts transfer with their superordinate domains, so for hosts with a superordinate domain,
// the client id, needs to be read off of it.
EppResource owningResource =
@@ -16,6 +16,8 @@ package google.registry.model.console;
/** Permissions that users may have in the UI, either per-registrar or globally. */
public enum ConsolePermission {
AUDIT_ACTIVITY_BY_USER,
AUDIT_ACTIVITY_BY_REGISTRAR,
/** View basic information about a registrar. */
VIEW_REGISTRAR_DETAILS,
/** Edit basic information about a registrar. */
@@ -55,6 +55,8 @@ public class ConsoleRoleDefinitions {
new ImmutableSet.Builder<ConsolePermission>()
.addAll(SUPPORT_AGENT_PERMISSIONS)
.add(
ConsolePermission.AUDIT_ACTIVITY_BY_USER,
ConsolePermission.AUDIT_ACTIVITY_BY_REGISTRAR,
ConsolePermission.MANAGE_REGISTRARS,
ConsolePermission.GET_REGISTRANT_EMAIL,
ConsolePermission.SUSPEND_DOMAIN,
@@ -111,6 +113,7 @@ public class ConsoleRoleDefinitions {
new ImmutableSet.Builder<ConsolePermission>()
.addAll(TECH_CONTACT_PERMISSIONS)
.add(ConsolePermission.MANAGE_USERS)
.add(ConsolePermission.AUDIT_ACTIVITY_BY_REGISTRAR)
.build();
private ConsoleRoleDefinitions() {}
@@ -16,6 +16,7 @@ package google.registry.model.console;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.gson.annotations.Expose;
import google.registry.model.Buildable;
import google.registry.model.ImmutableObject;
import google.registry.model.annotations.IdAllocation;
@@ -45,6 +46,7 @@ public class ConsoleUpdateHistory extends ImmutableObject implements Buildable {
@Id @IdAllocation @Column Long revisionId;
@Column(nullable = false)
@Expose
DateTime modificationTime;
/** The HTTP method (e.g. POST, PUT) used to make this modification. */
@@ -54,6 +56,7 @@ public class ConsoleUpdateHistory extends ImmutableObject implements Buildable {
/** The type of modification. */
@Column(nullable = false)
@Enumerated(EnumType.STRING)
@Expose
Type type;
/** The URL of the action that was used to make the modification. */
@@ -61,11 +64,12 @@ public class ConsoleUpdateHistory extends ImmutableObject implements Buildable {
String url;
/** An optional further description of the action. */
String description;
@Expose String description;
/** The user that performed the modification. */
@JoinColumn(name = "actingUser", referencedColumnName = "emailAddress", nullable = false)
@ManyToOne
@Expose
User actingUser;
public Long getRevisionId() {
@@ -102,18 +106,24 @@ public class ConsoleUpdateHistory extends ImmutableObject implements Buildable {
}
public enum Type {
DUM_DOWNLOAD,
DOMAIN_DELETE,
DOMAIN_SUSPEND,
DOMAIN_UNSUSPEND,
EPP_PASSWORD_UPDATE,
REGISTRAR_CREATE,
REGISTRAR_CONTACTS_UPDATE,
REGISTRAR_SECURITY_UPDATE,
REGISTRAR_UPDATE,
REGISTRY_LOCK,
REGISTRY_UNLOCK,
USER_CREATE,
USER_DELETE,
USER_UPDATE
USER_UPDATE,
}
public static final String DESCRIPTION_SEPARATOR = "|";
public static class Builder extends Buildable.Builder<ConsoleUpdateHistory> {
public Builder() {}
@@ -62,7 +62,7 @@ public class User extends UpdateAutoTimestampEntity implements Buildable {
@Id @Expose String emailAddress;
/** Optional external email address to use for registry lock confirmation emails. */
@Column String registryLockEmailAddress;
@Column @Expose String registryLockEmailAddress;
/** Roles (which grant permissions) associated with this user. */
@Expose
@@ -250,51 +250,50 @@ public class User extends UpdateAutoTimestampEntity implements Buildable {
}
@Override
public Builder<? extends User, ?> asBuilder() {
return new Builder<>(clone(this));
public Builder asBuilder() {
return new Builder(clone(this));
}
/** Builder for constructing immutable {@link User} objects. */
public static class Builder<T extends User, B extends Builder<T, B>>
extends GenericBuilder<T, B> {
public static class Builder extends Buildable.Builder<User> {
public Builder() {}
public Builder(T abstractUser) {
super(abstractUser);
public Builder(User user) {
super(user);
}
@Override
public T build() {
public User build() {
checkArgumentNotNull(getInstance().emailAddress, "Email address cannot be null");
checkArgumentNotNull(getInstance().userRoles, "User roles cannot be null");
return super.build();
}
public B setEmailAddress(String emailAddress) {
public Builder setEmailAddress(String emailAddress) {
getInstance().emailAddress = checkValidEmail(emailAddress);
return thisCastToDerived();
return this;
}
public B setRegistryLockEmailAddress(@Nullable String registryLockEmailAddress) {
public Builder setRegistryLockEmailAddress(@Nullable String registryLockEmailAddress) {
getInstance().registryLockEmailAddress =
registryLockEmailAddress == null ? null : checkValidEmail(registryLockEmailAddress);
return thisCastToDerived();
return this;
}
public B setUserRoles(UserRoles userRoles) {
public Builder setUserRoles(UserRoles userRoles) {
checkArgumentNotNull(userRoles, "User roles cannot be null");
getInstance().userRoles = userRoles;
return thisCastToDerived();
return this;
}
public B removeRegistryLockPassword() {
public Builder removeRegistryLockPassword() {
getInstance().registryLockPasswordHash = null;
getInstance().registryLockPasswordSalt = null;
return thisCastToDerived();
return this;
}
public B setRegistryLockPassword(String registryLockPassword) {
public Builder setRegistryLockPassword(String registryLockPassword) {
checkArgument(
getInstance().hasAnyRegistryLockPermission(), "User has no registry lock permission");
checkArgument(
@@ -304,7 +303,7 @@ public class User extends UpdateAutoTimestampEntity implements Buildable {
byte[] salt = SALT_SUPPLIER.get();
getInstance().registryLockPasswordSalt = base64().encode(salt);
getInstance().registryLockPasswordHash = hashPassword(registryLockPassword, salt);
return thisCastToDerived();
return this;
}
}
}
@@ -18,7 +18,7 @@ import static google.registry.util.CollectionUtils.forceEmptyToNull;
import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
import google.registry.model.Buildable.GenericBuilder;
import google.registry.model.Buildable;
import google.registry.model.ImmutableObject;
import google.registry.model.domain.Period;
import google.registry.model.domain.fee.Fee;
@@ -77,8 +77,7 @@ public class FeeCheckResponseExtensionItemCommandV12 extends ImmutableObject {
}
/** Builder for {@link FeeCheckResponseExtensionItemCommandV12}. */
public static class Builder
extends GenericBuilder<FeeCheckResponseExtensionItemCommandV12, Builder> {
public static class Builder extends Buildable.Builder<FeeCheckResponseExtensionItemCommandV12> {
public Builder setCommandName(CommandName commandName) {
getInstance().commandName = Ascii.toLowerCase(commandName.name());
@@ -690,8 +690,8 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
}
@Override
public Builder<? extends Registrar, ?> asBuilder() {
return new Builder<>(clone(this));
public Builder asBuilder() {
return new Builder(clone(this));
}
@Override
@@ -706,59 +706,58 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
}
/** A builder for constructing {@link Registrar}, since it is immutable. */
public static class Builder<T extends Registrar, B extends Builder<T, B>>
extends GenericBuilder<T, B> {
public static class Builder extends Buildable.Builder<Registrar> {
public Builder() {}
public Builder(T instance) {
public Builder(Registrar instance) {
super(instance);
}
public B setRegistrarId(String registrarId) {
public Builder setRegistrarId(String registrarId) {
// Registrar id must be [3,16] chars long. See "clIDType" in the base EPP schema of RFC 5730.
// (Need to validate this here as there's no matching EPP XSD for validation.)
checkArgument(
Range.closed(3, 16).contains(registrarId.length()),
"Registrar ID must be 3-16 characters long.");
getInstance().registrarId = registrarId;
return thisCastToDerived();
return this;
}
public B setIanaIdentifier(@Nullable Long ianaIdentifier) {
public Builder setIanaIdentifier(@Nullable Long ianaIdentifier) {
checkArgument(
ianaIdentifier == null || ianaIdentifier > 0, "IANA ID must be a positive number");
getInstance().ianaIdentifier = ianaIdentifier;
return thisCastToDerived();
return this;
}
public B setPoNumber(Optional<String> poNumber) {
public Builder setPoNumber(Optional<String> poNumber) {
getInstance().poNumber = poNumber.orElse(null);
return thisCastToDerived();
return this;
}
public B setBillingAccountMap(@Nullable Map<CurrencyUnit, String> billingAccountMap) {
public Builder setBillingAccountMap(@Nullable Map<CurrencyUnit, String> billingAccountMap) {
getInstance().billingAccountMap = nullToEmptyImmutableCopy(billingAccountMap);
return thisCastToDerived();
return this;
}
public B setRegistrarName(String registrarName) {
public Builder setRegistrarName(String registrarName) {
getInstance().registrarName = registrarName;
return thisCastToDerived();
return this;
}
public B setType(Type type) {
public Builder setType(Type type) {
getInstance().type = type;
return thisCastToDerived();
return this;
}
public B setState(State state) {
public Builder setState(State state) {
getInstance().state = state;
return thisCastToDerived();
return this;
}
public B setAllowedTlds(Set<String> allowedTlds) {
public Builder setAllowedTlds(Set<String> allowedTlds) {
getInstance().allowedTlds = ImmutableSortedSet.copyOf(assertTldsExist(allowedTlds));
return thisCastToDerived();
return this;
}
/**
@@ -771,7 +770,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
* {@code .now()} when saving the Registry entity to make sure it's actually saved before trying
* to set the allowed TLDs.
*/
public B setAllowedTldsUncached(Set<String> allowedTlds) {
public Builder setAllowedTldsUncached(Set<String> allowedTlds) {
ImmutableSet<VKey<Tld>> newTldKeys =
Sets.difference(allowedTlds, getInstance().getAllowedTlds()).stream()
.map(Tld::createVKey)
@@ -780,10 +779,10 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
Sets.difference(newTldKeys, tm().loadByKeysIfPresent(newTldKeys).keySet());
checkArgument(missingTldKeys.isEmpty(), "Trying to set nonexistent TLDs: %s", missingTldKeys);
getInstance().allowedTlds = ImmutableSortedSet.copyOf(allowedTlds);
return thisCastToDerived();
return this;
}
public B setClientCertificate(String clientCertificate, DateTime now) {
public Builder setClientCertificate(String clientCertificate, DateTime now) {
clientCertificate = emptyToNull(clientCertificate);
String clientCertificateHash = calculateHash(clientCertificate);
if (!Objects.equals(clientCertificate, getInstance().clientCertificate)
@@ -792,23 +791,23 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
getInstance().clientCertificateHash = clientCertificateHash;
getInstance().lastCertificateUpdateTime = now;
}
return thisCastToDerived();
return this;
}
public B setLastExpiringCertNotificationSentDate(DateTime now) {
public Builder setLastExpiringCertNotificationSentDate(DateTime now) {
checkArgumentNotNull(now, "Registrar lastExpiringCertNotificationSentDate cannot be null");
getInstance().lastExpiringCertNotificationSentDate = now;
return thisCastToDerived();
return this;
}
public B setLastExpiringFailoverCertNotificationSentDate(DateTime now) {
public Builder setLastExpiringFailoverCertNotificationSentDate(DateTime now) {
checkArgumentNotNull(
now, "Registrar lastExpiringFailoverCertNotificationSentDate cannot be null");
getInstance().lastExpiringFailoverCertNotificationSentDate = now;
return thisCastToDerived();
return this;
}
public B setFailoverClientCertificate(String clientCertificate, DateTime now) {
public Builder setFailoverClientCertificate(String clientCertificate, DateTime now) {
clientCertificate = emptyToNull(clientCertificate);
String clientCertificateHash = calculateHash(clientCertificate);
if (!Objects.equals(clientCertificate, getInstance().failoverClientCertificate)
@@ -817,13 +816,13 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
getInstance().failoverClientCertificateHash = clientCertificateHash;
getInstance().lastCertificateUpdateTime = now;
}
return thisCastToDerived();
return this;
}
public B setLastPocVerificationDate(DateTime now) {
public Builder setLastPocVerificationDate(DateTime now) {
checkArgumentNotNull(now, "Registrar lastPocVerificationDate cannot be null");
getInstance().lastPocVerificationDate = now;
return thisCastToDerived();
return this;
}
private static String calculateHash(String clientCertificate) {
@@ -855,75 +854,75 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
Objects.equals(newInstance.ianaIdentifier, registrar.getIanaIdentifier()));
}
public B setContactsRequireSyncing(boolean contactsRequireSyncing) {
public Builder setContactsRequireSyncing(boolean contactsRequireSyncing) {
getInstance().contactsRequireSyncing = contactsRequireSyncing;
return thisCastToDerived();
return this;
}
public B setIpAddressAllowList(Iterable<CidrAddressBlock> ipAddressAllowList) {
public Builder setIpAddressAllowList(Iterable<CidrAddressBlock> ipAddressAllowList) {
getInstance().ipAddressAllowList = ImmutableList.copyOf(ipAddressAllowList);
return thisCastToDerived();
return this;
}
public B setLocalizedAddress(RegistrarAddress localizedAddress) {
public Builder setLocalizedAddress(RegistrarAddress localizedAddress) {
getInstance().localizedAddress = localizedAddress;
return thisCastToDerived();
return this;
}
public B setInternationalizedAddress(RegistrarAddress internationalizedAddress) {
public Builder setInternationalizedAddress(RegistrarAddress internationalizedAddress) {
getInstance().internationalizedAddress = internationalizedAddress;
return thisCastToDerived();
return this;
}
public B setPhoneNumber(String phoneNumber) {
public Builder setPhoneNumber(String phoneNumber) {
getInstance().phoneNumber = (phoneNumber == null) ? null : checkValidPhoneNumber(phoneNumber);
return thisCastToDerived();
return this;
}
public B setFaxNumber(String faxNumber) {
public Builder setFaxNumber(String faxNumber) {
getInstance().faxNumber = (faxNumber == null) ? null : checkValidPhoneNumber(faxNumber);
return thisCastToDerived();
return this;
}
public B setEmailAddress(String emailAddress) {
public Builder setEmailAddress(String emailAddress) {
getInstance().emailAddress = checkValidEmail(emailAddress);
return thisCastToDerived();
return this;
}
public B setWhoisServer(String whoisServer) {
public Builder setWhoisServer(String whoisServer) {
getInstance().whoisServer = whoisServer;
return thisCastToDerived();
return this;
}
public B setRdapBaseUrls(Set<String> rdapBaseUrls) {
public Builder setRdapBaseUrls(Set<String> rdapBaseUrls) {
getInstance().rdapBaseUrls = ImmutableSet.copyOf(rdapBaseUrls);
return thisCastToDerived();
return this;
}
public B setBlockPremiumNames(boolean blockPremiumNames) {
public Builder setBlockPremiumNames(boolean blockPremiumNames) {
getInstance().blockPremiumNames = blockPremiumNames;
return thisCastToDerived();
return this;
}
public B setUrl(String url) {
public Builder setUrl(String url) {
getInstance().url = url;
return thisCastToDerived();
return this;
}
public B setIcannReferralEmail(String icannReferralEmail) {
public Builder setIcannReferralEmail(String icannReferralEmail) {
getInstance().icannReferralEmail = checkValidEmail(icannReferralEmail);
return thisCastToDerived();
return this;
}
public B setDriveFolderId(@Nullable String driveFolderId) {
public Builder setDriveFolderId(@Nullable String driveFolderId) {
checkArgument(
driveFolderId == null || !driveFolderId.contains("/"),
"Drive folder ID must not be a full URL");
getInstance().driveFolderId = driveFolderId;
return thisCastToDerived();
return this;
}
public B setPassword(String password) {
public Builder setPassword(String password) {
// Passwords must be [6,16] chars long. See "pwType" in the base EPP schema of RFC 5730.
checkArgument(
Range.closed(6, 16).contains(nullToEmpty(password).length()),
@@ -931,7 +930,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
byte[] salt = SALT_SUPPLIER.get();
getInstance().salt = base64().encode(salt);
getInstance().passwordHash = hashPassword(password, salt);
return thisCastToDerived();
return this;
}
/**
@@ -939,18 +938,18 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
*
* @throws IllegalArgumentException if provided passcode is not 5-digit numeric
*/
public B setPhonePasscode(String phonePasscode) {
public Builder setPhonePasscode(String phonePasscode) {
checkArgument(
phonePasscode == null || PHONE_PASSCODE_PATTERN.matcher(phonePasscode).matches(),
"Not a valid telephone passcode (must be 5 digits long): %s",
phonePasscode);
getInstance().phonePasscode = phonePasscode;
return thisCastToDerived();
return this;
}
public B setRegistryLockAllowed(boolean registryLockAllowed) {
public Builder setRegistryLockAllowed(boolean registryLockAllowed) {
getInstance().registryLockAllowed = registryLockAllowed;
return thisCastToDerived();
return this;
}
/**
@@ -958,14 +957,14 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
* and breaks the verification that an object has not been updated since it was copied.
*/
@VisibleForTesting
public B setLastUpdateTime(DateTime timestamp) {
public Builder setLastUpdateTime(DateTime timestamp) {
getInstance().setUpdateTimestamp(UpdateAutoTimestamp.create(timestamp));
return thisCastToDerived();
return this;
}
/** Build the registrar, nullifying empty fields. */
@Override
public T build() {
public Registrar build() {
checkArgumentNotNull(getInstance().type, "Registrar type cannot be null");
checkArgumentNotNull(getInstance().registrarName, "Registrar name cannot be null");
checkArgument(
@@ -31,7 +31,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.gson.annotations.Expose;
import google.registry.model.Buildable.GenericBuilder;
import google.registry.model.Buildable;
import google.registry.model.ImmutableObject;
import google.registry.model.JsonMapBuilder;
import google.registry.model.Jsonifiable;
@@ -225,8 +225,8 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
return visibleInDomainWhoisAsAbuse;
}
public Builder<? extends RegistrarPoc, ?> asBuilder() {
return new Builder<>(clone(this));
public Builder asBuilder() {
return new Builder(clone(this));
}
public boolean isAllowedToSetRegistryLockPassword() {
@@ -332,17 +332,16 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
}
/** A builder for constructing a {@link RegistrarPoc}, since it is immutable. */
public static class Builder<T extends RegistrarPoc, B extends Builder<T, B>>
extends GenericBuilder<T, B> {
public static class Builder extends Buildable.Builder<RegistrarPoc> {
public Builder() {}
protected Builder(T instance) {
protected Builder(RegistrarPoc instance) {
super(instance);
}
/** Build the registrar, nullifying empty fields. */
@Override
public T build() {
public RegistrarPoc build() {
checkNotNull(getInstance().registrarId, "Registrar ID cannot be null");
checkValidEmail(getInstance().emailAddress);
// Check allowedToSetRegistryLockPassword here because if we want to allow the user to set
@@ -356,71 +355,71 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
return cloneEmptyToNull(super.build());
}
public B setName(String name) {
public Builder setName(String name) {
getInstance().name = name;
return thisCastToDerived();
return this;
}
public B setEmailAddress(String emailAddress) {
public Builder setEmailAddress(String emailAddress) {
getInstance().emailAddress = emailAddress;
return thisCastToDerived();
return this;
}
public B setRegistryLockEmailAddress(@Nullable String registryLockEmailAddress) {
public Builder setRegistryLockEmailAddress(@Nullable String registryLockEmailAddress) {
getInstance().registryLockEmailAddress = registryLockEmailAddress;
return thisCastToDerived();
return this;
}
public B setPhoneNumber(String phoneNumber) {
public Builder setPhoneNumber(String phoneNumber) {
getInstance().phoneNumber = phoneNumber;
return thisCastToDerived();
return this;
}
public B setRegistrarId(String registrarId) {
public Builder setRegistrarId(String registrarId) {
getInstance().registrarId = registrarId;
return thisCastToDerived();
return this;
}
public B setRegistrar(Registrar registrar) {
public Builder setRegistrar(Registrar registrar) {
getInstance().registrarId = registrar.getRegistrarId();
return thisCastToDerived();
return this;
}
public B setFaxNumber(String faxNumber) {
public Builder setFaxNumber(String faxNumber) {
getInstance().faxNumber = faxNumber;
return thisCastToDerived();
return this;
}
public B setTypes(Iterable<Type> types) {
public Builder setTypes(Iterable<Type> types) {
getInstance().types = ImmutableSet.copyOf(types);
return thisCastToDerived();
return this;
}
public B setVisibleInWhoisAsAdmin(boolean visible) {
public Builder setVisibleInWhoisAsAdmin(boolean visible) {
getInstance().visibleInWhoisAsAdmin = visible;
return thisCastToDerived();
return this;
}
public B setVisibleInWhoisAsTech(boolean visible) {
public Builder setVisibleInWhoisAsTech(boolean visible) {
getInstance().visibleInWhoisAsTech = visible;
return thisCastToDerived();
return this;
}
public B setVisibleInDomainWhoisAsAbuse(boolean visible) {
public Builder setVisibleInDomainWhoisAsAbuse(boolean visible) {
getInstance().visibleInDomainWhoisAsAbuse = visible;
return thisCastToDerived();
return this;
}
public B setAllowedToSetRegistryLockPassword(boolean allowedToSetRegistryLockPassword) {
public Builder setAllowedToSetRegistryLockPassword(boolean allowedToSetRegistryLockPassword) {
if (allowedToSetRegistryLockPassword) {
getInstance().registryLockPasswordSalt = null;
getInstance().registryLockPasswordHash = null;
}
getInstance().allowedToSetRegistryLockPassword = allowedToSetRegistryLockPassword;
return thisCastToDerived();
return this;
}
public B setRegistryLockPassword(String registryLockPassword) {
public Builder setRegistryLockPassword(String registryLockPassword) {
checkArgument(
getInstance().allowedToSetRegistryLockPassword,
"Not allowed to set registry lock password for this contact");
@@ -430,7 +429,7 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
getInstance().registryLockPasswordSalt = base64().encode(salt);
getInstance().registryLockPasswordHash = hashPassword(registryLockPassword, salt);
getInstance().allowedToSetRegistryLockPassword = false;
return thisCastToDerived();
return this;
}
}
@@ -95,10 +95,4 @@ public class SignedMarkRevocationList extends ImmutableObject {
public int size() {
return revokes.size();
}
/** Save this list to Cloud SQL. Returns {@code this}. */
public SignedMarkRevocationList save() {
SignedMarkRevocationListDao.save(this);
return this;
}
}
@@ -44,11 +44,25 @@ public class SignedMarkRevocationListDao {
return smdrl.orElseGet(() -> SignedMarkRevocationList.create(START_OF_TIME, ImmutableMap.of()));
}
/** Save the given {@link SignedMarkRevocationList} */
static void save(SignedMarkRevocationList signedMarkRevocationList) {
tm().transact(() -> tm().insert(signedMarkRevocationList));
/**
* Persists a {@link SignedMarkRevocationList} instance and returns the persisted entity.
*
* <p>Note that the input parameter is untouched. Use the returned object if metadata fields like
* {@code revisionId} are needed.
*/
public static SignedMarkRevocationList save(SignedMarkRevocationList signedMarkRevocationList) {
var persisted =
tm().transact(
() -> {
var entity =
SignedMarkRevocationList.create(
signedMarkRevocationList.getCreationTime(),
ImmutableMap.copyOf(signedMarkRevocationList.revokes));
tm().insert(entity);
return entity;
});
logger.atInfo().log(
"Inserted %,d signed mark revocations into Cloud SQL.",
signedMarkRevocationList.revokes.size());
"Inserted %,d signed mark revocations into Cloud SQL.", persisted.revokes.size());
return persisted;
}
}
@@ -133,24 +133,30 @@ public final class PremiumListDao {
}
/** Saves the given premium list (and its premium list entries) to Cloud SQL. */
public static PremiumList save(PremiumList premiumList) {
tm().transact(
() -> {
tm().insert(premiumList);
tm().getEntityManager().flush(); // This populates the revisionId.
long revisionId = premiumList.getRevisionId();
public static PremiumList save(PremiumList premiumListToPersist) {
PremiumList persisted =
tm().transact(
() -> {
// Make a new copy in each attempt to insert. See javadoc of the insert method for
// more information.
PremiumList premiumList = premiumListToPersist.asBuilder().build();
tm().insert(premiumList);
tm().getEntityManager().flush(); // This populates the revisionId.
long revisionId = premiumList.getRevisionId();
if (!isNullOrEmpty(premiumList.getLabelsToPrices())) {
ImmutableSet.Builder<PremiumEntry> entries = new ImmutableSet.Builder<>();
premiumList
.getLabelsToPrices()
.forEach(
(key, value) -> entries.add(PremiumEntry.create(revisionId, value, key)));
tm().insertAll(entries.build());
}
});
premiumListCache.invalidate(premiumList.getName());
return premiumList;
if (!isNullOrEmpty(premiumList.getLabelsToPrices())) {
ImmutableSet.Builder<PremiumEntry> entries = new ImmutableSet.Builder<>();
premiumList
.getLabelsToPrices()
.forEach(
(key, value) ->
entries.add(PremiumEntry.create(revisionId, value, key)));
tm().insertAll(entries.build());
}
return premiumList;
});
premiumListCache.invalidate(persisted.getName());
return persisted;
}
public static void delete(PremiumList premiumList) {
@@ -27,14 +27,26 @@ public class ReservedListDao {
private ReservedListDao() {}
/** Persist a new reserved list to Cloud SQL. */
public static void save(ReservedList reservedList) {
/**
* Persists a new reserved list to Cloud SQL and returns the persisted entity.
*
* <p>Note that the input parameter is untouched. Use the returned object if metadata fields like
* {@code revisionId} are needed.
*/
public static ReservedList save(ReservedList reservedList) {
checkArgumentNotNull(reservedList, "Must specify reservedList");
logger.atInfo().log("Saving reserved list %s to Cloud SQL.", reservedList.getName());
tm().transact(() -> tm().insert(reservedList));
var persisted =
tm().transact(
() -> {
var entity = reservedList.asBuilder().build();
tm().insert(entity);
return entity;
});
logger.atInfo().log(
"Saved reserved list %s with %d entries to Cloud SQL.",
reservedList.getName(), reservedList.getReservedListEntries().size());
return persisted;
}
/** Deletes a reserved list from Cloud SQL. */
@@ -49,10 +49,23 @@ public class ClaimsListDao {
return CacheUtils.newCacheBuilder(expiry).build(ignored -> ClaimsListDao.getUncached());
}
/** Saves the given {@link ClaimsList} to Cloud SQL. */
public static void save(ClaimsList claimsList) {
tm().transact(() -> tm().insert(claimsList));
CACHE.put(ClaimsListDao.class, claimsList);
/**
* Persists a {@link ClaimsList} instance and returns the persisted entity.
*
* <p>Note that the input parameter is untouched. Use the returned object if metadata fields like
* {@code revisionId} are needed.
*/
public static ClaimsList save(ClaimsList claimsList) {
var persisted =
tm().transact(
() -> {
var entity =
ClaimsList.create(claimsList.tmdbGenerationTime, claimsList.labelsToKeys);
tm().insert(entity);
return entity;
});
CACHE.put(ClaimsListDao.class, persisted);
return persisted;
}
/** Returns the most recent revision of the {@link ClaimsList} from the cache. */
@@ -115,6 +115,7 @@ import google.registry.ui.server.console.ConsoleDomainGetAction;
import google.registry.ui.server.console.ConsoleDomainListAction;
import google.registry.ui.server.console.ConsoleDumDownloadAction;
import google.registry.ui.server.console.ConsoleEppPasswordAction;
import google.registry.ui.server.console.ConsoleHistoryDataAction;
import google.registry.ui.server.console.ConsoleModule;
import google.registry.ui.server.console.ConsoleOteAction;
import google.registry.ui.server.console.ConsoleRegistryLockAction;
@@ -185,6 +186,8 @@ interface RequestComponent {
ConsoleEppPasswordAction consoleEppPasswordAction();
ConsoleHistoryDataAction consoleHistoryDataAction();
ConsoleOteAction consoleOteAction();
ConsoleRegistryLockAction consoleRegistryLockAction();
@@ -344,6 +344,18 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
return txnInfo.transactionTime;
}
/**
* Inserts an object into the database.
*
* <p>If {@code entity} has an auto-generated identity field (i.e., a field annotated with {@link
* jakarta.persistence.GeneratedValue}), the caller must not assign a value to this field,
* otherwise Hibernate would mistake the entity as detached and raise an error.
*
* <p>The practical implication of the above is that when inserting such an entity using a
* retriable transaction , the entity should be instantiated inside the transaction body. A failed
* attempt may still assign and ID to the entity, therefore reusing the same entity would cause
* retries to fail.
*/
@Override
public void insert(Object entity) {
checkArgumentNotNull(entity, "entity must be specified");
@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import google.registry.keyring.api.KeyModule.Key;
import google.registry.model.smd.SignedMarkRevocationList;
import google.registry.model.smd.SignedMarkRevocationListDao;
import google.registry.request.Action;
import google.registry.request.Action.GaeService;
import google.registry.request.auth.Auth;
@@ -57,7 +58,7 @@ public final class TmchSmdrlAction implements Runnable {
} catch (GeneralSecurityException | IOException | PGPException e) {
throw new RuntimeException(e);
}
smdrl.save();
smdrl = SignedMarkRevocationListDao.save(smdrl);
logger.atInfo().log(
"Inserted %,d smd revocations into the database, created at %s.",
smdrl.size(), smdrl.getCreationTime());
@@ -23,6 +23,7 @@ import com.google.common.flogger.FluentLogger;
import com.google.common.net.MediaType;
import google.registry.config.RegistryConfig.Config;
import google.registry.model.console.ConsolePermission;
import google.registry.model.console.ConsoleUpdateHistory;
import google.registry.model.console.User;
import google.registry.request.Action;
import google.registry.request.Action.GaeService;
@@ -98,6 +99,13 @@ public class ConsoleDumDownloadAction extends ConsoleApiAction {
consoleApiParams.response().setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
tm().transact(
() -> {
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()
.setType(ConsoleUpdateHistory.Type.DUM_DOWNLOAD)
.setDescription(registrarId));
});
consoleApiParams.response().setStatus(HttpServletResponse.SC_OK);
}
@@ -0,0 +1,116 @@
// Copyright 2025 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.ui.server.console;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.GET;
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
import com.google.common.base.Strings;
import google.registry.model.console.ConsolePermission;
import google.registry.model.console.ConsoleUpdateHistory;
import google.registry.model.console.User;
import google.registry.request.Action;
import google.registry.request.Action.GaeService;
import google.registry.request.Action.GkeService;
import google.registry.request.Parameter;
import google.registry.request.auth.Auth;
import jakarta.inject.Inject;
import java.util.List;
import java.util.Optional;
@Action(
service = GaeService.DEFAULT,
gkeService = GkeService.CONSOLE,
path = ConsoleHistoryDataAction.PATH,
method = {GET},
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
public class ConsoleHistoryDataAction extends ConsoleApiAction {
private static final String SQL_USER_HISTORY =
"""
SELECT * FROM "ConsoleUpdateHistory"
WHERE acting_user = :actingUser
""";
private static final String SQL_REGISTRAR_HISTORY =
"""
SELECT *
FROM "ConsoleUpdateHistory"
WHERE SPLIT_PART(description, '|', 1) = :registrarId;
""";
public static final String PATH = "/console-api/history";
private final String registrarId;
private final Optional<String> consoleUserEmail;
@Inject
public ConsoleHistoryDataAction(
ConsoleApiParams consoleApiParams,
@Parameter("registrarId") String registrarId,
@Parameter("consoleUserEmail") Optional<String> consoleUserEmail) {
super(consoleApiParams);
this.registrarId = registrarId;
this.consoleUserEmail = consoleUserEmail;
}
@Override
protected void getHandler(User user) {
if (this.consoleUserEmail.isPresent()) {
this.historyByUser(user, this.consoleUserEmail.get());
return;
}
this.historyByRegistrarId(user, this.registrarId);
}
private void historyByUser(User user, String consoleUserEmail) {
if (!user.getUserRoles().hasGlobalPermission(ConsolePermission.AUDIT_ACTIVITY_BY_USER)) {
setFailedResponse(
"User doesn't have a permission to check audit activity by user", SC_BAD_REQUEST);
return;
}
List<ConsoleUpdateHistory> queryResult =
tm().transact(
() ->
tm().getEntityManager()
.createNativeQuery(SQL_USER_HISTORY, ConsoleUpdateHistory.class)
.setParameter("actingUser", consoleUserEmail)
.setHint("org.hibernate.fetchSize", 1000)
.getResultList());
consoleApiParams.response().setPayload(consoleApiParams.gson().toJson(queryResult));
consoleApiParams.response().setStatus(SC_OK);
}
private void historyByRegistrarId(User user, String registrarId) {
checkArgument(!Strings.isNullOrEmpty(registrarId), "Empty registrarId param");
checkPermission(user, registrarId, ConsolePermission.AUDIT_ACTIVITY_BY_REGISTRAR);
List<ConsoleUpdateHistory> queryResult =
tm().transact(
() ->
tm().getEntityManager()
.createNativeQuery(SQL_REGISTRAR_HISTORY, ConsoleUpdateHistory.class)
.setParameter("registrarId", registrarId)
.setHint("org.hibernate.fetchSize", 1000)
.getResultList());
consoleApiParams.response().setPayload(consoleApiParams.gson().toJson(queryResult));
consoleApiParams.response().setStatus(SC_OK);
}
}
@@ -14,10 +14,12 @@
package google.registry.ui.server.console;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.GET;
import com.google.common.base.Ascii;
import com.google.gson.annotations.Expose;
import google.registry.model.console.ConsoleUpdateHistory;
import google.registry.model.console.User;
import google.registry.model.domain.RegistryLock;
import google.registry.request.Action;
@@ -64,6 +66,21 @@ public class ConsoleRegistryLockVerifyAction extends ConsoleApiAction {
RegistryLockVerificationResponse lockResponse =
new RegistryLockVerificationResponse(
Ascii.toLowerCase(action.toString()), lock.getDomainName(), lock.getRegistrarId());
tm().transact(
() -> {
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()
.setType(
action == RegistryLockAction.LOCKED
? ConsoleUpdateHistory.Type.REGISTRY_LOCK
: ConsoleUpdateHistory.Type.REGISTRY_UNLOCK)
.setDescription(
String.format(
"%s%s%s",
lock.getRegistrarId(),
ConsoleUpdateHistory.DESCRIPTION_SEPARATOR,
lockResponse)));
});
consoleApiParams.response().setPayload(consoleApiParams.gson().toJson(lockResponse));
consoleApiParams.response().setStatus(HttpServletResponse.SC_OK);
}
@@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.gson.annotations.Expose;
import google.registry.config.RegistryConfig.Config;
import google.registry.model.console.ConsolePermission;
import google.registry.model.console.ConsoleUpdateHistory;
import google.registry.model.console.RegistrarRole;
import google.registry.model.console.User;
import google.registry.model.console.UserRoles;
@@ -118,6 +119,7 @@ public class ConsoleUsersAction extends ConsoleApiAction {
u ->
new UserData(
u.getEmailAddress(),
u.getRegistryLockEmailAddress().orElse(null),
u.getUserRoles().getRegistrarRoles().get(registrarId).toString(),
null))
.collect(Collectors.toList());
@@ -177,6 +179,12 @@ public class ConsoleUsersAction extends ConsoleApiAction {
tm().delete(key);
User.revokeIapPermission(email, maybeGroupEmailAddress, cloudTasksUtils, null, iamClient);
sendConfirmationEmail(registrarId, email, "Deleted user");
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()
.setType(ConsoleUpdateHistory.Type.USER_DELETE)
.setDescription(
String.format(
"%s%s%s", registrarId, ConsoleUpdateHistory.DESCRIPTION_SEPARATOR, email)));
}
consoleApiParams.response().setStatus(SC_OK);
@@ -230,7 +238,15 @@ public class ConsoleUsersAction extends ConsoleApiAction {
.setPayload(
consoleApiParams
.gson()
.toJson(new UserData(newEmail, ACCOUNT_MANAGER.toString(), newUser.getPassword())));
.toJson(
new UserData(
newEmail, null, ACCOUNT_MANAGER.toString(), newUser.getPassword())));
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()
.setType(ConsoleUpdateHistory.Type.USER_CREATE)
.setDescription(
String.format(
"%s%s%s", registrarId, ConsoleUpdateHistory.DESCRIPTION_SEPARATOR, newEmail)));
}
private void runUpdateInTransaction() {
@@ -245,6 +261,15 @@ public class ConsoleUsersAction extends ConsoleApiAction {
sendConfirmationEmail(registrarId, this.userData.get().emailAddress, "Updated user");
consoleApiParams.response().setStatus(SC_OK);
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()
.setType(ConsoleUpdateHistory.Type.USER_UPDATE)
.setDescription(
String.format(
"%s%s%s",
registrarId,
ConsoleUpdateHistory.DESCRIPTION_SEPARATOR,
this.userData.get().emailAddress)));
}
private boolean isModifyingRequestValid() {
@@ -323,5 +348,8 @@ public class ConsoleUsersAction extends ConsoleApiAction {
}
public record UserData(
@Expose String emailAddress, @Expose String role, @Expose @Nullable String password) {}
@Expose String emailAddress,
@Expose String registryLockEmailAddress,
@Expose String role,
@Expose @Nullable String password) {}
}
@@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.flogger.FluentLogger;
import google.registry.model.console.ConsolePermission;
import google.registry.model.console.ConsoleUpdateHistory;
import google.registry.model.console.User;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarPoc;
@@ -84,6 +85,7 @@ public class ContactAction extends ConsoleApiAction {
protected void deleteHandler(User user) {
updateContacts(
user,
"Deleted " + contact.get().getEmailAddress(),
(registrar, oldContacts) ->
oldContacts.stream()
.filter(
@@ -96,6 +98,7 @@ public class ContactAction extends ConsoleApiAction {
protected void postHandler(User user) {
updateContacts(
user,
"Created " + contact.get().getEmailAddress(),
(registrar, oldContacts) -> {
RegistrarPoc newContact = contact.get();
return ImmutableSet.<RegistrarPoc>builder()
@@ -121,6 +124,7 @@ public class ContactAction extends ConsoleApiAction {
protected void putHandler(User user) {
updateContacts(
user,
"Updated " + contact.get().getEmailAddress(),
(registrar, oldContacts) -> {
RegistrarPoc updatedContact = contact.get();
return oldContacts.stream()
@@ -146,6 +150,7 @@ public class ContactAction extends ConsoleApiAction {
private void updateContacts(
User user,
String historyDescription,
BiFunction<Registrar, ImmutableSet<RegistrarPoc>, ImmutableSet<RegistrarPoc>>
contactsUpdater) {
checkPermission(user, registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS);
@@ -176,6 +181,15 @@ public class ContactAction extends ConsoleApiAction {
tm().put(updatedRegistrar);
sendExternalUpdatesIfNecessary(
EmailInfo.create(registrar, updatedRegistrar, oldContacts, newContacts));
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()
.setType(ConsoleUpdateHistory.Type.REGISTRAR_CONTACTS_UPDATE)
.setDescription(
String.format(
"%s%s%s",
registrarId,
ConsoleUpdateHistory.DESCRIPTION_SEPARATOR,
historyDescription)));
});
consoleApiParams.response().setStatus(SC_OK);
}
@@ -35,6 +35,7 @@ import google.registry.ui.server.console.ConsoleApiAction;
import google.registry.ui.server.console.ConsoleApiParams;
import jakarta.inject.Inject;
import java.util.Optional;
import java.util.StringJoiner;
/**
* Console action for editing fields on a registrar that are visible in WHOIS/RDAP.
@@ -82,19 +83,37 @@ public class RdapRegistrarFieldsAction extends ConsoleApiAction {
return;
}
Registrar newRegistrar =
savedRegistrar
.asBuilder()
.setLocalizedAddress(providedRegistrar.getLocalizedAddress())
.setPhoneNumber(providedRegistrar.getPhoneNumber())
.setFaxNumber(providedRegistrar.getFaxNumber())
.setEmailAddress(providedRegistrar.getEmailAddress())
.build();
StringJoiner updates = new StringJoiner(",");
var newRegistrarBuilder = savedRegistrar.asBuilder();
if (!providedRegistrar.getLocalizedAddress().equals(savedRegistrar.getLocalizedAddress())) {
newRegistrarBuilder.setLocalizedAddress(providedRegistrar.getLocalizedAddress());
updates.add("ADDRESS");
}
if (!providedRegistrar.getPhoneNumber().equals(savedRegistrar.getPhoneNumber())) {
newRegistrarBuilder.setPhoneNumber(providedRegistrar.getPhoneNumber());
updates.add("PHONE");
}
if (!providedRegistrar.getFaxNumber().equals(savedRegistrar.getPhoneNumber())) {
newRegistrarBuilder.setFaxNumber(providedRegistrar.getFaxNumber());
updates.add("FAX");
}
if (!providedRegistrar.getEmailAddress().equals(savedRegistrar.getEmailAddress())) {
newRegistrarBuilder.setEmailAddress(providedRegistrar.getEmailAddress());
updates.add("EMAIL");
}
var newRegistrar = newRegistrarBuilder.build();
tm().put(newRegistrar);
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()
.setType(ConsoleUpdateHistory.Type.REGISTRAR_UPDATE)
.setDescription(newRegistrar.getRegistrarId()));
.setDescription(
String.format(
"%s%s%s",
newRegistrar.getRegistrarId(),
ConsoleUpdateHistory.DESCRIPTION_SEPARATOR,
updates)));
sendExternalUpdatesIfNecessary(
EmailInfo.create(
savedRegistrar,
@@ -39,6 +39,7 @@ import google.registry.ui.server.console.ConsoleApiAction;
import google.registry.ui.server.console.ConsoleApiParams;
import jakarta.inject.Inject;
import java.util.Optional;
import java.util.StringJoiner;
@Action(
service = GaeService.DEFAULT,
@@ -86,10 +87,15 @@ public class SecurityAction extends ConsoleApiAction {
private void setResponse(Registrar savedRegistrar) {
Registrar registrarParameter = registrar.get();
Registrar.Builder updatedRegistrarBuilder =
savedRegistrar
.asBuilder()
.setIpAddressAllowList(registrarParameter.getIpAddressAllowList());
Registrar.Builder updatedRegistrarBuilder = savedRegistrar.asBuilder();
StringJoiner updates = new StringJoiner(",");
if (!savedRegistrar
.getIpAddressAllowList()
.equals(registrarParameter.getIpAddressAllowList())) {
updatedRegistrarBuilder.setIpAddressAllowList(registrarParameter.getIpAddressAllowList());
updates.add("IP_CHANGE");
}
try {
if (!savedRegistrar
@@ -99,6 +105,7 @@ public class SecurityAction extends ConsoleApiAction {
String newClientCert = registrarParameter.getClientCertificate().get();
certificateChecker.validateCertificate(newClientCert);
updatedRegistrarBuilder.setClientCertificate(newClientCert, tm().getTransactionTime());
updates.add("PRIMARY_SSL_CERT_CHANGE");
}
}
if (!savedRegistrar
@@ -109,6 +116,7 @@ public class SecurityAction extends ConsoleApiAction {
certificateChecker.validateCertificate(newFailoverCert);
updatedRegistrarBuilder.setFailoverClientCertificate(
newFailoverCert, tm().getTransactionTime());
updates.add("FAILOVER_SSL_CERT_CHANGE");
}
}
} catch (InsecureCertificateException e) {
@@ -121,7 +129,9 @@ public class SecurityAction extends ConsoleApiAction {
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()
.setType(ConsoleUpdateHistory.Type.REGISTRAR_SECURITY_UPDATE)
.setDescription(registrarId));
.setDescription(
String.format(
"%s%s%s", registrarId, ConsoleUpdateHistory.DESCRIPTION_SEPARATOR, updates)));
sendExternalUpdatesIfNecessary(
EmailInfo.create(savedRegistrar, updatedRegistrar, ImmutableSet.of(), ImmutableSet.of()));
@@ -27,7 +27,6 @@ import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
import static google.registry.testing.DatabaseHelper.persistDomainAsDeleted;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -287,7 +286,7 @@ class DeleteProberDataActionTest {
private static Set<ImmutableObject> persistDomainAndDescendants(String fqdn) {
Domain domain = persistDeletedDomain(fqdn, DELETION_TIME);
DomainHistory historyEntry =
persistSimpleResource(
persistResource(
new DomainHistory.Builder()
.setDomain(domain)
.setType(HistoryEntry.Type.DOMAIN_CREATE)
@@ -295,7 +294,7 @@ class DeleteProberDataActionTest {
.setModificationTime(DELETION_TIME.minusYears(3))
.build());
BillingEvent billingEvent =
persistSimpleResource(
persistResource(
new BillingEvent.Builder()
.setDomainHistory(historyEntry)
.setBillingTime(DELETION_TIME.plusYears(1))
@@ -307,7 +306,7 @@ class DeleteProberDataActionTest {
.setTargetId(fqdn)
.build());
PollMessage.OneTime pollMessage =
persistSimpleResource(
persistResource(
new PollMessage.OneTime.Builder()
.setHistoryEntry(historyEntry)
.setEventTime(DELETION_TIME)
@@ -315,7 +314,7 @@ class DeleteProberDataActionTest {
.setMsg("Domain registered")
.build());
GracePeriod gracePeriod =
persistSimpleResource(
persistResource(
GracePeriod.create(
ADD,
domain.getRepoId(),
@@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.JpaTransactionManagerExtension.makeRegistrar1;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.apache.http.HttpStatus.SC_OK;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -62,7 +62,8 @@ class SendExpiringCertificateNotificationEmailActionTest {
Kind update your account using the following steps:
1. Navigate to support and login using your %4$s@registry.example credentials.
2. Click Settings -> Privacy on the top left corner.
3. Click Edit and enter certificate string. 3. Click SaveRegards,Example Registry""";
3. Click Edit and enter certificate string. 3. Click SaveRegards,Example Registry\
""";
private static final String EXPIRATION_WARNING_EMAIL_SUBJECT_TEXT = "Expiration Warning Email";
@@ -223,7 +224,7 @@ class SendExpiringCertificateNotificationEmailActionTest {
.setVisibleInWhoisAsAdmin(true)
.setVisibleInWhoisAsTech(false)
.build());
persistSimpleResources(contacts);
persistResources(contacts);
RuntimeException thrown =
assertThrows(
RuntimeException.class,
@@ -548,7 +549,7 @@ class SendExpiringCertificateNotificationEmailActionTest {
.setTypes(ImmutableSet.of(RegistrarPoc.Type.ADMIN))
.setVisibleInWhoisAsTech(true)
.build());
persistSimpleResources(contacts);
persistResources(contacts);
assertThat(action.getEmailAddresses(registrar, Type.TECH))
.containsExactly(
new InternetAddress("will@example-registrar.tld"),
@@ -700,7 +701,7 @@ class SendExpiringCertificateNotificationEmailActionTest {
/** Returns persisted sample contacts with a customized contact email type. */
private static ImmutableList<RegistrarPoc> persistSampleContacts(
Registrar registrar, RegistrarPoc.Type emailType) {
return persistSimpleResources(
return persistResources(
ImmutableList.of(
new RegistrarPoc.Builder()
.setRegistrar(registrar)
@@ -15,9 +15,10 @@
package google.registry.beam.common;
import static google.registry.persistence.transaction.JpaTransactionManagerExtension.makeRegistrar1;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.newContact;
import static google.registry.testing.DatabaseHelper.newTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
@@ -75,7 +76,7 @@ public class RegistryJpaReadTest {
@BeforeEach
void beforeEach() {
Registrar ofyRegistrar = JpaIntegrationTestExtension.makeRegistrar2();
insertInDb(ofyRegistrar);
persistResource(ofyRegistrar);
ImmutableList.Builder<Contact> builder = new ImmutableList.Builder<>();
@@ -84,7 +85,7 @@ public class RegistryJpaReadTest {
builder.add(contact);
}
contacts = builder.build();
insertInDb(contacts);
persistResources(contacts);
}
@Test
@@ -211,6 +212,6 @@ public class RegistryJpaReadTest {
null,
100L))
.build();
insertInDb(registry, registrar, contact, domain);
persistResources(registry, registrar, contact, domain);
}
}
@@ -30,7 +30,6 @@ import static google.registry.rde.RdeResourceType.DOMAIN;
import static google.registry.rde.RdeResourceType.HOST;
import static google.registry.rde.RdeResourceType.REGISTRAR;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.insertSimpleResources;
import static google.registry.testing.DatabaseHelper.newDomain;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
@@ -38,6 +37,7 @@ import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistEppResource;
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertThrows;
@@ -223,7 +223,7 @@ public class RdePipelineTest {
@BeforeEach
void beforeEach() throws Exception {
insertSimpleResources(ImmutableList.of(makeRegistrar1(), makeRegistrar2()));
persistResources(ImmutableList.of(makeRegistrar1(), makeRegistrar2()));
// Two real registrars have been created by loadInitialData(), named "New Registrar" and "The
// Registrar". Create one included registrar (external_monitoring) and two excluded ones.
@@ -403,7 +403,8 @@ public class RdePipelineTest {
<rdeDomain:crRr>TheRegistrar</rdeDomain:crRr>
<rdeDomain:crDate>1970-01-01T00:00:00Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54Z</rdeDomain:exDate>
</rdeDomain:domain>""");
</rdeDomain:domain>\
""");
}
if (kv.getKey().mode().equals(FULL)) {
// Contact fragments for hello.soy.
@@ -441,7 +442,8 @@ public class RdePipelineTest {
<rdeDomain:crRr>TheRegistrar</rdeDomain:crRr>
<rdeDomain:crDate>1970-01-01T00:00:00Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54Z</rdeDomain:exDate>
</rdeDomain:domain>""");
</rdeDomain:domain>\
""");
} else {
// Contact fragments for cat.fun.
assertThat(
@@ -484,7 +486,8 @@ public class RdePipelineTest {
<rdeDomain:crRr>TheRegistrar</rdeDomain:crRr>
<rdeDomain:crDate>1970-01-01T00:00:00Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54Z</rdeDomain:exDate>
</rdeDomain:domain>""");
</rdeDomain:domain>\
""");
}
});
return null;
@@ -23,7 +23,7 @@ import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.DatabaseHelper.persistResources;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.joda.time.DateTimeZone.UTC;
@@ -179,7 +179,7 @@ public class SyncRegistrarsSheetTest {
.build());
// Use registrar key for contacts' parent.
DateTime registrarCreationTime = persistResource(registrar).getCreationTime();
persistSimpleResources(contacts);
persistResources(contacts);
clock.advanceBy(standardMinutes(1));
newSyncRegistrarsSheet().run("foobar");
@@ -182,6 +182,43 @@ class ContactDeleteFlowTest extends ResourceFlowTestCase<ContactDeleteFlow, Cont
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@Test
void testSuccess_clientDeleteProhibited_superuser() throws Exception {
persistResource(
persistActiveContact(getUniqueIdFromCommand())
.asBuilder()
.addStatusValue(StatusValue.CLIENT_DELETE_PROHIBITED)
.build());
runFlowAssertResponse(
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("contact_delete_response.xml"));
}
@Test
void testSuccess_serverDeleteProhibited_superuser() throws Exception {
persistResource(
persistActiveContact(getUniqueIdFromCommand())
.asBuilder()
.addStatusValue(StatusValue.SERVER_DELETE_PROHIBITED)
.build());
runFlowAssertResponse(
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("contact_delete_response.xml"));
}
@Test
void testFailure_pendingDelete_superuser() throws Exception {
persistResource(
persistActiveContact(getUniqueIdFromCommand())
.asBuilder()
.addStatusValue(StatusValue.PENDING_DELETE)
.build());
assertAboutEppExceptions()
.that(
assertThrows(
ResourceStatusProhibitsOperationException.class,
() -> runFlow(CommitMode.LIVE, UserPrivileges.SUPERUSER)))
.marshalsToXml();
}
@Test
void testFailure_unauthorizedClient() throws Exception {
sessionMetadata.setRegistrarId("NewRegistrar");
@@ -179,6 +179,7 @@ import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.HistoryEntry.HistoryEntryId;
import google.registry.model.smd.SignedMarkRevocationListDao;
import google.registry.model.tld.Tld;
import google.registry.model.tld.Tld.TldState;
import google.registry.model.tld.Tld.TldType;
@@ -2727,8 +2728,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
@Test
void testFail_startDateSunriseRegistration_revokedSignedMark() throws Exception {
SmdrlCsvParser.parse(TmchTestData.loadFile("smd/smdrl.csv").lines().collect(toImmutableList()))
.save();
SignedMarkRevocationListDao.save(
SmdrlCsvParser.parse(
TmchTestData.loadFile("smd/smdrl.csv").lines().collect(toImmutableList())));
createTld("tld", START_DATE_SUNRISE);
clock.setTo(SMD_VALID_TIME);
String revokedSmd =
@@ -2753,9 +2755,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
if (labels.isEmpty()) {
return;
}
SmdrlCsvParser.parse(
TmchTestData.loadFile("idn/idn_smdrl.csv").lines().collect(toImmutableList()))
.save();
SignedMarkRevocationListDao.save(
SmdrlCsvParser.parse(
TmchTestData.loadFile("idn/idn_smdrl.csv").lines().collect(toImmutableList())));
createTld("tld", START_DATE_SUNRISE);
clock.setTo(SMD_VALID_TIME);
String revokedSmd =
@@ -917,6 +917,52 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
assertThat(thrown).hasMessageThat().contains("pendingDelete");
}
@Test
void testSuccess_clientDeleteProhibited_superuser() throws Exception {
eppRequestSource = EppRequestSource.TOOL;
setEppInput(
"domain_delete_superuser_extension.xml",
ImmutableMap.of("REDEMPTION_GRACE_PERIOD_DAYS", "15", "PENDING_DELETE_DAYS", "0"));
setUpSuccessfulTest();
persistResource(
domain.asBuilder().addStatusValue(StatusValue.CLIENT_DELETE_PROHIBITED).build());
clock.advanceOneMilli();
runFlowAssertResponse(
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("domain_delete_response_pending.xml"));
}
@Test
void testSuccess_serverDeleteProhibited_superuser() throws Exception {
eppRequestSource = EppRequestSource.TOOL;
setEppInput(
"domain_delete_superuser_extension.xml",
ImmutableMap.of("REDEMPTION_GRACE_PERIOD_DAYS", "15", "PENDING_DELETE_DAYS", "0"));
setUpSuccessfulTest();
persistResource(
domain.asBuilder().addStatusValue(StatusValue.SERVER_DELETE_PROHIBITED).build());
clock.advanceOneMilli();
runFlowAssertResponse(
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("domain_delete_response_pending.xml"));
}
@Test
void testFailure_pendingDelete_superuser() throws Exception {
eppRequestSource = EppRequestSource.TOOL;
setEppInput(
"domain_delete_superuser_extension.xml",
ImmutableMap.of("REDEMPTION_GRACE_PERIOD_DAYS", "15", "PENDING_DELETE_DAYS", "0"));
setUpSuccessfulTest();
persistResource(domain.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build());
ResourceStatusProhibitsOperationException thrown =
assertThrows(
ResourceStatusProhibitsOperationException.class,
() -> runFlow(CommitMode.LIVE, UserPrivileges.SUPERUSER));
assertThat(thrown).hasMessageThat().contains("pendingDelete");
}
@Test
void testSuccess_metadata() throws Exception {
eppRequestSource = EppRequestSource.TOOL;
@@ -150,53 +150,50 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
StatusValue... statusValues)
throws Exception {
Domain domain = DatabaseHelper.newDomain(getUniqueIdFromCommand());
tm().transact(
() -> {
try {
DomainHistory historyEntryDomainCreate =
new DomainHistory.Builder()
.setDomain(domain)
.setType(HistoryEntry.Type.DOMAIN_CREATE)
.setModificationTime(clock.nowUtc())
.setRegistrarId(domain.getCreationRegistrarId())
.build();
BillingRecurrence autorenewEvent =
new BillingRecurrence.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
.setEventTime(expirationTime)
.setRecurrenceEndTime(END_OF_TIME)
.setDomainHistory(historyEntryDomainCreate)
.setRenewalPriceBehavior(renewalPriceBehavior)
.setRenewalPrice(renewalPrice)
.build();
PollMessage.Autorenew autorenewPollMessage =
new PollMessage.Autorenew.Builder()
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
.setEventTime(expirationTime)
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntryDomainCreate)
.build();
Domain newDomain =
domain
.asBuilder()
.setRegistrationExpirationTime(expirationTime)
.setStatusValues(ImmutableSet.copyOf(statusValues))
.setAutorenewBillingEvent(autorenewEvent.createVKey())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.build();
persistResources(
ImmutableSet.of(
historyEntryDomainCreate, autorenewEvent,
autorenewPollMessage, newDomain));
} catch (Exception e) {
throw new RuntimeException("Error persisting domain", e);
}
});
try {
DomainHistory historyEntryDomainCreate =
new DomainHistory.Builder()
.setDomain(domain)
.setType(HistoryEntry.Type.DOMAIN_CREATE)
.setModificationTime(clock.nowUtc())
.setRegistrarId(domain.getCreationRegistrarId())
.build();
BillingRecurrence autorenewEvent =
new BillingRecurrence.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
.setEventTime(expirationTime)
.setRecurrenceEndTime(END_OF_TIME)
.setDomainHistory(historyEntryDomainCreate)
.setRenewalPriceBehavior(renewalPriceBehavior)
.setRenewalPrice(renewalPrice)
.build();
PollMessage.Autorenew autorenewPollMessage =
new PollMessage.Autorenew.Builder()
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
.setEventTime(expirationTime)
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntryDomainCreate)
.build();
Domain newDomain =
domain
.asBuilder()
.setRegistrationExpirationTime(expirationTime)
.setStatusValues(ImmutableSet.copyOf(statusValues))
.setAutorenewBillingEvent(autorenewEvent.createVKey())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.build();
persistResources(
ImmutableSet.of(
historyEntryDomainCreate, autorenewEvent,
autorenewPollMessage, newDomain));
} catch (Exception e) {
throw new RuntimeException("Error persisting domain", e);
}
clock.advanceOneMilli();
}
@@ -346,18 +346,18 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
}
@Test
void testFailure_minimumDatasetPhase2_nonRegistrantContactsStillExist() throws Exception {
void testFailure_minimumDatasetPhase2_whenAddingNewContacts() throws Exception {
persistResource(
new FeatureFlag.Builder()
.setFeatureName(MINIMUM_DATASET_CONTACTS_PROHIBITED)
.setStatusMap(
ImmutableSortedMap.of(START_OF_TIME, INACTIVE, clock.nowUtc().minusDays(5), ACTIVE))
.build());
// This EPP adds a new technical contact mak21 that wasn't already present.
setEppInput("domain_update_empty_registrant.xml");
persistReferencedEntities();
persistDomain();
// Fails because after the update the domain would still have some contacts on it even though
// the registrant has been removed.
// Fails because the update adds some new contacts, although the registrant has been removed.
ContactsProhibitedException thrown =
assertThrows(ContactsProhibitedException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@@ -1574,14 +1574,13 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
}
@Test
void testFailure_minimumDatasetPhase2_registrantStillExists() throws Exception {
void testFailure_minimumDatasetPhase2_addingNewRegistrantFails() throws Exception {
persistResource(
new FeatureFlag.Builder()
.setFeatureName(MINIMUM_DATASET_CONTACTS_PROHIBITED)
.setStatusMap(
ImmutableSortedMap.of(START_OF_TIME, INACTIVE, clock.nowUtc().minusDays(5), ACTIVE))
.build());
setEppInput("domain_update_remove_admin.xml");
persistReferencedEntities();
persistResource(
DatabaseHelper.newDomain(getUniqueIdFromCommand())
@@ -1590,7 +1589,10 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
ImmutableSet.of(
DesignatedContact.create(Type.ADMIN, sh8013Contact.createVKey()),
DesignatedContact.create(Type.TECH, sh8013Contact.createVKey())))
.setRegistrant(Optional.empty())
.build());
// This EPP sets the registrant to sh8013, whereas in our test setup it is absent.
setEppInput("domain_update_registrant.xml");
RegistrantProhibitedException thrown =
assertThrows(RegistrantProhibitedException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@@ -1657,6 +1659,32 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
assertThat(updatedDomain.getContacts()).isEmpty();
}
@Test
void testSuccess_minimumDatasetPhase2_removeOneContact() throws Exception {
persistResource(
new FeatureFlag.Builder()
.setFeatureName(MINIMUM_DATASET_CONTACTS_PROHIBITED)
.setStatusMap(
ImmutableSortedMap.of(START_OF_TIME, INACTIVE, clock.nowUtc().minusDays(5), ACTIVE))
.build());
setEppInput("domain_update_remove_admin.xml");
persistReferencedEntities();
persistResource(
DatabaseHelper.newDomain(getUniqueIdFromCommand())
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.ADMIN, sh8013Contact.createVKey()),
DesignatedContact.create(Type.TECH, sh8013Contact.createVKey())))
.build());
assertThat(reloadResourceByForeignKey().getRegistrant()).isPresent();
assertThat(reloadResourceByForeignKey().getContacts()).hasSize(2);
runFlowAssertResponse(loadFile("generic_success_response.xml"));
Domain updatedDomain = reloadResourceByForeignKey();
assertThat(updatedDomain.getRegistrant()).isPresent();
assertThat(updatedDomain.getContacts()).hasSize(1);
}
@Test
void testFailure_addPendingDeleteContact() throws Exception {
persistReferencedEntities();
@@ -153,6 +153,43 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, Host> {
assertSqlDeleteSuccess();
}
@Test
void testSuccess_clientDeleteProhibited_superuser() throws Exception {
persistResource(
persistActiveHost("ns1.example.tld")
.asBuilder()
.addStatusValue(StatusValue.CLIENT_DELETE_PROHIBITED)
.build());
runFlowAssertResponse(
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("host_delete_response.xml"));
}
@Test
void testSuccess_serverDeleteProhibited_superuser() throws Exception {
persistResource(
persistActiveHost("ns1.example.tld")
.asBuilder()
.addStatusValue(StatusValue.SERVER_DELETE_PROHIBITED)
.build());
runFlowAssertResponse(
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("host_delete_response.xml"));
}
@Test
void testFailure_pendingDelete_superuser() throws Exception {
persistResource(
persistActiveHost("ns1.example.tld")
.asBuilder()
.addStatusValue(StatusValue.PENDING_DELETE)
.build());
assertAboutEppExceptions()
.that(
assertThrows(
ResourceStatusProhibitsOperationException.class,
() -> runFlow(CommitMode.LIVE, UserPrivileges.SUPERUSER)))
.marshalsToXml();
}
@Test
void testSuccess_authorizedClientReadFromSuperordinate() throws Exception {
sessionMetadata.setRegistrarId("TheRegistrar");
@@ -24,7 +24,7 @@ import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadByKeyIfPresent;
import static google.registry.testing.DatabaseHelper.persistPremiumList;
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -275,7 +275,7 @@ public final class OteAccountBuilderTest {
@Test
void testCreateOteEntities_registrarExists_failsWhenNotReplaceExisting() {
persistSimpleResource(makeRegistrar1().asBuilder().setRegistrarId("myclientid-1").build());
persistResource(makeRegistrar1().asBuilder().setRegistrarId("myclientid-1").build());
OteAccountBuilder oteSetupHelper = OteAccountBuilder.forRegistrarId("myclientid");
@@ -301,7 +301,7 @@ public final class OteAccountBuilderTest {
@Test
void testCreateOteEntities_entitiesExist_succeedsWhenReplaceExisting() {
persistSimpleResource(makeRegistrar1().asBuilder().setRegistrarId("myclientid-1").build());
persistResource(makeRegistrar1().asBuilder().setRegistrarId("myclientid-1").build());
// we intentionally create the -ga TLD with the wrong state, to make sure it's overwritten.
createTld("myclientid-ga", START_DATE_SUNRISE);
@@ -16,7 +16,7 @@ package google.registry.model.common;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.loadAllOf;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -41,7 +41,7 @@ public class DnsRefreshRequestTest extends EntityTestCase {
void testPersistence() {
assertThat(request.getLastProcessTime()).isEqualTo(START_OF_TIME);
fakeClock.advanceOneMilli();
insertInDb(request);
tm().transact(() -> tm().insert(request));
fakeClock.advanceOneMilli();
ImmutableList<DnsRefreshRequest> requests = loadAllOf(DnsRefreshRequest.class);
assertThat(requests.size()).isEqualTo(1);
@@ -20,7 +20,6 @@ import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableO
import static google.registry.testing.ContactSubject.assertAboutContacts;
import static google.registry.testing.DatabaseHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.SqlHelper.assertThrowForeignKeyViolation;
@@ -132,7 +131,7 @@ public class ContactTest extends EntityTestCase {
void testCloudSqlPersistence_failWhenViolateForeignKeyConstraint() {
assertThrowForeignKeyViolation(
() ->
insertInDb(
persistResource(
originalContact
.asBuilder()
.setRepoId("2-FOOBAR")
@@ -20,11 +20,10 @@ import static google.registry.model.domain.token.AllocationToken.TokenStatus.NOT
import static google.registry.model.domain.token.AllocationToken.TokenType.BULK_PRICING;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.updateInDb;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.SqlHelper.assertThrowForeignKeyViolation;
import static google.registry.testing.SqlHelper.saveRegistrar;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
@@ -169,13 +168,13 @@ public class DomainSqlTest {
@Test
void testHostForeignKeyConstraints() {
// Persist the domain without the associated host object.
assertThrowForeignKeyViolation(() -> insertInDb(contact, contact2, domain));
assertThrowForeignKeyViolation(() -> persistResources(contact, contact2, domain));
}
@Test
void testContactForeignKeyConstraints() {
// Persist the domain without the associated contact objects.
assertThrowForeignKeyViolation(() -> insertInDb(domain, host));
assertThrowForeignKeyViolation(() -> persistResources(domain, host));
}
@Test
@@ -358,7 +357,7 @@ public class DomainSqlTest {
@Test
void testSerializable() {
createTld("com");
insertInDb(contact, contact2, domain, host);
persistResources(contact, contact2, domain, host);
Domain persisted = tm().transact(() -> tm().loadByEntity(domain));
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
}
@@ -366,9 +365,9 @@ public class DomainSqlTest {
@Test
void testUpdates() {
createTld("com");
insertInDb(contact, contact2, domain, host);
persistResources(contact, contact2, domain, host);
domain = domain.asBuilder().setNameservers(ImmutableSet.of()).build();
updateInDb(domain);
persistResource(domain);
assertAboutImmutableObjects()
.that(loadByEntity(domain))
.isEqualExceptFields(domain, "updateTimestamp", "creationTime");
@@ -385,7 +384,7 @@ public class DomainSqlTest {
private void persistDomain() {
createTld("com");
insertInDb(contact, contact2, domain, host);
persistResources(contact, contact2, domain, host);
}
private <T> VKey<T> createKey(Class<T> clazz, String key) {
@@ -414,24 +413,19 @@ public class DomainSqlTest {
Domain persisted = loadByKey(domain.createVKey());
DateTime originalUpdateTime = persisted.getUpdateTimestamp().getTimestamp();
fakeClock.advanceOneMilli();
DateTime transactionTime =
tm().transact(
() -> {
Host host2 =
new Host.Builder()
.setRepoId("host2")
.setHostName("ns2.example.com")
.setCreationRegistrarId("registrar1")
.setPersistedCurrentSponsorRegistrarId("registrar2")
.build();
insertInDb(host2);
Host host2 =
new Host.Builder()
.setRepoId("host2")
.setHostName("ns2.example.com")
.setCreationRegistrarId("registrar1")
.setPersistedCurrentSponsorRegistrarId("registrar2")
.build();
persistResource(host2);
domain = persisted.asBuilder().addNameserver(host2.createVKey()).build();
updateInDb(domain);
return tm().getTransactionTime();
});
persistResource(domain);
domain = loadByKey(domain.createVKey());
assertThat(domain.getUpdateTimestamp().getTimestamp()).isEqualTo(transactionTime);
assertThat(domain.getUpdateTimestamp().getTimestamp()).isNotEqualTo(originalUpdateTime);
assertThat(domain.getUpdateTimestamp().getTimestamp())
.isEqualTo(originalUpdateTime.plusMillis(1));
}
@Test
@@ -440,20 +434,14 @@ public class DomainSqlTest {
Domain persisted = loadByKey(domain.createVKey());
DateTime originalUpdateTime = persisted.getUpdateTimestamp().getTimestamp();
fakeClock.advanceOneMilli();
DateTime transactionTime =
tm().transact(
() -> {
domain =
persisted
.asBuilder()
.setDsData(
ImmutableSet.of(DomainDsData.create(1, 2, 3, new byte[] {0, 1, 2})))
.build();
updateInDb(domain);
return tm().getTransactionTime();
});
domain =
persisted
.asBuilder()
.setDsData(ImmutableSet.of(DomainDsData.create(1, 2, 3, new byte[] {0, 1, 2})))
.build();
persistResource(domain);
domain = loadByKey(domain.createVKey());
assertThat(domain.getUpdateTimestamp().getTimestamp()).isEqualTo(transactionTime);
assertThat(domain.getUpdateTimestamp().getTimestamp()).isNotEqualTo(originalUpdateTime);
assertThat(domain.getUpdateTimestamp().getTimestamp())
.isEqualTo(originalUpdateTime.plusMillis(1));
}
}
@@ -23,12 +23,12 @@ import static google.registry.model.domain.token.AllocationToken.TokenType.BULK_
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
import static google.registry.testing.DatabaseHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.newHost;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.DomainSubject.assertAboutDomains;
import static google.registry.testing.SqlHelper.saveRegistrar;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
@@ -162,7 +162,7 @@ public class DomainTest {
.setRecurrenceEndTime(END_OF_TIME)
.setDomainHistory(historyEntry)
.build();
insertInDb(historyEntry, billingEventBill, billingRecurrence);
persistResources(historyEntry, billingEventBill, billingRecurrence);
recurrenceBillKey = billingRecurrence.createVKey();
VKey<PollMessage.Autorenew> autorenewPollKey = VKey.create(PollMessage.Autorenew.class, 3L);
VKey<PollMessage.OneTime> onetimePollKey = VKey.create(PollMessage.OneTime.class, 1L);
@@ -16,8 +16,8 @@ package google.registry.model.eppcommon;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
@@ -50,25 +50,25 @@ class AddressTest {
private static final String ENTITY_XML =
"""
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<testEntity>
<address>
<street>123 W 14th St</street>
<street>8th Fl</street>
<street>Rm 8</street>
<city>New York</city>
<sp>NY</sp>
<pc>10011</pc>
<cc>US</cc>
</address>
</testEntity>
""";
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<testEntity>
<address>
<street>123 W 14th St</street>
<street>8th Fl</street>
<street>Rm 8</street>
<city>New York</city>
<sp>NY</sp>
<pc>10011</pc>
<cc>US</cc>
</address>
</testEntity>
""";
private TestAddress address = createAddress("123 W 14th St", "8th Fl", "Rm 8");
private TestEntity entity = new TestEntity(1L, address);
private static TestEntity saveAndLoad(TestEntity entity) {
insertInDb(entity);
persistResource(entity);
return loadByEntity(entity);
}
@@ -17,9 +17,9 @@ package google.registry.model.history;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.newContactWithRoid;
import static google.registry.testing.DatabaseHelper.persistResource;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
@@ -45,10 +45,10 @@ public class ContactHistoryTest extends EntityTestCase {
@Test
void testPersistence() {
Contact contact = newContactWithRoid("contactId", "contact1");
insertInDb(contact);
persistResource(contact);
Contact contactFromDb = loadByEntity(contact);
ContactHistory contactHistory = createContactHistory(contactFromDb);
insertInDb(contactHistory);
persistResource(contactHistory);
tm().transact(
() -> {
ContactHistory fromDatabase = tm().loadByKey(contactHistory.createVKey());
@@ -60,10 +60,10 @@ public class ContactHistoryTest extends EntityTestCase {
@Test
void testSerializable() {
Contact contact = newContactWithRoid("contactId", "contact1");
insertInDb(contact);
persistResource(contact);
Contact contactFromDb = loadByEntity(contact);
ContactHistory contactHistory = createContactHistory(contactFromDb);
insertInDb(contactHistory);
persistResource(contactHistory);
ContactHistory fromDatabase = tm().transact(() -> tm().loadByKey(contactHistory.createVKey()));
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
}
@@ -18,10 +18,10 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.newContactWithRoid;
import static google.registry.testing.DatabaseHelper.newDomain;
import static google.registry.testing.DatabaseHelper.newHostWithRoid;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -60,7 +60,7 @@ public class DomainHistoryTest extends EntityTestCase {
void testPersistence() {
Domain domain = addGracePeriodForSql(createDomainWithContactsAndHosts());
DomainHistory domainHistory = createDomainHistory(domain);
insertInDb(domainHistory);
persistResource(domainHistory);
tm().transact(
() -> {
@@ -74,7 +74,7 @@ public class DomainHistoryTest extends EntityTestCase {
void testSerializable() {
Domain domain = addGracePeriodForSql(createDomainWithContactsAndHosts());
DomainHistory domainHistory = createDomainHistory(domain);
insertInDb(domainHistory);
persistResource(domainHistory);
DomainHistory fromDatabase = tm().transact(() -> tm().loadByKey(domainHistory.createVKey()));
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
}
@@ -96,7 +96,7 @@ public class DomainHistoryTest extends EntityTestCase {
.setNameservers(host.createVKey())
.setDsData(ImmutableSet.of(DomainDsData.create(1, 2, 3, new byte[] {0, 1, 2})))
.build();
insertInDb(domain);
persistResource(domain);
return domain;
}
@@ -17,9 +17,9 @@ package google.registry.model.history;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.newHostWithRoid;
import static google.registry.testing.DatabaseHelper.persistResource;
import static java.nio.charset.StandardCharsets.UTF_8;
import google.registry.model.EntityTestCase;
@@ -41,10 +41,10 @@ public class HostHistoryTest extends EntityTestCase {
@Test
void testPersistence() {
Host host = newHostWithRoid("ns1.example.com", "host1");
insertInDb(host);
persistResource(host);
Host hostFromDb = loadByEntity(host);
HostHistory hostHistory = createHostHistory(hostFromDb);
insertInDb(hostHistory);
persistResource(hostHistory);
tm().transact(
() -> {
HostHistory fromDatabase = tm().loadByKey(hostHistory.createVKey());
@@ -56,10 +56,10 @@ public class HostHistoryTest extends EntityTestCase {
@Test
void testSerializable() {
Host host = newHostWithRoid("ns1.example.com", "host1");
insertInDb(host);
persistResource(host);
Host hostFromDb = loadByEntity(host);
HostHistory hostHistory = createHostHistory(hostFromDb);
insertInDb(hostHistory);
persistResource(hostHistory);
HostHistory fromDatabase = tm().transact(() -> tm().loadByKey(hostHistory.createVKey()));
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
}
@@ -17,7 +17,6 @@ package google.registry.model.poll;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistActiveContact;
import static google.registry.testing.DatabaseHelper.persistResource;
@@ -90,12 +89,12 @@ public class PollMessageTest extends EntityTestCase {
@Test
void testCloudSqlSupportForPolymorphicVKey() {
insertInDb(oneTime);
persistResource(oneTime);
PollMessage persistedOneTime = loadByKey(VKey.create(PollMessage.class, oneTime.getId()));
assertThat(persistedOneTime).isInstanceOf(PollMessage.OneTime.class);
assertThat(persistedOneTime).isEqualTo(oneTime);
insertInDb(autoRenew);
persistResource(autoRenew);
PollMessage persistedAutoRenew = loadByKey(VKey.create(PollMessage.class, autoRenew.getId()));
assertThat(persistedAutoRenew).isInstanceOf(PollMessage.Autorenew.class);
assertThat(persistedAutoRenew).isEqualTo(autoRenew);
@@ -25,8 +25,7 @@ import static google.registry.testing.DatabaseHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.newTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
@@ -132,7 +131,7 @@ class RegistrarTest extends EntityTestCase {
.setFaxNumber("+1.2125551213")
.setTypes(ImmutableSet.of(RegistrarPoc.Type.ABUSE, RegistrarPoc.Type.ADMIN))
.build();
persistSimpleResources(
persistResources(
ImmutableList.of(
abuseAdminContact,
new RegistrarPoc.Builder()
@@ -301,7 +300,7 @@ class RegistrarTest extends EntityTestCase {
@Test
void testSuccess_emptyContactTypesAllowed() {
persistSimpleResource(
persistResource(
new RegistrarPoc.Builder()
.setRegistrar(registrar)
.setName("John Abussy")
@@ -318,7 +317,7 @@ class RegistrarTest extends EntityTestCase {
@Test
void testSuccess_getContactsByType() {
RegistrarPoc newTechContact =
persistSimpleResource(
persistResource(
new RegistrarPoc.Builder()
.setRegistrar(registrar)
.setName("Jake Tech")
@@ -330,7 +329,7 @@ class RegistrarTest extends EntityTestCase {
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH))
.build());
RegistrarPoc newTechAbuseContact =
persistSimpleResource(
persistResource(
new RegistrarPoc.Builder()
.setRegistrar(registrar)
.setName("Jim Tech-Abuse")
@@ -17,9 +17,10 @@ package google.registry.model.reporting;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.model.reporting.Spec11ThreatMatch.ThreatType.MALWARE;
import static google.registry.model.reporting.Spec11ThreatMatch.ThreatType.UNWANTED_SOFTWARE;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.loadByEntity;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.SqlHelper.assertThrowForeignKeyViolation;
import static google.registry.testing.SqlHelper.saveRegistrar;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -105,7 +106,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
void testPersistence() {
createTld("tld");
saveRegistrar(REGISTRAR_ID);
insertInDb(registrantContact, domain, host, threat);
tm().transact(() -> tm().insertAll(registrantContact, domain, host, threat));
assertAboutImmutableObjects().that(loadByEntity(threat)).isEqualExceptFields(threat, "id");
}
@@ -113,12 +114,12 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
@Disabled("We can't rely on foreign keys until we've migrated to SQL")
void testThreatForeignKeyConstraints() {
// Persist the threat without the associated registrar.
assertThrowForeignKeyViolation(() -> insertInDb(host, registrantContact, domain, threat));
assertThrowForeignKeyViolation(() -> persistResources(host, registrantContact, domain, threat));
saveRegistrar(REGISTRAR_ID);
// Persist the threat without the associated domain.
assertThrowForeignKeyViolation(() -> insertInDb(registrantContact, host, threat));
assertThrowForeignKeyViolation(() -> persistResources(registrantContact, host, threat));
}
@Test
@@ -16,9 +16,12 @@ package google.registry.model.smd;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.collect.ImmutableMap;
import google.registry.model.EntityTestCase;
import jakarta.persistence.OptimisticLockException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.jupiter.api.Test;
public class SignedMarkRevocationListDaoTest extends EntityTestCase {
@@ -32,11 +35,29 @@ public class SignedMarkRevocationListDaoTest extends EntityTestCase {
SignedMarkRevocationList list =
SignedMarkRevocationList.create(
fakeClock.nowUtc(), ImmutableMap.of("mark", fakeClock.nowUtc().minusHours(1)));
SignedMarkRevocationListDao.save(list);
list = SignedMarkRevocationListDao.save(list);
SignedMarkRevocationList fromDb = SignedMarkRevocationListDao.load();
assertAboutImmutableObjects().that(fromDb).isEqualExceptFields(list);
}
@Test
void testSave_retrySuccess() {
SignedMarkRevocationList list =
SignedMarkRevocationList.create(
fakeClock.nowUtc(), ImmutableMap.of("mark", fakeClock.nowUtc().minusHours(1)));
AtomicBoolean isFirstAttempt = new AtomicBoolean(true);
tm().transact(
() -> {
SignedMarkRevocationListDao.save(list);
if (isFirstAttempt.get()) {
isFirstAttempt.set(false);
throw new OptimisticLockException();
}
});
SignedMarkRevocationList fromDb = SignedMarkRevocationListDao.load();
assertAboutImmutableObjects().that(fromDb).isEqualExceptFields(list, "revisionId");
}
@Test
void testSaveAndLoad_emptyList() {
SignedMarkRevocationList list =
@@ -48,7 +48,8 @@ public class SignedMarkRevocationListTest {
for (int i = 0; i < rows; i++) {
revokes.put(Integer.toString(i), clock.nowUtc());
}
SignedMarkRevocationList.create(clock.nowUtc(), revokes.build()).save();
SignedMarkRevocationListDao.save(
SignedMarkRevocationList.create(clock.nowUtc(), revokes.build()));
SignedMarkRevocationList res = SignedMarkRevocationList.get();
assertThat(res.size()).isEqualTo(rows);
return res;
@@ -31,10 +31,12 @@ import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.TestCacheExtension;
import jakarta.persistence.OptimisticLockException;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.IntStream;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
@@ -93,6 +95,27 @@ public class PremiumListDaoTest {
});
}
@Test
void saveNew_retry_success() {
AtomicBoolean isFirstAttempt = new AtomicBoolean(true);
tm().transact(
() -> {
PremiumListDao.save(testList);
if (isFirstAttempt.get()) {
isFirstAttempt.set(false);
throw new OptimisticLockException();
}
});
tm().transact(
() -> {
Optional<PremiumList> persistedListOpt = PremiumListDao.getLatestRevision("testname");
assertThat(persistedListOpt).isPresent();
PremiumList persistedList = persistedListOpt.get();
assertThat(persistedList.getLabelsToPrices()).containsExactlyEntriesIn(TEST_PRICES);
assertThat(persistedList.getCreationTimestamp()).isEqualTo(fakeClock.nowUtc());
});
}
@Test
void update_worksSuccessfully() {
PremiumListDao.save(testList);
@@ -22,6 +22,8 @@ import google.registry.model.tld.label.ReservedList.ReservedListEntry;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
import jakarta.persistence.OptimisticLockException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -71,11 +73,34 @@ public class ReservedListDaoTest {
});
}
@Test
void save_withRetry_worksSuccessfully() {
AtomicBoolean isFirstAttempt = new AtomicBoolean(true);
tm().transact(
() -> {
ReservedListDao.save(testReservedList);
if (isFirstAttempt.get()) {
isFirstAttempt.set(false);
throw new OptimisticLockException();
}
});
tm().transact(
() -> {
ReservedList persistedList =
tm().query("FROM ReservedList WHERE name = :name", ReservedList.class)
.setParameter("name", "testlist")
.getSingleResult();
assertThat(persistedList.getReservedListEntries())
.containsExactlyEntriesIn(testReservations);
assertThat(persistedList.getCreationTimestamp()).isEqualTo(fakeClock.nowUtc());
});
}
@Test
void delete_worksSuccessfully() {
ReservedListDao.save(testReservedList);
var persisted = ReservedListDao.save(testReservedList);
assertThat(ReservedListDao.checkExists("testlist")).isTrue();
ReservedListDao.delete(testReservedList);
ReservedListDao.delete(persisted);
assertThat(ReservedListDao.checkExists("testlist")).isFalse();
}
@@ -16,15 +16,15 @@ package google.registry.model.tmch;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableMap;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.TestCacheExtension;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.OptimisticLockException;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -49,27 +49,36 @@ public class ClaimsListDaoTest {
void save_insertsClaimsListSuccessfully() {
ClaimsList claimsList =
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
ClaimsListDao.save(claimsList);
claimsList = ClaimsListDao.save(claimsList);
ClaimsList insertedClaimsList = ClaimsListDao.get();
assertClaimsListEquals(claimsList, insertedClaimsList);
assertThat(insertedClaimsList.getCreationTimestamp()).isEqualTo(fakeClock.nowUtc());
}
@Test
void save_fail_duplicateId() {
void save_insertsClaimsListSuccessfully_withRetries() {
ClaimsList claimsList =
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
ClaimsListDao.save(claimsList);
AtomicBoolean isFirstAttempt = new AtomicBoolean(true);
tm().transact(
() -> {
ClaimsListDao.save(claimsList);
if (isFirstAttempt.get()) {
isFirstAttempt.set(false);
throw new OptimisticLockException();
}
});
ClaimsList insertedClaimsList = ClaimsListDao.get();
assertClaimsListEquals(claimsList, insertedClaimsList);
// Save ClaimsList with existing revisionId should fail because revisionId is the primary key.
assertThrows(PersistenceException.class, () -> ClaimsListDao.save(insertedClaimsList));
assertThat(insertedClaimsList.getTmdbGenerationTime())
.isEqualTo(claimsList.getTmdbGenerationTime());
assertThat(insertedClaimsList.getLabelsToKeys()).isEqualTo(claimsList.getLabelsToKeys());
assertThat(insertedClaimsList.getCreationTimestamp()).isEqualTo(fakeClock.nowUtc());
}
@Test
void save_claimsListWithNoEntries() {
ClaimsList claimsList = ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of());
ClaimsListDao.save(claimsList);
claimsList = ClaimsListDao.save(claimsList);
ClaimsList insertedClaimsList = ClaimsListDao.get();
assertClaimsListEquals(claimsList, insertedClaimsList);
assertThat(insertedClaimsList.getLabelsToKeys()).isEmpty();
@@ -86,8 +95,8 @@ public class ClaimsListDaoTest {
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
ClaimsList newClaimsList =
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label3", "key3", "label4", "key4"));
ClaimsListDao.save(oldClaimsList);
ClaimsListDao.save(newClaimsList);
oldClaimsList = ClaimsListDao.save(oldClaimsList);
newClaimsList = ClaimsListDao.save(newClaimsList);
assertClaimsListEquals(newClaimsList, ClaimsListDao.get());
}
@@ -96,11 +105,11 @@ public class ClaimsListDaoTest {
assertThat(ClaimsListDao.CACHE.getIfPresent(ClaimsListDao.class)).isNull();
ClaimsList oldList =
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
ClaimsListDao.save(oldList);
oldList = ClaimsListDao.save(oldList);
assertThat(ClaimsListDao.CACHE.getIfPresent(ClaimsListDao.class)).isEqualTo(oldList);
ClaimsList newList =
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label3", "key3", "label4", "key4"));
ClaimsListDao.save(newList);
newList = ClaimsListDao.save(newList);
assertThat(ClaimsListDao.CACHE.getIfPresent(ClaimsListDao.class)).isEqualTo(newList);
}
@@ -29,6 +29,7 @@ import google.registry.testing.TestDataHelper;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link RequestComponent}. */
@@ -49,6 +50,7 @@ public class RequestComponentTest {
}
@Test
@Disabled("To be removed with GAE components")
void testGaeToJettyRoutingCoverage() {
Set<Route> jettyRoutes = getRoutes(RequestComponent.class, "routing.txt");
Set<Route> gaeRoutes = new HashSet<>();
@@ -18,7 +18,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableSet;
import google.registry.model.ImmutableObject;
@@ -51,7 +51,7 @@ class EntityCallbacksListenerTest {
@Test
void verifyAllCallbacks_executedExpectedTimes() {
TestEntity testPersist = new TestEntity();
insertInDb(testPersist);
tm().transact(() -> tm().insert(testPersist));
checkAll(testPersist, 1, 0, 0, 0);
TestEntity testUpdate = new TestEntity();
@@ -99,7 +99,7 @@ class EntityCallbacksListenerTest {
@Test
void verifyCallbacksNotCalledOnCommit() {
insertInDb(new TestEntity());
persistResource(new TestEntity());
TestEntity testLoad = tm().transact(() -> tm().loadByKey(VKey.create(TestEntity.class, "id")));
assertThat(testLoad.entityPreUpdate).isEqualTo(0);
@@ -19,7 +19,7 @@ import static google.registry.model.domain.token.AllocationToken.TokenStatus.END
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.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ImmutableSortedMap;
@@ -59,7 +59,7 @@ public class AllocationTokenStatusTransitionUserTypeTest {
TimedTransitionProperty.fromValueMap(values);
AllocationTokenStatusTransitionConverterTestEntity testEntity =
new AllocationTokenStatusTransitionConverterTestEntity(timedTransitionProperty);
insertInDb(testEntity);
persistResource(testEntity);
AllocationTokenStatusTransitionConverterTestEntity persisted =
tm().transact(
() ->
@@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
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.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableList;
import google.registry.model.ImmutableObject;
@@ -51,7 +51,7 @@ public class AllocationTokenVkeyListUserTypeTest {
List<VKey<AllocationToken>> tokens = ImmutableList.of(token1.createVKey(), token2.createVKey());
TestAllocationTokenVKeyList testAllocationTokenVKeyList =
new TestAllocationTokenVKeyList(tokens);
insertInDb(testAllocationTokenVKeyList);
persistResource(testAllocationTokenVKeyList);
TestAllocationTokenVKeyList persisted =
tm().transact(() -> tm().getEntityManager().find(TestAllocationTokenVKeyList.class, "id"));
assertThat(persisted.tokenList).isEqualTo(tokens);
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.USD;
@@ -52,7 +52,7 @@ public class BillingCostTransitionUserTypeTest {
TimedTransitionProperty<Money> timedTransitionProperty =
TimedTransitionProperty.fromValueMap(values);
TestEntity testEntity = new TestEntity(timedTransitionProperty);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.timedTransitionProperty.toValueMap())
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.hash.Funnels.stringFunnel;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static java.nio.charset.StandardCharsets.US_ASCII;
import com.google.common.collect.ImmutableSet;
@@ -41,7 +41,7 @@ class BloomFilterConverterTest {
BloomFilter<String> bloomFilter = BloomFilter.create(stringFunnel(US_ASCII), 3);
ImmutableSet.of("foo", "bar", "baz").forEach(bloomFilter::put);
TestEntity entity = new TestEntity(bloomFilter);
insertInDb(entity);
persistResource(entity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.bloomFilter).isEqualTo(bloomFilter);
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableList;
import google.registry.model.ImmutableObject;
@@ -47,7 +47,7 @@ public class CidrBlockListUserTypeTest {
CidrAddressBlock.create("8000::/1"),
CidrAddressBlock.create("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
TestEntity testEntity = new TestEntity(addresses);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.addresses).isEqualTo(addresses);
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableMap;
import google.registry.model.ImmutableObject;
@@ -44,7 +44,7 @@ public class CurrencyToStringMapUserTypeTest {
CurrencyUnit.of("USD"), "accountId1",
CurrencyUnit.of("CNY"), "accountId2");
TestEntity testEntity = new TestEntity(currencyToBilling);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.currencyToBilling).containsExactlyEntriesIn(currencyToBilling);
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
import google.registry.model.ImmutableObject;
@@ -39,7 +39,7 @@ public class CurrencyUnitConverterTest {
@Test
void roundTripConversion() {
TestEntity entity = new TestEntity(CurrencyUnit.EUR);
insertInDb(entity);
persistResource(entity);
assertThat(
tm().transact(
() ->
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static java.time.ZoneOffset.UTC;
import google.registry.model.ImmutableObject;
@@ -75,7 +75,7 @@ public class DateTimeConverterTest {
void converter_generatesTimestampWithNormalizedZone() {
DateTime dt = parseDateTime("2019-09-01T01:01:01Z");
TestEntity entity = new TestEntity("normalized_utc_time", dt);
insertInDb(entity);
persistResource(entity);
TestEntity retrievedEntity =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "normalized_utc_time"));
assertThat(retrievedEntity.dt.toString()).isEqualTo("2019-09-01T01:01:01.000Z");
@@ -86,7 +86,7 @@ public class DateTimeConverterTest {
DateTime dt = parseDateTime("2019-09-01T01:01:01-05:00");
TestEntity entity = new TestEntity("new_york_time", dt);
insertInDb(entity);
persistResource(entity);
TestEntity retrievedEntity =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "new_york_time"));
assertThat(retrievedEntity.dt.toString()).isEqualTo("2019-09-01T06:01:01.000Z");
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestExtensions;
@@ -39,7 +39,7 @@ public class DurationUserTypeTest {
@Test
void testNulls() {
DurationTestEntity entity = new DurationTestEntity(null);
insertInDb(entity);
persistResource(entity);
DurationTestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(DurationTestEntity.class, "id"));
assertThat(persisted.duration).isNull();
@@ -90,7 +90,7 @@ public class DurationUserTypeTest {
private void assertPersistedEntityHasSameDuration(Duration duration) {
DurationTestEntity entity = new DurationTestEntity(duration);
insertInDb(entity);
persistResource(entity);
DurationTestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(DurationTestEntity.class, "id"));
assertThat(persisted.duration.getMillis()).isEqualTo(duration.getMillis());
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
@@ -64,7 +64,7 @@ public class InetAddressSetUserTypeTest {
private void verifySaveAndLoad(@Nullable Set<InetAddress> inetAddresses) {
InetAddressSetTestEntity testEntity = new InetAddressSetTestEntity(inetAddresses);
insertInDb(testEntity);
persistResource(testEntity);
InetAddressSetTestEntity persisted =
tm().transact(() -> tm().loadByKey(VKey.create(InetAddressSetTestEntity.class, "id")));
assertThat(persisted.addresses).isEqualTo(inetAddresses);
@@ -15,7 +15,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableMap;
@@ -57,7 +57,7 @@ public class JodaMoneyTypeTest {
Money money = Money.of(CurrencyUnit.USD, 100.12);
assertThat(money.getAmount().scale()).isEqualTo(2);
TestEntity entity = new TestEntity(money);
insertInDb(entity);
persistResource(entity);
List<?> result =
tm().transact(
() ->
@@ -81,7 +81,7 @@ public class JodaMoneyTypeTest {
Money money = Money.ofMajor(CurrencyUnit.JPY, 100);
assertThat(money.getAmount().scale()).isEqualTo(0); // JPY's amount has scale at 0.
TestEntity entity = new TestEntity(money);
insertInDb(entity);
persistResource(entity);
List<?> result =
tm().transact(
() ->
@@ -121,7 +121,7 @@ public class JodaMoneyTypeTest {
"dos", Money.ofMajor(CurrencyUnit.JPY, 2000),
"tres", Money.of(CurrencyUnit.GBP, 20));
ComplexTestEntity entity = new ComplexTestEntity(moneyMap, myMoney, yourMoney);
insertInDb(entity);
persistResource(entity);
List<?> result =
tm().transact(
() ->
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import google.registry.model.ImmutableObject;
import google.registry.persistence.VKey;
@@ -54,7 +54,7 @@ public class LocalDateConverterTest {
private LocalDateConverterTestEntity persistAndLoadTestEntity(LocalDate date) {
LocalDateConverterTestEntity entity = new LocalDateConverterTestEntity(date);
insertInDb(entity);
persistResource(entity);
return tm().transact(
() -> tm().loadByKey(VKey.create(LocalDateConverterTestEntity.class, "id")));
}
@@ -48,7 +48,7 @@ public class RegistrarToRoleMapUserTypeTest {
"FooRegistrar",
RegistrarRole.TECH_CONTACT);
TestEntity entity = new TestEntity(map);
DatabaseHelper.insertInDb(entity);
DatabaseHelper.persistResource(entity);
TestEntity persisted = Iterables.getOnlyElement(DatabaseHelper.loadAllOf(TestEntity.class));
assertThat(persisted.map).isEqualTo(map);
}
@@ -17,7 +17,7 @@ package google.registry.persistence.converter;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
@@ -45,7 +45,7 @@ public class StringCollectionUserTypeTest {
List<ListElement> value =
ImmutableList.of(new ListElement("app"), new ListElement("dev"), new ListElement("com"));
TestEntity testEntity = new TestEntity(value);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.value).containsExactlyElementsIn(value);
@@ -56,7 +56,7 @@ public class StringCollectionUserTypeTest {
List<ListElement> value =
ImmutableList.of(new ListElement("app"), new ListElement("dev"), new ListElement("com"));
TestEntity testEntity = new TestEntity(value);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
persisted.value = ImmutableList.of(new ListElement("app"), new ListElement("org"));
@@ -68,7 +68,7 @@ public class StringCollectionUserTypeTest {
@Test
void testNullValue_writesAndReadsNullSuccessfully() {
TestEntity testEntity = new TestEntity(null);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.value).isNull();
@@ -77,7 +77,7 @@ public class StringCollectionUserTypeTest {
@Test
void testEmptyCollection_writesAndReadsEmptyCollectionSuccessfully() {
TestEntity testEntity = new TestEntity(ImmutableList.of());
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.value).isEmpty();
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
@@ -41,7 +41,7 @@ public class StringListConversionTest {
void roundTripConversion_returnsSameStringList() {
List<String> tlds = ImmutableList.of("app", "dev", "how");
TestEntity testEntity = new TestEntity(tlds);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.tlds).containsExactly("app", "dev", "how");
@@ -51,7 +51,7 @@ public class StringListConversionTest {
void testMerge_succeeds() {
List<String> tlds = ImmutableList.of("app", "dev", "how");
TestEntity testEntity = new TestEntity(tlds);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
persisted.tlds = ImmutableList.of("com", "gov");
@@ -63,7 +63,7 @@ public class StringListConversionTest {
@Test
void testNullValue_writesAndReadsNullSuccessfully() {
TestEntity testEntity = new TestEntity(null);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.tlds).isNull();
@@ -72,7 +72,7 @@ public class StringListConversionTest {
@Test
void testEmptyCollection_writesAndReadsEmptyCollectionSuccessfully() {
TestEntity testEntity = new TestEntity(ImmutableList.of());
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.tlds).isEmpty();
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableMap;
@@ -47,7 +47,7 @@ public class StringMapUserTypeTest {
@Test
void roundTripConversion_returnsSameMap() {
TestEntity testEntity = new TestEntity(MAP);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.map).containsExactlyEntriesIn(MAP);
@@ -56,7 +56,7 @@ public class StringMapUserTypeTest {
@Test
void testUpdateColumn_succeeds() {
TestEntity testEntity = new TestEntity(MAP);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.map).containsExactlyEntriesIn(MAP);
@@ -69,7 +69,7 @@ public class StringMapUserTypeTest {
@Test
void testNullValue_writesAndReadsNullSuccessfully() {
TestEntity testEntity = new TestEntity(null);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.map).isNull();
@@ -78,7 +78,7 @@ public class StringMapUserTypeTest {
@Test
void testEmptyMap_writesAndReadsEmptyCollectionSuccessfully() {
TestEntity testEntity = new TestEntity(ImmutableMap.of());
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.map).isEmpty();
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableSet;
import google.registry.model.ImmutableObject;
@@ -39,7 +39,7 @@ public class StringSetConversionTest {
void roundTripConversion_returnsSameStringList() {
Set<String> tlds = ImmutableSet.of("app", "dev", "how");
TestEntity testEntity = new TestEntity(tlds);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.tlds).containsExactly("app", "dev", "how");
@@ -48,7 +48,7 @@ public class StringSetConversionTest {
@Test
void testNullValue_writesAndReadsNullSuccessfully() {
TestEntity testEntity = new TestEntity(null);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.tlds).isNull();
@@ -57,7 +57,7 @@ public class StringSetConversionTest {
@Test
void testEmptyCollection_writesAndReadsEmptyCollectionSuccessfully() {
TestEntity testEntity = new TestEntity(ImmutableSet.of());
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.tlds).isEmpty();
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import google.registry.model.ImmutableObject;
import google.registry.model.registrar.Registrar.State;
@@ -39,7 +39,7 @@ public class StringValueEnumeratedTest {
@Test
void roundTripConversion_returnsSameEnum() {
TestEntity testEntity = new TestEntity(State.ACTIVE);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.state).isEqualTo(State.ACTIVE);
@@ -48,7 +48,7 @@ public class StringValueEnumeratedTest {
@Test
void testNativeQuery_succeeds() {
TestEntity testEntity = new TestEntity(State.DISABLED);
insertInDb(testEntity);
persistResource(testEntity);
assertThat(
tm().transact(
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -55,7 +55,7 @@ class TimedTransitionBaseUserTypeTest {
@Test
void roundTripConversion_returnsSameTimedTransitionProperty() {
TestEntity testEntity = new TestEntity(TIMED_TRANSITION_PROPERTY);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.property.toValueMap())
@@ -65,7 +65,7 @@ class TimedTransitionBaseUserTypeTest {
@Test
void testUpdateColumn_succeeds() {
TestEntity testEntity = new TestEntity(TIMED_TRANSITION_PROPERTY);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.property.toValueMap())
@@ -80,7 +80,7 @@ class TimedTransitionBaseUserTypeTest {
@Test
void testNullValue_writesAndReadsNullSuccessfully() {
TestEntity testEntity = new TestEntity(null);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.property).isNull();
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ImmutableSortedMap;
@@ -55,7 +55,7 @@ class TldStateTransitionUserTypeTest {
TimedTransitionProperty<TldState> timedTransitionProperty =
TimedTransitionProperty.fromValueMap(values);
TestEntity testEntity = new TestEntity(timedTransitionProperty);
insertInDb(testEntity);
persistResource(testEntity);
TestEntity persisted =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.timedTransitionProperty.toValueMap())
@@ -16,7 +16,7 @@ package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResources;
import google.registry.model.ImmutableObject;
import google.registry.persistence.VKey;
@@ -50,7 +50,7 @@ public class VKeyConverterTest {
TestLongEntity longEntity = new TestLongEntity(300L);
VKey<TestLongEntity> longKey = VKey.create(TestLongEntity.class, 300L);
TestEntity original = new TestEntity(1984L, stringKey, longKey);
insertInDb(stringEntity, longEntity, original);
persistResources(stringEntity, longEntity, original);
TestEntity retrieved =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, 1984L));
@@ -16,7 +16,7 @@ package google.registry.persistence.transaction;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResources;
import com.google.common.collect.ImmutableList;
import google.registry.model.ImmutableObject;
@@ -50,7 +50,7 @@ class CriteriaQueryBuilderTest {
@BeforeEach
void beforeEach() {
insertInDb(entity1, entity2, entity3);
persistResources(entity1, entity2, entity3);
}
@Test
@@ -17,7 +17,7 @@ package google.registry.persistence.transaction;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.testing.DatabaseHelper.insertSimpleResources;
import static google.registry.testing.DatabaseHelper.persistResources;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.testcontainers.containers.PostgreSQLContainer.POSTGRESQL_PORT;
@@ -444,7 +444,7 @@ public abstract class JpaTransactionManagerExtension
/** Create some fake registrars. */
public static void loadInitialData() {
insertSimpleResources(
persistResources(
ImmutableList.of(
makeRegistrar1(),
makeRegistrarContact1(),
@@ -17,7 +17,7 @@ package google.registry.persistence.transaction;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.persistResource;
import static org.junit.jupiter.api.Assertions.assertThrows;
import google.registry.model.ImmutableObject;
@@ -76,7 +76,7 @@ public class JpaTransactionManagerExtensionTest {
// This test verifies that 1) withEntityClass() has registered TestEntity and 2) The table
// has been created, implying withProperty(HBM2DDL_AUTO, "update") worked.
TestEntity original = new TestEntity("key", "value");
insertInDb(original);
persistResource(original);
TestEntity retrieved =
tm().transact(() -> tm().getEntityManager().find(TestEntity.class, "key"));
assertThat(retrieved).isEqualTo(original);
@@ -24,8 +24,9 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.assertDetachedFromEntityManager;
import static google.registry.testing.DatabaseHelper.existsInDb;
import static google.registry.testing.DatabaseHelper.insertInDb;
import static google.registry.testing.DatabaseHelper.loadByKey;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.TestDataHelper.fileClassPath;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
@@ -397,7 +398,7 @@ class JpaTransactionManagerImplTest {
@Test
void saveAllNew_succeeds() {
moreEntities.forEach(entity -> assertThat(tm().transact(() -> tm().exists(entity))).isFalse());
insertInDb(moreEntities);
persistResources(moreEntities);
moreEntities.forEach(entity -> assertThat(tm().transact(() -> tm().exists(entity))).isTrue());
assertThat(tm().transact(() -> tm().loadAllOf(TestEntity.class)))
.containsExactlyElementsIn(moreEntities);
@@ -406,8 +407,12 @@ class JpaTransactionManagerImplTest {
@Test
void saveAllNew_rollsBackWhenFailure() {
moreEntities.forEach(entity -> assertThat(tm().transact(() -> tm().exists(entity))).isFalse());
insertInDb(moreEntities.get(0));
assertThat(assertThrows(PersistenceException.class, () -> insertInDb(moreEntities)).getCause())
persistResource(moreEntities.get(0));
assertThat(
assertThrows(
PersistenceException.class,
() -> tm().transact(() -> tm().insertAll(moreEntities)))
.getCause())
.isInstanceOf(RollbackException.class);
assertThat(tm().transact(() -> tm().exists(moreEntities.get(0)))).isTrue();
assertThat(tm().transact(() -> tm().exists(moreEntities.get(1)))).isFalse();
@@ -424,7 +429,7 @@ class JpaTransactionManagerImplTest {
@Test
void put_updatesExistingEntity() {
insertInDb(theEntity);
persistResource(theEntity);
TestEntity persisted = tm().transact(() -> tm().loadByKey(theEntityKey));
assertThat(persisted.data).isEqualTo("foo");
theEntity.data = "bar";
@@ -444,7 +449,7 @@ class JpaTransactionManagerImplTest {
@Test
void update_succeeds() {
insertInDb(theEntity);
persistResource(theEntity);
TestEntity persisted =
tm().transact(() -> tm().loadByKey(VKey.create(TestEntity.class, "theEntity")));
assertThat(persisted.data).isEqualTo("foo");
@@ -456,7 +461,7 @@ class JpaTransactionManagerImplTest {
@Test
void updateCompoundIdEntity_succeeds() {
insertInDb(compoundIdEntity);
persistResource(compoundIdEntity);
TestCompoundIdEntity persisted = tm().transact(() -> tm().loadByKey(compoundIdEntityKey));
assertThat(persisted.data).isEqualTo("foo");
compoundIdEntity.data = "bar";
@@ -474,7 +479,7 @@ class JpaTransactionManagerImplTest {
@Test
void updateAll_succeeds() {
insertInDb(moreEntities);
persistResources(moreEntities);
ImmutableList<TestEntity> updated =
ImmutableList.of(
new TestEntity("entity1", "foo_updated"),
@@ -487,7 +492,7 @@ class JpaTransactionManagerImplTest {
@Test
void updateAll_rollsBackWhenFailure() {
insertInDb(moreEntities);
persistResources(moreEntities);
ImmutableList<TestEntity> updated =
ImmutableList.of(
new TestEntity("entity1", "foo_updated"),
@@ -503,7 +508,7 @@ class JpaTransactionManagerImplTest {
@Test
void load_succeeds() {
assertThat(tm().transact(() -> tm().exists(theEntity))).isFalse();
insertInDb(theEntity);
persistResource(theEntity);
TestEntity persisted =
tm().transact(() -> assertDetachedFromEntityManager(tm().loadByKey(theEntityKey)));
assertThat(persisted.name).isEqualTo("theEntity");
@@ -519,7 +524,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadByEntity_succeeds() {
insertInDb(theEntity);
persistResource(theEntity);
TestEntity persisted =
tm().transact(() -> assertDetachedFromEntityManager(tm().loadByEntity(theEntity)));
assertThat(persisted.name).isEqualTo("theEntity");
@@ -529,7 +534,7 @@ class JpaTransactionManagerImplTest {
@Test
void maybeLoad_succeeds() {
assertThat(tm().transact(() -> tm().exists(theEntity))).isFalse();
insertInDb(theEntity);
persistResource(theEntity);
TestEntity persisted =
tm().transact(
() -> assertDetachedFromEntityManager(tm().loadByKeyIfPresent(theEntityKey).get()));
@@ -546,7 +551,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadCompoundIdEntity_succeeds() {
assertThat(tm().transact(() -> tm().exists(compoundIdEntity))).isFalse();
insertInDb(compoundIdEntity);
persistResource(compoundIdEntity);
TestCompoundIdEntity persisted =
tm().transact(() -> assertDetachedFromEntityManager(tm().loadByKey(compoundIdEntityKey)));
assertThat(persisted.name).isEqualTo("compoundIdEntity");
@@ -556,7 +561,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadByKeysIfPresent() {
insertInDb(theEntity);
persistResource(theEntity);
tm().transact(
() -> {
ImmutableMap<VKey<? extends TestEntity>, TestEntity> results =
@@ -571,7 +576,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadByKeys_succeeds() {
insertInDb(theEntity);
persistResource(theEntity);
tm().transact(
() -> {
ImmutableMap<VKey<? extends TestEntity>, TestEntity> results =
@@ -583,7 +588,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadByEntitiesIfPresent_succeeds() {
insertInDb(theEntity);
persistResource(theEntity);
tm().transact(
() -> {
ImmutableList<TestEntity> results =
@@ -596,7 +601,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadByEntities_succeeds() {
insertInDb(theEntity);
persistResource(theEntity);
tm().transact(
() -> {
ImmutableList<TestEntity> results = tm().loadByEntities(ImmutableList.of(theEntity));
@@ -607,7 +612,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadAll_succeeds() {
insertInDb(moreEntities);
persistResources(moreEntities);
ImmutableList<TestEntity> persisted =
tm().transact(
() ->
@@ -619,7 +624,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadSingleton_detaches() {
insertInDb(theEntity);
persistResource(theEntity);
tm().transact(
() ->
assertThat(
@@ -629,7 +634,7 @@ class JpaTransactionManagerImplTest {
@Test
void delete_succeeds() {
insertInDb(theEntity);
persistResource(theEntity);
assertThat(tm().transact(() -> tm().exists(theEntity))).isTrue();
tm().transact(() -> tm().delete(theEntityKey));
assertThat(tm().transact(() -> tm().exists(theEntity))).isFalse();
@@ -644,7 +649,7 @@ class JpaTransactionManagerImplTest {
@Test
void deleteCompoundIdEntity_succeeds() {
insertInDb(compoundIdEntity);
persistResource(compoundIdEntity);
assertThat(tm().transact(() -> tm().exists(compoundIdEntity))).isTrue();
tm().transact(() -> tm().delete(compoundIdEntityKey));
assertThat(tm().transact(() -> tm().exists(compoundIdEntity))).isFalse();
@@ -674,7 +679,7 @@ class JpaTransactionManagerImplTest {
@Test
void loadAfterUpdate_fails() {
insertInDb(theEntity);
persistResource(theEntity);
assertThat(
assertThrows(
IllegalStateException.class,
@@ -690,7 +695,7 @@ class JpaTransactionManagerImplTest {
@Test
void cqQuery_detaches() {
insertInDb(moreEntities);
persistResources(moreEntities);
tm().transact(
() ->
assertThat(
@@ -724,7 +729,7 @@ class JpaTransactionManagerImplTest {
@Test
void query_detachesResults() {
insertInDb(moreEntities);
persistResources(moreEntities);
tm().transact(
() ->
tm().query("FROM TestEntity", TestEntity.class)
@@ -21,7 +21,7 @@ import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHost;
import static google.registry.testing.FullFieldsTestEntityHelper.makeDomain;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
@@ -78,7 +78,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
createTld("lol");
Registrar registrarLol = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrarLol));
persistResources(makeRegistrarPocs(registrarLol));
registrantLol =
FullFieldsTestEntityHelper.makeAndPersistContact(
"5372808-ERL",
@@ -152,7 +152,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
createTld("xn--q9jyb4c");
Registrar registrarIdn =
persistResource(makeRegistrar("idnregistrar", "IDN Registrar", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrarIdn));
persistResources(makeRegistrarPocs(registrarIdn));
Contact registrantIdn =
FullFieldsTestEntityHelper.makeAndPersistContact(
"5372808-ERL",
@@ -188,7 +188,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
createTld("1.tld");
Registrar registrar1Tld = persistResource(
makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrar1Tld));
persistResources(makeRegistrarPocs(registrar1Tld));
Contact registrant1Tld =
FullFieldsTestEntityHelper.makeAndPersistContact(
"5372808-ERL",
@@ -21,7 +21,6 @@ import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistDomainAsDeleted;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.FullFieldsTestEntityHelper.makeDomain;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
@@ -131,7 +130,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
registrar =
persistResource(
makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrar));
persistResources(makeRegistrarPocs(registrar));
contact1 =
FullFieldsTestEntityHelper.makeAndPersistContact(
"5372808-ERL", "Goblin Market", "lol@cat.lol", clock.nowUtc().minusYears(1), registrar);
@@ -209,7 +208,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
registrar =
persistResource(
makeRegistrar("goodregistrar", "St. John Chrysostom", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrar));
persistResources(makeRegistrarPocs(registrar));
domainCatExample =
persistResource(
makeDomain(
@@ -246,7 +245,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
// cat.みんな
createTld("xn--q9jyb4c");
registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrar));
persistResources(makeRegistrarPocs(registrar));
domainIdn =
persistResource(
makeDomain(
@@ -285,7 +284,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
// cat.1.test
createTld("1.test");
registrar = persistResource(makeRegistrar("multiregistrar", "1.test", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrar));
persistResources(makeRegistrarPocs(registrar));
domainMultipart =
persistResource(
makeDomain(
@@ -17,7 +17,7 @@ package google.registry.rdap;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistDeletedContact;
import static google.registry.testing.FullFieldsTestEntityHelper.makeDomain;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHost;
@@ -63,7 +63,7 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
createTld("lol");
registrarLol = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE, 101L));
persistSimpleResources(makeRegistrarPocs(registrarLol));
persistResources(makeRegistrarPocs(registrarLol));
registrant =
FullFieldsTestEntityHelper.makeAndPersistContact(
"8372808-REG",
@@ -96,16 +96,16 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
createTld("xn--q9jyb4c");
Registrar registrarIdn = persistResource(
makeRegistrar("idnregistrar", "IDN Registrar", Registrar.State.ACTIVE, 102L));
persistSimpleResources(makeRegistrarPocs(registrarIdn));
persistResources(makeRegistrarPocs(registrarIdn));
// 1.tld
createTld("1.tld");
Registrar registrar1tld = persistResource(
makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE, 103L));
persistSimpleResources(makeRegistrarPocs(registrar1tld));
persistResources(makeRegistrarPocs(registrar1tld));
// deleted registrar
Registrar registrarDeleted = persistResource(
makeRegistrar("deletedregistrar", "Yes Virginia <script>", Registrar.State.PENDING, 104L));
persistSimpleResources(makeRegistrarPocs(registrarDeleted));
persistResources(makeRegistrarPocs(registrarDeleted));
// other contacts
disconnectedContact =
FullFieldsTestEntityHelper.makeAndPersistContact(
@@ -20,7 +20,6 @@ import static google.registry.request.Action.Method.GET;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistDeletedContact;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
@@ -109,12 +108,12 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
registrarDeleted =
persistResource(
makeRegistrar("2-Registrar", "Yes Virginia <script>", Registrar.State.ACTIVE, 20L));
persistSimpleResources(makeRegistrarPocs(registrarDeleted));
persistResources(makeRegistrarPocs(registrarDeleted));
// inactive
registrarInactive =
persistResource(makeRegistrar("2-RegistrarInact", "No Way", Registrar.State.PENDING, 21L));
persistSimpleResources(makeRegistrarPocs(registrarInactive));
persistResources(makeRegistrarPocs(registrarInactive));
// test
registrarTest =
@@ -124,7 +123,7 @@ class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEntitySear
.setType(Registrar.Type.TEST)
.setIanaIdentifier(null)
.build());
persistSimpleResources(makeRegistrarPocs(registrarTest));
persistResources(makeRegistrarPocs(registrarTest));
FullFieldsTestEntityHelper.makeAndPersistContact(
"blinky",
@@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.rdap.RdapDataStructures.EventAction.TRANSFER;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHost;
import static google.registry.testing.FullFieldsTestEntityHelper.makeDomain;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
@@ -95,7 +95,7 @@ class RdapJsonFormatterTest {
clock.setTo(DateTime.parse("2000-01-01T00:00:00Z"));
registrar = persistResource(registrar);
persistSimpleResources(makeMoreRegistrarContacts(registrar));
persistResources(makeMoreRegistrarContacts(registrar));
contactRegistrant =
FullFieldsTestEntityHelper.makeAndPersistContact(
@@ -21,7 +21,6 @@ import static google.registry.request.Action.Method.GET;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistResources;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.FullFieldsTestEntityHelper.makeDomain;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarPocs;
@@ -103,7 +102,7 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
Registrar registrar =
persistResource(
makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrar));
persistResources(makeRegistrarPocs(registrar));
hostNs1CatLol =
FullFieldsTestEntityHelper.makeAndPersistHost(
"ns1.cat.lol", "1.2.3.4", clock.nowUtc().minusYears(1));
@@ -118,14 +117,14 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
// cat.みんな
createTld("xn--q9jyb4c");
registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrar));
persistResources(makeRegistrarPocs(registrar));
FullFieldsTestEntityHelper.makeAndPersistHost(
"ns1.cat.みんな", "1.2.3.5", clock.nowUtc().minusYears(1));
// cat.1.test
createTld("1.test");
registrar = persistResource(makeRegistrar("multiregistrar", "1.test", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrar));
persistResources(makeRegistrarPocs(registrar));
FullFieldsTestEntityHelper.makeAndPersistHost(
"ns1.cat.1.test", "1.2.3.6", clock.nowUtc().minusYears(1));
@@ -17,7 +17,7 @@ package google.registry.rdap;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.loadRegistrar;
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
import static google.registry.testing.DatabaseHelper.persistResource;
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -94,7 +94,7 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
private static void persistRegistrar(
String registrarId, Long ianaId, Registrar.Type type, String... rdapBaseUrls) {
persistSimpleResource(
persistResource(
new Registrar.Builder()
.setRegistrarId(registrarId)
.setRegistrarName(registrarId)

Some files were not shown because too many files have changed in this diff Show More