1
0
mirror of https://github.com/google/nomulus synced 2026-05-27 02:00:33 +00:00

Compare commits

..

19 Commits

Author SHA1 Message Date
Pavlo Tkach
e78ce42dd5 Add console DUM download (#2402)
* Add console DUM download

* Add console DUM download
2024-04-26 15:56:50 +00:00
Ben McIlwain
55fade497d Convert a bunch more @AutoValues to records (#2412) 2024-04-25 16:59:31 +00:00
gbrodman
e7501b621a Add DB column for separate rlock email address (#2413)
We cannot rely on the user checking their login email, so we'll want to
send the emails to the other address if configured. This is already the
case in RegistrarPoc.
2024-04-25 15:38:57 +00:00
Weimin Yu
9c443bede1 Fix conflicts between locks (#2407)
Use REPEATABLE READ for lock acquire/release operation to avoid conlicts
between locks.

Postgresql uses table scan on small tables, causing false sharing at
the SERIALIZABLE isolation level.

See b/333537928 for details.
2024-04-24 18:51:18 +00:00
Lai Jiang
6d0a746b76 Bind console users to the appropriate IAP roles upon creation (#2403)
Console users need IAP to inject the necessary OIDC tokens into their
request headers and therefore need to be bound to appropriate roles. Note
that in environments managed by latchkey, the bindings will need to be
present in latchkey config files as well, otherwise the changes made by
the nomulus tool will be reverted.

TESTED=ran the nomulus command against alpha and verified that the
bindings are created/removed upon console user creation/deletion.
2024-04-24 15:03:43 +00:00
Pavlo Tkach
0765e7b209 Console deps update (#2409)
* Update angular/core to 17.3.5

* Update angular/material 17.3.5

* Update angular/cli 17.3.5

* Update angular-eslint 17.3.0

* Disable cli cache

* General console deps update
2024-04-23 19:38:32 +00:00
sarahcaseybot
f729802094 Make createBillingCostTransitions not null (#2405)
* Make createBillingCostTransitions not null

* Set up createBillingCost field to be removed form config files

* Add clarifying comment
2024-04-23 18:22:45 +00:00
Ben McIlwain
e809e967a3 Convert more @AutoValues to records, particularly in custom flow classes (#2408) 2024-04-22 20:25:33 +00:00
Pavlo Tkach
4de2bd5901 Add console backend for EPP password change (#2396) 2024-04-20 10:44:26 +00:00
sarahcaseybot
b5629ff16f Run deleteProberData cron job daily (#2406)
* Run deleteProberData cron job daily

* Sign the commits

* try signing again
2024-04-19 19:32:14 +00:00
Ben McIlwain
91615aef54 Handle bad header names in registrar sheet syncing action (#2404)
The existing behavior was to ignore bad header names, in a way that was
counter-intuitive as a user of the Google Sheet. If a header name was bad (which
could just be someone accidentally changing it not realizing it needs to
correspond exactly to the name of the field on the Java object), then all of the
data in that column was just silently left as-is and never updated. This led to
gradually worsening sync and offset shift errors over time.

Now, it will write out an error message into every single cell in the bad
column, so it's clear that the column name is wrong and does not correspond to any
actual data in the DB.

BUG=http://b/332336068
2024-04-19 17:59:58 +00:00
Ben McIlwain
fa6898167b Convert more @AutoValues to Java records (#2378) 2024-04-17 19:30:23 +00:00
Lai Jiang
903b7979de Upgrade to jline 3 (#2400)
jline 3 contains API breaking changes, necessitating changes in
ShellCommand.
2024-04-12 19:57:02 +00:00
Weimin Yu
8721085d14 Fix BSA validation (#2401)
Unblocked reserved names wrongly reported as missing unblockable domain.
2024-04-12 19:54:59 +00:00
Lai Jiang
e434528cd3 Add nomulus deployment and service manifests (#2389) 2024-04-11 19:01:09 +00:00
Pavlo Tkach
9ca54e4364 Add UI for EPP Password update (#2393) 2024-04-10 22:29:52 +00:00
Weimin Yu
a16794e2af Run BSA Validate without lock (#2399)
As a read-only action that tolerates staleness, locking is unnecessary.
This should help with the lock contention we are observing.

Also reduces the number of VM instances provisioned for BSA and increase
the idle timeout. This should reduce invocation delay. Longer delay may
cause AppEngine to return `Timeout` status to Cloud Scheduler even
though the cron job succeeds.
2024-04-10 19:58:24 +00:00
Lai Jiang
496a781572 Upgrade jcommander (#2398) 2024-04-10 17:34:11 +00:00
Ben McIlwain
2df583df1a Statically import Truth.assertThat() in tests (#2395)
This also involved breaking out an improperly done assertThat() helper overload
method for JsonObjects into a proper Subject that doesn't further overload
assertThat().
2024-04-09 16:27:26 +00:00
216 changed files with 5506 additions and 4392 deletions

View File

@@ -122,6 +122,9 @@
}
},
"cli": {
"cache": {
"enabled": false
},
"analytics": false,
"schematicCollections": [
"@angular-eslint/schematics"

File diff suppressed because it is too large Load Diff

View File

@@ -16,35 +16,35 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^17.0.7",
"@angular/cdk": "^17.0.4",
"@angular/common": "^17.0.7",
"@angular/compiler": "^17.0.7",
"@angular/core": "^17.0.7",
"@angular/forms": "^17.0.7",
"@angular/material": "^17.0.4",
"@angular/platform-browser": "^17.0.7",
"@angular/platform-browser-dynamic": "^17.0.7",
"@angular/router": "^17.0.7",
"@angular/animations": "^17.3.5",
"@angular/cdk": "^17.3.5",
"@angular/common": "^17.3.5",
"@angular/compiler": "^17.3.5",
"@angular/core": "^17.3.5",
"@angular/forms": "^17.3.5",
"@angular/material": "^17.3.5",
"@angular/platform-browser": "^17.3.5",
"@angular/platform-browser-dynamic": "^17.3.5",
"@angular/router": "^17.3.5",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.0.7",
"@angular-eslint/builder": "17.1.1",
"@angular-eslint/eslint-plugin": "17.1.1",
"@angular-eslint/eslint-plugin-template": "17.1.1",
"@angular-eslint/schematics": "17.1.1",
"@angular-eslint/template-parser": "17.1.1",
"@angular/cli": "~17.0.7",
"@angular/compiler-cli": "^17.0.7",
"@angular-devkit/build-angular": "^17.3.5",
"@angular-eslint/builder": "17.3.0",
"@angular-eslint/eslint-plugin": "17.3.0",
"@angular-eslint/eslint-plugin-template": "17.3.0",
"@angular-eslint/schematics": "17.3.0",
"@angular-eslint/template-parser": "17.3.0",
"@angular/cli": "~17.3.5",
"@angular/compiler-cli": "^17.3.5",
"@types/jasmine": "~4.0.0",
"@types/node": "^18.11.18",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"concurrently": "^7.6.0",
"eslint": "^8.39.0",
"eslint": "^8.57.0",
"jasmine-core": "~4.3.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
@@ -54,4 +54,4 @@
"prettier": "2.8.7",
"typescript": "~5.2.2"
}
}
}

View File

@@ -36,6 +36,7 @@ import { RegistrarComponent } from './registrar/registrarsTable.component';
import { ResourcesComponent } from './resources/resources.component';
import SettingsContactComponent from './settings/contact/contact.component';
import { ContactDetailsComponent } from './settings/contact/contactDetails.component';
import EppPasswordEditComponent from './settings/security/eppPasswordEdit.component';
import SecurityComponent from './settings/security/security.component';
import SecurityEditComponent from './settings/security/securityEdit.component';
import { SettingsComponent } from './settings/settings.component';
@@ -57,6 +58,7 @@ import { TldsComponent } from './tlds/tlds.component';
BillingInfoComponent,
ContactDetailsComponent,
DomainListComponent,
EppPasswordEditComponent,
HeaderComponent,
HomeComponent,
LocationBackDirective,

View File

@@ -1,6 +1,6 @@
<app-selected-registrar-wrapper>
<h1 class="mat-headline-4">Domains</h1>
<div class="console-domains">
<h1 class="mat-headline-4">Domains</h1>
@if (totalResults === 0) {
<div class="console-app__empty-domains">
<h1>
@@ -13,6 +13,17 @@
} @else if(isLoading) {
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
} @else {
<a
mat-stroked-button
color="primary"
href="/console-api/dum-download?registrarId={{
registrarService.registrarId()
}}"
class="console-app-domains__download"
>
<mat-icon>download</mat-icon>
Download domains (.csv)
</a>
<mat-form-field class="console-app__domains-filter">
<mat-label>Filter</mat-label>
<input

View File

@@ -12,6 +12,15 @@
}
}
&-domains {
position: relative;
&__download {
position: absolute;
top: 0;
right: 0;
}
}
&__domains {
width: 100%;
overflow: auto;

View File

@@ -54,7 +54,7 @@ export class DomainListComponent {
constructor(
private backendService: BackendService,
private domainListService: DomainListService,
private registrarService: RegistrarService,
protected registrarService: RegistrarService,
private _snackBar: MatSnackBar
) {
effect(() => {

View File

@@ -12,16 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { NgModule } from '@angular/core';
import { A11yModule } from '@angular/cdk/a11y';
import { DialogModule } from '@angular/cdk/dialog';
import { CdkMenuModule } from '@angular/cdk/menu';
import { OverlayModule } from '@angular/cdk/overlay';
import { CdkTableModule } from '@angular/cdk/table';
import { CdkTreeModule } from '@angular/cdk/tree';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatBadgeModule } from '@angular/material/badge';
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips';
import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
import { MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';
import { MatGridListModule } from '@angular/material/grid-list';
@@ -29,24 +36,18 @@ import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatRadioModule } from '@angular/material/radio';
import { MatSelectModule } from '@angular/material/select';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTableModule } from '@angular/material/table';
import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatTreeModule } from '@angular/material/tree';
import { OverlayModule } from '@angular/cdk/overlay';
import { CdkMenuModule } from '@angular/cdk/menu';
import { DialogModule } from '@angular/cdk/dialog';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatChipsModule } from '@angular/material/chips';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
@NgModule({
exports: [
@@ -85,6 +86,7 @@ import { MatAutocompleteModule } from '@angular/material/autocomplete';
MatPaginatorModule,
MatChipsModule,
MatAutocompleteModule,
ReactiveFormsModule,
],
})
export class MaterialModule {}

View File

@@ -23,6 +23,10 @@ import {
GlobalLoaderService,
} from '../shared/services/globalLoader.service';
export interface IpAllowListItem {
value: string;
}
export interface Address {
city?: string;
countryCode?: string;
@@ -31,6 +35,19 @@ export interface Address {
zip?: string;
}
export interface SecuritySettingsBackendModel {
clientCertificate?: string;
failoverClientCertificate?: string;
ipAddressAllowList?: Array<string>;
// TODO: @ptkach At some point we want to add a back-end support for this
eppPasswordLastUpdated?: string;
}
export interface SecuritySettings
extends Omit<SecuritySettingsBackendModel, 'ipAddressAllowList'> {
ipAddressAllowList?: Array<IpAllowListItem>;
}
export interface WhoisRegistrarFields {
ianaIdentifier?: number;
icannReferralEmail: string;
@@ -40,13 +57,14 @@ export interface WhoisRegistrarFields {
whoisServer: string;
}
export interface Registrar extends WhoisRegistrarFields {
export interface Registrar
extends WhoisRegistrarFields,
SecuritySettingsBackendModel {
allowedTlds?: string[];
billingAccountMap?: object;
driveFolderId?: string;
emailAddress?: string;
faxNumber?: string;
ipAddressAllowList?: string[];
phoneNumber?: string;
registrarId: string;
registrarName: string;

View File

@@ -25,6 +25,9 @@
font-weight: 500;
padding: 10px 0;
}
.contact__name-column-roles {
margin-bottom: 10px;
}
}
&__empty-contacts {
display: flex;

View File

@@ -17,10 +17,9 @@ import { MatTableDataSource } from '@angular/material/table';
import { take } from 'rxjs';
import { RegistrarService } from 'src/app/registrar/registrar.service';
import {
Contact,
ContactService,
ViewReadyContact,
contactTypeToViewReadyContact,
ViewReadyContact,
} from './contact.service';
@Component({
@@ -85,7 +84,7 @@ export default class ContactComponent {
});
}
openDetails(contact: Contact) {
openDetails(contact: ViewReadyContact) {
this.contactService.setEditableContact(contact);
this.contactService.isContactDetailsView = true;
}

View File

@@ -77,19 +77,17 @@ export class ContactService {
private registrarService: RegistrarService
) {}
setEditableContact(contact?: Contact) {
this.contactInEdit = contactTypeToViewReadyContact(
contact
? contact
: {
emailAddress: '',
name: '',
types: ['ADMIN'],
faxNumber: '',
phoneNumber: '',
registrarId: '',
}
);
setEditableContact(contact?: ViewReadyContact) {
this.contactInEdit = contact
? contact
: contactTypeToViewReadyContact({
emailAddress: '',
name: '',
types: ['ADMIN'],
faxNumber: '',
phoneNumber: '',
registrarId: '',
});
}
fetchContacts(): Observable<Contact[]> {
@@ -106,13 +104,6 @@ export class ContactService {
.pipe(switchMap((_) => this.fetchContacts()));
}
updateContact(index: number, contact: ViewReadyContact) {
const newContacts = this.contacts().map((c, i) =>
i === index ? contact : c
);
return this.saveContacts(newContacts);
}
addContact(contact: ViewReadyContact) {
const newContacts = this.contacts().concat([contact]);
return this.saveContacts(newContacts);

View File

@@ -65,16 +65,17 @@ export class ContactDetailsComponent {
save(e: SubmitEvent) {
e.preventDefault();
this.contactService
.saveContacts([this.contactService.contactInEdit])
.subscribe({
complete: () => {
this.goBack();
},
error: (err: HttpErrorResponse) => {
this._snackBar.open(err.error);
},
});
const request = this.contactService.isContactNewView
? this.contactService.addContact(this.contactService.contactInEdit)
: this.contactService.saveContacts(this.contactService.contacts());
request.subscribe({
complete: () => {
this.goBack();
},
error: (err: HttpErrorResponse) => {
this._snackBar.open(err.error);
},
});
}
checkboxIsChecked(type: string) {

View File

@@ -0,0 +1,76 @@
<div class="settings-security__edit-password">
<p>
<button
mat-icon-button
aria-label="Back to security settings"
(click)="goBack()"
>
<mat-icon>arrow_back</mat-icon>
</button>
</p>
<h1>Update EPP password</h1>
<p class="secondary-text">
Passwords must be between 6 and 16 alphanumeric characters
</p>
<form
(ngSubmit)="save()"
[formGroup]="passwordUpdateForm"
class="settings-security__edit-password-form"
>
<div class="settings-security__edit-password-field">
<mat-form-field appearance="outline">
<mat-label>Old password: </mat-label>
<input
matInput
type="text"
formControlName="oldPassword"
required
autocomplete="current-password"
/>
<mat-error *ngIf="hasError('oldPassword') as errorText">{{
errorText
}}</mat-error>
</mat-form-field>
</div>
<div class="settings-security__edit-password-field">
<mat-form-field appearance="outline">
<mat-label>New password: </mat-label>
<input
matInput
type="text"
formControlName="newPassword"
required
autocomplete="new-password"
/>
<mat-error *ngIf="hasError('newPassword') as errorText">{{
errorText
}}</mat-error>
</mat-form-field>
</div>
<div class="settings-security__edit-password-field">
<mat-form-field appearance="outline">
<mat-label>Confirm new password: </mat-label>
<input
matInput
type="text"
formControlName="newPasswordRepeat"
required
autocomplete="new-password"
/>
<mat-error *ngIf="hasError('newPasswordRepeat') as errorText">{{
errorText
}}</mat-error>
</mat-form-field>
</div>
<button
mat-flat-button
color="primary"
[disabled]="!passwordUpdateForm.valid"
aria-label="Save epp password update"
type="submit"
class="settings-security__edit-password-save"
>
Save
</button>
</form>
</div>

View File

@@ -0,0 +1,16 @@
.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;
}
}

View File

@@ -0,0 +1,109 @@
// Copyright 2024 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.
import { Component } from '@angular/core';
import {
AbstractControl,
FormControl,
FormGroup,
ValidatorFn,
Validators,
} from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
import { RegistrarService } from 'src/app/registrar/registrar.service';
import { SecurityService } from './security.service';
type errorCode = 'required' | 'maxlength' | 'minlength' | 'passwordsDontMatch';
type errorFriendlyText = { [type in errorCode]: String };
@Component({
selector: 'app-epp-password-edit',
templateUrl: './eppPasswordEdit.component.html',
styleUrls: ['./eppPasswordEdit.component.scss'],
})
export default class EppPasswordEditComponent {
MIN_MAX_LENGHT = new String(
'Passwords must be between 6 and 16 alphanumeric characters'
);
errorTextMap: errorFriendlyText = {
required: "This field can't be empty",
maxlength: this.MIN_MAX_LENGHT,
minlength: this.MIN_MAX_LENGHT,
passwordsDontMatch: "Passwords don't match",
};
constructor(
public securityService: SecurityService,
private _snackBar: MatSnackBar,
public registrarService: RegistrarService
) {}
hasError(controlName: string) {
const maybeErrors = this.passwordUpdateForm.get(controlName)?.errors;
const maybeError =
maybeErrors && (Object.keys(maybeErrors)[0] as errorCode);
if (maybeError) {
return this.errorTextMap[maybeError];
}
return '';
}
newPasswordsMatch: ValidatorFn = (control: AbstractControl) => {
if (
this.passwordUpdateForm?.get('newPassword')?.value ===
this.passwordUpdateForm?.get('newPasswordRepeat')?.value
) {
this.passwordUpdateForm?.get('newPasswordRepeat')?.setErrors(null);
} else {
this.passwordUpdateForm
?.get('newPasswordRepeat')
?.setErrors({ passwordsDontMatch: control.value });
}
return null;
};
passwordUpdateForm = new FormGroup({
oldPassword: new FormControl('', [Validators.required]),
newPassword: new FormControl('', [
Validators.required,
Validators.minLength(6),
Validators.maxLength(16),
this.newPasswordsMatch,
]),
newPasswordRepeat: new FormControl('', [
Validators.required,
Validators.minLength(6),
Validators.maxLength(16),
this.newPasswordsMatch,
]),
});
save() {
debugger;
// this.securityService.saveEppPassword().subscribe({
// complete: () => {
// this.goBack();
// },
// error: (err: HttpErrorResponse) => {
// this._snackBar.open(err.error);
// },
// });
}
goBack() {
this.securityService.isEditingPassword = false;
}
}

View File

@@ -1,7 +1,48 @@
@if(securityService.isEditingSecurity) {
<app-security-edit></app-security-edit>
} @else if(securityService.isEditingPassword) {
<app-epp-password-edit></app-epp-password-edit>
} @else {
<div class="settings-security">
<mat-card appearance="outlined">
<mat-card-content>
<mat-list role="list">
<!-- IP Allowlist Start -->
<mat-list-item role="listitem">
<div class="settings-security__section-header">
<h2>EPP Password</h2>
<button
mat-flat-button
color="primary"
aria-label="Edit EPP Password"
(click)="editEppPassword()"
>
<mat-icon>edit</mat-icon>
Edit
</button>
</div>
</mat-list-item>
<mat-list-item role="listitem" lines="3">
<span class="console-app__list-value"
>todo: come up with a text here</span
>
</mat-list-item>
<mat-list-item role="listitem">
<span class="console-app__list-key">Password</span>
<span class="console-app__list-value">••••••••••••••</span>
</mat-list-item>
@if(dataSource.eppPasswordLastUpdated) {
<mat-divider></mat-divider>
<mat-list-item role="listitem">
<span class="console-app__list-key">Last Changed</span>
<span class="console-app__list-value">{{
dataSource.eppPasswordLastUpdated
}}</span>
</mat-list-item>
}
</mat-list>
</mat-card-content>
</mat-card>
<mat-card appearance="outlined">
<mat-card-content>
<mat-list role="list">
@@ -12,7 +53,7 @@
<button
mat-flat-button
color="primary"
aria-label="Edit Contact"
aria-label="Edit security settings"
(click)="editSecurity()"
>
<mat-icon>edit</mat-icon>

View File

@@ -13,12 +13,11 @@
// limitations under the License.
import { Component, effect } from '@angular/core';
import { RegistrarService } from 'src/app/registrar/registrar.service';
import {
SecurityService,
RegistrarService,
SecuritySettings,
apiToUiConverter,
} from './security.service';
} from 'src/app/registrar/registrar.service';
import { SecurityService, apiToUiConverter } from './security.service';
@Component({
selector: 'app-security',
@@ -43,4 +42,8 @@ export default class SecurityComponent {
editSecurity() {
this.securityService.isEditingSecurity = true;
}
editEppPassword() {
this.securityService.isEditingPassword = true;
}
}

View File

@@ -14,24 +14,14 @@
import { Injectable } from '@angular/core';
import { switchMap } from 'rxjs';
import { RegistrarService } from 'src/app/registrar/registrar.service';
import {
IpAllowListItem,
RegistrarService,
SecuritySettings,
SecuritySettingsBackendModel,
} from 'src/app/registrar/registrar.service';
import { BackendService } from 'src/app/shared/services/backend.service';
export interface ipAllowListItem {
value: string;
}
export interface SecuritySettings {
clientCertificate?: string;
failoverClientCertificate?: string;
ipAddressAllowList?: Array<ipAllowListItem>;
}
export interface SecuritySettingsBackendModel {
clientCertificate?: string;
failoverClientCertificate?: string;
ipAddressAllowList?: Array<string>;
}
export function apiToUiConverter(
securitySettings: SecuritySettingsBackendModel = {}
): SecuritySettings {
@@ -48,7 +38,7 @@ export function uiToApiConverter(
return Object.assign({}, securitySettings, {
ipAddressAllowList: (securitySettings.ipAddressAllowList || [])
.filter((s) => s.value)
.map((ipAllowItem: ipAllowListItem) => ipAllowItem.value),
.map((ipAllowItem: IpAllowListItem) => ipAllowItem.value),
});
}
@@ -58,6 +48,7 @@ export function uiToApiConverter(
export class SecurityService {
securitySettings: SecuritySettings = {};
isEditingSecurity: boolean = false;
isEditingPassword: boolean = false;
constructor(
private backend: BackendService,
@@ -76,4 +67,6 @@ export class SecurityService {
})
);
}
saveEppPassword() {}
}

View File

@@ -15,13 +15,12 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { RegistrarService } from 'src/app/registrar/registrar.service';
import {
SecurityService,
IpAllowListItem,
RegistrarService,
SecuritySettings,
apiToUiConverter,
ipAllowListItem,
} from './security.service';
} from 'src/app/registrar/registrar.service';
import { SecurityService, apiToUiConverter } from './security.service';
@Component({
selector: 'app-security-edit',
@@ -58,7 +57,7 @@ export default class SecurityEditComponent {
this.securityService.isEditingSecurity = false;
}
removeIpEntry(ip: ipAllowListItem) {
removeIpEntry(ip: IpAllowListItem) {
this.dataSource.ipAddressAllowList =
this.dataSource.ipAddressAllowList?.filter((item) => item !== ip);
}

View File

@@ -15,11 +15,11 @@
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, catchError, of, throwError } from 'rxjs';
import { SecuritySettingsBackendModel } from 'src/app/settings/security/security.service';
import { DomainListResult } from 'src/app/domains/domainList.service';
import {
Registrar,
SecuritySettingsBackendModel,
WhoisRegistrarFields,
} from '../../registrar/registrar.service';
import { Contact } from '../../settings/contact/contact.service';

View File

@@ -130,7 +130,6 @@ dependencies {
testRuntimeOnly files(sourceSets.test.resources.srcDirs)
implementation deps['com.beust:jcommander']
implementation deps['com.github.ben-manes.caffeine:caffeine']
implementation deps['com.google.api:gax']
implementation deps['com.google.api.grpc:proto-google-common-protos']
@@ -150,6 +149,7 @@ dependencies {
implementation deps['com.google.apis:google-api-services-drive']
implementation deps['com.google.apis:google-api-services-gmail']
implementation deps['com.google.apis:google-api-services-groupssettings']
implementation deps['com.google.apis:google-api-services-iam']
implementation deps['com.google.apis:google-api-services-monitoring']
implementation deps['com.google.apis:google-api-services-sheets']
implementation deps['com.google.apis:google-api-services-storage']
@@ -200,7 +200,6 @@ dependencies {
implementation deps['javax.persistence:javax.persistence-api']
implementation deps['jakarta.servlet:jakarta.servlet-api']
implementation deps['javax.xml.bind:jaxb-api']
implementation deps['jline:jline']
implementation deps['joda-time:joda-time']
implementation deps['org.apache.avro:avro']
testImplementation deps['org.apache.beam:beam-runners-core-construction-java']
@@ -226,6 +225,8 @@ dependencies {
testImplementation deps['com.fasterxml.jackson.core:jackson-databind']
implementation deps['org.hibernate:hibernate-core']
implementation deps['org.hibernate:hibernate-hikaricp']
implementation deps['org.jcommander:jcommander']
implementation deps['org.jline:jline']
implementation deps['org.joda:joda-money']
implementation deps['org.json:json']
implementation deps['org.jsoup:jsoup']

View File

@@ -7,8 +7,6 @@ args4j:args4j:2.0.23=soy
args4j:args4j:2.0.26=css
args4j:args4j:2.33=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
cglib:cglib-nodep:2.2=css
com.101tec:zkclient:0.10=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.beust:jcommander:1.60=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.charleskorn.kaml:kaml:0.20.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-annotations:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-core:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -39,66 +37,67 @@ com.google.api-client:google-api-client-jackson2:2.0.1=compileClasspath,deploy_j
com.google.api-client:google-api-client-java6:2.1.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api-client:google-api-client-servlet:2.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api-client:google-api-client:1.35.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:gapic-google-cloud-storage-v2:2.36.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1:3.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.172.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta2:0.172.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.108.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-pubsublite-v1:1.12.20=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-admin-database-v1:6.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-admin-instance-v1:6.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-v1:6.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-storage-v2:2.36.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-common-protos:2.30.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1:3.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta1:0.172.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta2:0.172.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigtable-admin-v2:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigtable-v2:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-datastore-v1:0.109.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-firestore-v1:3.16.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:gapic-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1:3.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.173.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta2:0.173.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.108.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-pubsublite-v1:1.12.22=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-admin-database-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-admin-instance-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-common-protos:2.37.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1:3.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta1:0.173.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta2:0.173.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigtable-admin-v2:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigtable-v2:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-datastore-v1:0.109.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-firestore-v1:3.16.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-monitoring-v3:1.64.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
com.google.api.grpc:proto-google-cloud-monitoring-v3:3.34.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-pubsub-v1:1.108.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-pubsublite-v1:1.12.20=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-secretmanager-v1:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta1:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-admin-database-v1:6.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-admin-instance-v1:6.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-executor-v1:6.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-v1:6.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-storage-v2:2.36.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.127.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2beta3:0.127.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-common-protos:2.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-iam-v1:1.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:api-common:2.28.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-grpc:2.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-httpjson:2.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax:2.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-monitoring-v3:3.36.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-pubsub-v1:1.108.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-pubsublite-v1:1.12.22=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-secretmanager-v1:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta2:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-admin-database-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-admin-instance-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-executor-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.131.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2beta3:0.131.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-common-protos:2.37.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-iam-v1:1.32.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:api-common:2.29.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-grpc:2.46.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-httpjson:2.46.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax:2.46.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-admin-directory:directory_v1-rev20240304-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-appengine:v1-rev20240226-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-bigquery:v2-rev20230812-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-cloudresourcemanager:v1-rev20230806-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-bigquery:v2-rev20240124-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-cloudresourcemanager:v1-rev20240128-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-dataflow:v1b3-rev20240113-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-dns:v2beta1-rev99-1.25.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-drive:v2-rev393-1.25.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-gmail:v1-rev20231218-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-groupssettings:v1-rev20210624-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-healthcare:v1-rev20240110-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-healthcare:v1-rev20240130-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-iam:v2-rev20240314-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-iamcredentials:v1-rev20211203-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-monitoring:v3-rev20240303-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-monitoring:v3-rev20240414-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-pubsub:v1-rev20220904-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-sheets:v4-rev20230815-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-sqladmin:v1beta4-rev20240304-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-storage:v1-rev20240307-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-api-1.0-sdk:2.0.25=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-api-stubs:2.0.25=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-remote-api:2.0.25=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-testing:2.0.25=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-tools-sdk:2.0.25=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-sheets:v4-rev20240402-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-sqladmin:v1beta4-rev20240324-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-storage:v1-rev20240205-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-api-1.0-sdk:2.0.26=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-api-stubs:2.0.26=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-remote-api:2.0.26=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-testing:2.0.26=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-tools-sdk:2.0.26=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.auth:google-auth-library-credentials:1.23.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.auth:google-auth-library-oauth2-http:1.23.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.auto.service:auto-service-annotations:1.0.1=errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
@@ -112,35 +111,35 @@ com.google.closure-stylesheets:closure-stylesheets:1.5.0=css
com.google.cloud.bigdataoss:gcsio:2.2.16=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.bigdataoss:util:2.2.16=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.bigtable:bigtable-client-core-config:1.28.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.datastore:datastore-v1-proto-client:2.17.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.sql:jdbc-socket-factory-core:1.17.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.sql:postgres-socket-factory:1.17.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigquerystorage:3.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigtable-stats:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigtable:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core-grpc:2.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core-http:2.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core:2.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-firestore:3.16.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.datastore:datastore-v1-proto-client:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.sql:jdbc-socket-factory-core:1.18.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.sql:postgres-socket-factory:1.18.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigquerystorage:3.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigtable-stats:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigtable:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core-grpc:2.32.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core-http:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core:2.32.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-firestore:3.16.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-monitoring:1.82.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
com.google.cloud:google-cloud-monitoring:3.34.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-nio:0.127.14=testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-pubsub:1.126.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-pubsublite:1.12.20=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-secretmanager:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-spanner:6.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-storage:2.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-tasks:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-monitoring:3.36.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-nio:0.127.15=testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-pubsub:1.126.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-pubsublite:1.12.22=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-secretmanager:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-spanner:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-storage:2.32.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-tasks:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:grpc-gcp:1.5.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:proto-google-cloud-firestore-bundle-v1:3.16.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:proto-google-cloud-firestore-bundle-v1:3.16.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.code.findbugs:jsr305:3.0.1=css
com.google.code.findbugs:jsr305:3.0.2=annotationProcessor,checkstyle,compileClasspath,deploy_jar,errorprone,nonprodAnnotationProcessor,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.code.gson:gson:2.10.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.code.gson:gson:2.7=css,soy
com.google.common.html.types:types:1.0.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
com.google.dagger:dagger-compiler:2.51=annotationProcessor,testAnnotationProcessor
com.google.dagger:dagger-spi:2.51=annotationProcessor,testAnnotationProcessor
com.google.dagger:dagger:2.51=annotationProcessor,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.dagger:dagger-compiler:2.51.1=annotationProcessor,testAnnotationProcessor
com.google.dagger:dagger-spi:2.51.1=annotationProcessor,testAnnotationProcessor
com.google.dagger:dagger:2.51.1=annotationProcessor,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.devtools.ksp:symbol-processing-api:1.9.20-1.0.14=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_annotation:2.23.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_annotations:2.23.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
@@ -152,7 +151,7 @@ com.google.errorprone:error_prone_type_annotations:2.23.0=annotationProcessor,er
com.google.errorprone:javac-shaded:9-dev-r4023-3=annotationProcessor,testAnnotationProcessor
com.google.errorprone:javac:9+181-r4173-1=errorproneJavac
com.google.escapevelocity:escapevelocity:0.9.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
com.google.flatbuffers:flatbuffers-java:1.12.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.flatbuffers:flatbuffers-java:23.5.26=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.flogger:flogger-system-backend:0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.flogger:flogger:0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.flogger:google-extensions:0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -168,10 +167,10 @@ com.google.guava:guava:33.0.0-jre=annotationProcessor,testAnnotationProcessor
com.google.guava:guava:33.1.0-jre=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,checkstyle,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.gwt:gwt-user:2.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-apache-v2:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-apache-v2:1.43.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-appengine:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-gson:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-jackson2:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-jackson2:1.43.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-protobuf:1.43.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.inject.extensions:guice-multibindings:4.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
@@ -179,8 +178,7 @@ com.google.inject:guice:4.1.0=compileClasspath,deploy_jar,nonprodCompileClasspat
com.google.inject:guice:5.1.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
com.google.inject:guice:7.0.0=soy
com.google.j2objc:j2objc-annotations:1.3=checkstyle,soy
com.google.j2objc:j2objc-annotations:2.8=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath
com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath,testRuntimeClasspath
com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.javascript:closure-compiler-externs:v20160713=css
com.google.javascript:closure-compiler-unshaded:v20160713=css
com.google.javascript:closure-compiler:v20210505=closureCompiler
@@ -251,10 +249,6 @@ guru.nidi:graphviz-java-all-j2v8:0.18.1=testRuntimeClasspath
guru.nidi:graphviz-java:0.18.1=testRuntimeClasspath
info.picocli:picocli:4.6.2=checkstyle
io.apicurio:apicurio-registry-protobuf-schema-utilities:3.0.0.M2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.confluent:common-config:5.3.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.confluent:common-utils:5.3.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.confluent:kafka-avro-serializer:5.3.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.confluent:kafka-schema-registry-client:5.3.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.github.classgraph:classgraph:4.8.162=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.github.eisop:dataflow-errorprone:3.34.0-eisop1=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
io.github.java-diff-utils:java-diff-utils:4.12=annotationProcessor,deploy_jar,errorprone,nonprodAnnotationProcessor,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
@@ -268,11 +262,10 @@ io.grpc:grpc-googleapis:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspa
io.grpc:grpc-grpclb:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-inprocess:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-netty-shaded:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-netty:1.60.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-protobuf-lite:1.60.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
io.grpc:grpc-netty:1.61.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-protobuf-lite:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-protobuf:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-rls:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-rls:1.61.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-services:1.61.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
io.grpc:grpc-services:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-stub:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -305,6 +298,8 @@ io.opencensus:opencensus-exporter-stats-stackdriver:0.31.0=compileClasspath,depl
io.opencensus:opencensus-impl-core:0.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.opencensus:opencensus-impl:0.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.opencensus:opencensus-proto:0.2.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-api:1.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-context:1.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.outfoxx:swiftpoet:1.3.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.perfmark:perfmark-api:0.27.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
jakarta-regexp:jakarta-regexp:1.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -327,7 +322,6 @@ javax.servlet:servlet-api:2.5=compileClasspath,deploy_jar,nonprodCompileClasspat
javax.validation:validation-api:1.0.0.GA=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
javax.xml.bind:jaxb-api:2.3.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
javax.xml.bind:jaxb-api:2.4.0-b180830.0359=jaxb
jline:jline:1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
joda-time:joda-time:2.10.14=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
junit:junit:4.13.2=nonprodCompileClasspath,nonprodRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
net.arnx:nashorn-promise:0.1.1=testRuntimeClasspath
@@ -338,38 +332,38 @@ net.java.dev.javacc:javacc:4.1=css
net.java.dev.jna:jna:5.13.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
net.ltgt.gradle.incap:incap:0.2=annotationProcessor,testAnnotationProcessor
net.sf.saxon:Saxon-HE:10.6=checkstyle
org.antlr:antlr4-runtime:4.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.antlr:antlr4-runtime:4.9.3=checkstyle
org.apache.arrow:arrow-format:5.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-memory-core:5.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-vector:5.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-format:15.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-memory-core:15.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-vector:15.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.avro:avro:1.8.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-fn-execution:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-job-management:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-pipeline:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-core-construction-java:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-core-java:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-direct-java:2.54.0=testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-google-cloud-dataflow-java:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-java-fn-execution:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-core:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-expansion-service:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-arrow:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-avro:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-protobuf:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-fn-execution:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-harness:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-io-kafka:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-transform-service-launcher:2.54.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-vendor-grpc-1_60_1:0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-fn-execution:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-job-management:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-pipeline:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-core-construction-java:2.54.0=testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-core-java:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-direct-java:2.55.1=testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-google-cloud-dataflow-java:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-java-fn-execution:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-core:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-expansion-service:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-arrow:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-avro:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-protobuf:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-fn-execution:2.54.0=testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-harness:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-transform-service-launcher:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-vendor-grpc-1_60_1:0.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-vendor-guava-32_1_2-jre:0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-compress:1.24.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-csv:1.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-exec:1.3=testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-lang3:3.13.0=testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-lang3:3.14.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
org.apache.commons:commons-text:1.11.0=testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-lang3:3.14.0=testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-lang3:3.9=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
org.apache.commons:commons-text:1.12.0=testCompileClasspath,testRuntimeClasspath
org.apache.ftpserver:ftplet-api:1.2.0=testCompileClasspath,testRuntimeClasspath
org.apache.ftpserver:ftpserver-core:1.2.0=testCompileClasspath,testRuntimeClasspath
org.apache.httpcomponents:httpclient:4.5.14=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -379,12 +373,12 @@ org.apache.sshd:sshd-common:2.12.1=testCompileClasspath,testRuntimeClasspath
org.apache.sshd:sshd-core:2.12.1=testCompileClasspath,testRuntimeClasspath
org.apache.sshd:sshd-scp:2.12.1=testCompileClasspath,testRuntimeClasspath
org.apache.sshd:sshd-sftp:2.12.1=testCompileClasspath,testRuntimeClasspath
org.apache.tomcat:tomcat-annotations-api:11.0.0-M18=testCompileClasspath,testRuntimeClasspath
org.apache.tomcat:tomcat-annotations-api:11.0.0-M19=testCompileClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
org.bouncycastle:bcpg-jdk18on:1.77=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcpkix-jdk18on:1.77=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcprov-jdk18on:1.77=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcutil-jdk18on:1.77=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcpg-jdk18on:1.78=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcpkix-jdk18on:1.78=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcprov-jdk18on:1.78=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcutil-jdk18on:1.78=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.checkerframework:checker-compat-qual:2.5.3=compileClasspath,nonprodCompileClasspath,testCompileClasspath
org.checkerframework:checker-compat-qual:2.5.5=annotationProcessor,testAnnotationProcessor
org.checkerframework:checker-compat-qual:2.5.6=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
@@ -397,17 +391,19 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13=compileClasspath,deploy_jar,nonpr
org.codehaus.mojo:animal-sniffer-annotations:1.23=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.conscrypt:conscrypt-openjdk-uber:2.5.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.easymock:easymock:3.0=css
org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.7=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty.ee10:jetty-ee10-webapp:12.0.7=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-http:12.0.7=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-io:12.0.7=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-security:12.0.7=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-server:12.0.7=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-session:12.0.7=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-util:12.0.7=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-xml:12.0.7=testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-core:10.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-database-postgresql:10.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.eclipse.collections:eclipse-collections-api:11.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.eclipse.collections:eclipse-collections:11.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty.ee10:jetty-ee10-webapp:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-http:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-io:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-security:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-server:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-session:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-util:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-xml:12.0.8=testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-core:10.11.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-database-postgresql:10.11.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.glassfish.jaxb:jaxb-runtime:2.3.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.glassfish.jaxb:txw2:2.3.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.gwtproject:gwt-user:2.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -428,6 +424,7 @@ org.javassist:javassist:3.28.0-GA=checkstyle
org.jboss.logging:jboss-logging:3.4.3.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:1.1.1.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jboss:jandex:2.4.2.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jcommander:jcommander:1.83=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-bom:1.4.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-reflect:1.6.10=annotationProcessor,testAnnotationProcessor
org.jetbrains.kotlin:kotlin-reflect:1.9.20=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
@@ -445,6 +442,7 @@ org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.0.1=deploy_jar,nonprodRun
org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.jetbrains:annotations:13.0=annotationProcessor,testAnnotationProcessor
org.jetbrains:annotations:17.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jline:jline:3.25.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.joda:joda-money:1.0.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.json:json:20160212=soy
org.json:json:20231013=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -482,7 +480,7 @@ org.ow2.asm:asm:7.0=soy
org.ow2.asm:asm:9.2=compileClasspath,nonprodCompileClasspath
org.ow2.asm:asm:9.6=deploy_jar,jacocoAnt,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.pcollections:pcollections:3.1.4=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
org.postgresql:postgresql:42.7.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.postgresql:postgresql:42.7.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.reflections:reflections:0.10.2=checkstyle
org.rnorth.duct-tape:duct-tape:1.0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-api:3.141.59=testCompileClasspath,testRuntimeClasspath
@@ -497,13 +495,10 @@ org.seleniumhq.selenium:selenium-safari-driver:3.141.59=testCompileClasspath,tes
org.seleniumhq.selenium:selenium-support:3.141.59=testCompileClasspath,testRuntimeClasspath
org.slf4j:jcl-over-slf4j:1.7.32=testCompileClasspath,testRuntimeClasspath
org.slf4j:jul-to-slf4j:1.7.30=testRuntimeClasspath
org.slf4j:slf4j-api:2.0.12=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,testCompileClasspath
org.slf4j:slf4j-api:2.0.13=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,testCompileClasspath
org.slf4j:slf4j-api:2.1.0-alpha1=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.slf4j:slf4j-jdk14:2.1.0-alpha1=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.springframework:spring-core:5.3.27=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.springframework:spring-expression:5.3.27=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.springframework:spring-jcl:5.3.27=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:database-commons:1.19.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:jdbc:1.19.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:junit-jupiter:1.19.7=testCompileClasspath,testRuntimeClasspath

View File

@@ -14,7 +14,6 @@
package google.registry.beam.billing;
import com.google.auto.value.AutoValue;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import google.registry.reporting.billing.BillingModule;
@@ -29,13 +28,44 @@ import org.apache.beam.sdk.coders.NullableCoder;
import org.apache.beam.sdk.coders.StringUtf8Coder;
import org.apache.beam.sdk.coders.VarIntCoder;
import org.apache.beam.sdk.coders.VarLongCoder;
import org.jetbrains.annotations.NotNull;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
/** A POJO representing a single billable event, parsed from a {@code SchemaAndRecord}. */
@AutoValue
public abstract class BillingEvent {
/**
* A record representing a single billable event, parsed from a {@code SchemaAndRecord}.
*
* @param id The unique ID for the {@code BillingEvent} associated with this event.
* @param billingTime The DateTime (in UTC) this event becomes billable.
* @param eventTime The DateTime (in UTC) this event was generated.
* @param registrarId The billed registrar's name.
* @param billingId The billed registrar's billing account key.
* @param poNumber The Purchase Order number.
* @param tld The TLD this event was generated for.
* @param action The billable action this event was generated for (CREATE, RENEW, TRANSFER...).
* @param domain The fully qualified domain name this event was generated for.
* @param repositoryId The unique RepoID associated with the billed domain.
* @param years The number of years this billing event is made out for.
* @param currency The 3-letter currency code for the billing event (USD or JPY).
* @param amount The total cost associated with this billing event.
* @param flags A list of space-delimited flags associated with the event.
*/
public record BillingEvent(
long id,
DateTime billingTime,
DateTime eventTime,
String registrarId,
String billingId,
String poNumber,
String tld,
String action,
String domain,
String repositoryId,
int years,
String currency,
double amount,
String flags) {
private static final DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss zzz");
@@ -59,48 +89,6 @@ public abstract class BillingEvent {
"amount",
"flags");
/** Returns the unique ID for the {@code BillingEvent} associated with this event. */
abstract long id();
/** Returns the UTC DateTime this event becomes billable. */
abstract DateTime billingTime();
/** Returns the UTC DateTime this event was generated. */
abstract DateTime eventTime();
/** Returns the billed registrar's name. */
abstract String registrarId();
/** Returns the billed registrar's billing account key. */
abstract String billingId();
/** Returns the Purchase Order number. */
abstract String poNumber();
/** Returns the tld this event was generated for. */
abstract String tld();
/** Returns the billable action this event was generated for (i.e., RENEW, CREATE, TRANSFER...) */
abstract String action();
/** Returns the fully qualified domain name this event was generated for. */
abstract String domain();
/** Returns the unique RepoID associated with the billed domain. */
abstract String repositoryId();
/** Returns the number of years this billing event is made out for. */
abstract int years();
/** Returns the 3-letter currency code for the billing event (i.e., USD or JPY.) */
abstract String currency();
/** Returns the cost associated with this billing event. */
abstract double amount();
/** Returns a list of space-delimited flags associated with the event. */
abstract String flags();
/** Creates a concrete {@link BillingEvent}. */
static BillingEvent create(
long id,
@@ -117,7 +105,7 @@ public abstract class BillingEvent {
String currency,
double amount,
String flags) {
return new AutoValue_BillingEvent(
return new BillingEvent(
id,
billingTime,
eventTime,
@@ -173,7 +161,7 @@ public abstract class BillingEvent {
/** Returns the grouping key for this {@code BillingEvent}, to generate the overall invoice. */
InvoiceGroupingKey getInvoiceGroupingKey() {
return new AutoValue_BillingEvent_InvoiceGroupingKey(
return new InvoiceGroupingKey(
billingTime().toLocalDate().withDayOfMonth(1).toString(),
years() == 0
? ""
@@ -196,9 +184,28 @@ public abstract class BillingEvent {
return String.format("%s_%s", registrarId(), tld());
}
/** Key for each {@code BillingEvent}, when aggregating for the overall invoice. */
@AutoValue
abstract static class InvoiceGroupingKey {
/**
* Key for each {@code BillingEvent}, when aggregating for the overall invoice.
*
* @param startDate The first day this invoice is valid, in yyyy-MM-dd format.
* @param endDate The last day this invoice is valid, in yyyy-MM-dd format.
* @param productAccountKey The billing account id, which is the {@code BillingEvent.billingId}.
* @param usageGroupingKey The invoice grouping key, which is the registrar ID.
* @param description The description of the item, formatted as: {@code action | TLD: tld | TERM:
* n-year}.
* @param unitPrice The cost per invoice item.
* @param unitPriceCurrency The 3-digit currency code the unit price uses.
* @param poNumber The purchase order number for the item, blank for most registrars.
*/
record InvoiceGroupingKey(
String startDate,
String endDate,
String productAccountKey,
String usageGroupingKey,
String description,
Double unitPrice,
String unitPriceCurrency,
String poNumber) {
private static final ImmutableList<String> INVOICE_HEADERS =
ImmutableList.of(
@@ -217,29 +224,6 @@ public abstract class BillingEvent {
"UnitPriceCurrency",
"PONumber");
/** Returns the first day this invoice is valid, in yyyy-MM-dd format. */
abstract String startDate();
/** Returns the last day this invoice is valid, in yyyy-MM-dd format. */
abstract String endDate();
/** Returns the billing account id, which is the {@code BillingEvent.billingId}. */
abstract String productAccountKey();
/** Returns the invoice grouping key, which is the registrar ID. */
abstract String usageGroupingKey();
/** Returns a description of the item, formatted as "action | TLD: tld | TERM: n-year." */
abstract String description();
/** Returns the cost per invoice item. */
abstract Double unitPrice();
/** Returns the 3-digit currency code the unit price uses. */
abstract String unitPriceCurrency();
/** Returns the purchase order number for the item, blank for most registrars. */
abstract String poNumber();
/** Generates the CSV header for the overall invoice. */
static String invoiceHeader() {
@@ -280,7 +264,8 @@ public abstract class BillingEvent {
private InvoiceGroupingKeyCoder() {}
@Override
public void encode(InvoiceGroupingKey value, OutputStream outStream) throws IOException {
public void encode(InvoiceGroupingKey value, @NotNull OutputStream outStream)
throws IOException {
Coder<String> stringCoder = StringUtf8Coder.of();
stringCoder.encode(value.startDate(), outStream);
stringCoder.encode(value.endDate(), outStream);
@@ -293,8 +278,8 @@ public abstract class BillingEvent {
}
@Override
public InvoiceGroupingKey decode(InputStream inStream) throws IOException {
return new AutoValue_BillingEvent_InvoiceGroupingKey(
public InvoiceGroupingKey decode(@NotNull InputStream inStream) throws IOException {
return new InvoiceGroupingKey(
stringCoder.decode(inStream),
stringCoder.decode(inStream),
stringCoder.decode(inStream),
@@ -340,7 +325,7 @@ public abstract class BillingEvent {
@Override
public BillingEvent decode(InputStream inStream) throws IOException {
return new AutoValue_BillingEvent(
return new BillingEvent(
longCoder.decode(inStream),
DATE_TIME_FORMATTER.parseDateTime(stringCoder.decode(inStream)),
DATE_TIME_FORMATTER.parseDateTime(stringCoder.decode(inStream)),

View File

@@ -14,30 +14,23 @@
package google.registry.beam.spec11;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import java.io.Serializable;
/**
* A POJO representing a domain name and associated info, parsed from a {@code SchemaAndRecord}.
* A record representing a domain name and associated info, parsed from a {@code SchemaAndRecord}.
*
* <p>This is a trivially serializable class that allows Beam to transform the results of a SQL
* query into a standard Java representation.
*
* @param domainName The fully qualified domain name.
* @param domainRepoId The domain repo ID (the primary key of the domain table).
* @param registrarId The registrar ID of the associated registrar for this domain.
* @param registrarEmailAddress The email address of the registrar associated with this domain.
*/
@AutoValue
public abstract class DomainNameInfo implements Serializable {
/** Returns the fully qualified domain name. */
abstract String domainName();
/** Returns the domain repo ID (the primary key of the domain table). */
abstract String domainRepoId();
/** Returns the registrar ID of the associated registrar for this domain. */
abstract String registrarId();
/** Returns the email address of the registrar associated with this domain. */
abstract String registrarEmailAddress();
public record DomainNameInfo(
String domainName, String domainRepoId, String registrarId, String registrarEmailAddress)
implements Serializable {
/**
* Creates a concrete {@link DomainNameInfo}.
@@ -45,7 +38,6 @@ public abstract class DomainNameInfo implements Serializable {
@VisibleForTesting
static DomainNameInfo create(
String domainName, String domainRepoId, String registrarId, String registrarEmailAddress) {
return new AutoValue_DomainNameInfo(
domainName, domainRepoId, registrarId, registrarEmailAddress);
return new DomainNameInfo(domainName, domainRepoId, registrarId, registrarEmailAddress);
}
}

View File

@@ -14,28 +14,26 @@
package google.registry.beam.spec11;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import java.io.Serializable;
import org.json.JSONException;
import org.json.JSONObject;
/** A POJO representing a threat match response from the {@code SafeBrowsing API}. */
@AutoValue
public abstract class ThreatMatch implements Serializable {
/**
* A record representing a threat match response from the {@code SafeBrowsing API}.
*
* @param threatType What kind of threat this is (malware, phishing, etc.).
* @param domainName The fully qualified domain name of the matched threat.
*/
public record ThreatMatch(String threatType, String domainName) implements Serializable {
private static final String THREAT_TYPE_FIELD = "threatType";
private static final String DOMAIN_NAME_FIELD = "domainName";
private static final String OUTDATED_NAME_FIELD = "fullyQualifiedDomainName";
/** Returns what kind of threat it is (malware, phishing etc.) */
public abstract String threatType();
/** Returns the fully qualified domain name [SLD].[TLD] of the matched threat. */
public abstract String domainName();
@VisibleForTesting
static ThreatMatch create(String threatType, String domainName) {
return new AutoValue_ThreatMatch(threatType, domainName);
return new ThreatMatch(threatType, domainName);
}
/** Returns a {@link JSONObject} representing a subset of this object's data. */
@@ -49,7 +47,7 @@ public abstract class ThreatMatch implements Serializable {
public static ThreatMatch fromJSON(JSONObject threatMatch) throws JSONException {
// TODO: delete OUTDATED_NAME_FIELD once we no longer process reports saved with
// fullyQualifiedDomainName in them, likely 2023
return new AutoValue_ThreatMatch(
return new ThreatMatch(
threatMatch.getString(THREAT_TYPE_FIELD),
threatMatch.has(OUTDATED_NAME_FIELD)
? threatMatch.getString(OUTDATED_NAME_FIELD)

View File

@@ -21,7 +21,6 @@ import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Multimaps.newListMultimap;
import static com.google.common.collect.Multimaps.toMultimap;
import com.google.auto.value.AutoValue;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
@@ -192,8 +191,8 @@ class BsaDiffCreator {
newAndRemaining.values().stream()
.filter(value -> !Objects.equals(ORDER_ID_SENTINEL, value))
.distinct()
.map(id -> BlockOrder.of(id, OrderType.CREATE)),
deleted.values().stream().distinct().map(id -> BlockOrder.of(id, OrderType.DELETE)));
.map(id -> BlockOrder.create(id, OrderType.CREATE)),
deleted.values().stream().distinct().map(id -> BlockOrder.create(id, OrderType.DELETE)));
}
Stream<BlockLabel> getLabels() {
@@ -203,7 +202,7 @@ class BsaDiffCreator {
.filter(entry -> entry.getValue().contains(ORDER_ID_SENTINEL))
.map(
entry ->
BlockLabel.of(
BlockLabel.create(
entry.getKey(),
LabelType.NEW_ORDER_ASSOCIATION,
getAllValidIdnNames(entry.getKey()))),
@@ -212,12 +211,14 @@ class BsaDiffCreator {
.filter(entry -> !entry.getValue().contains(ORDER_ID_SENTINEL))
.map(
entry ->
BlockLabel.of(
BlockLabel.create(
entry.getKey(),
LabelType.CREATE,
getAllValidIdnNames(entry.getKey()))),
Sets.difference(deleted.keySet(), newAndRemaining.keySet()).stream()
.map(label -> BlockLabel.of(label, LabelType.DELETE, getAllValidIdnNames(label))))
.map(
label ->
BlockLabel.create(label, LabelType.DELETE, getAllValidIdnNames(label))))
.flatMap(x -> x);
}
@@ -241,29 +242,21 @@ class BsaDiffCreator {
}
}
@AutoValue
abstract static class LabelOrderPair {
abstract String label();
abstract Long orderId();
record LabelOrderPair(String label, Long orderId) {
static LabelOrderPair of(String key, Long value) {
return new AutoValue_BsaDiffCreator_LabelOrderPair(key, value);
return new LabelOrderPair(key, value);
}
}
@AutoValue
abstract static class Line {
abstract String label();
abstract ImmutableList<Long> orderIds();
record Line(String label, ImmutableList<Long> orderIds) {
Stream<LabelOrderPair> labelOrderPairs(Canonicals<Long> canonicals) {
return orderIds().stream().map(id -> LabelOrderPair.of(label(), canonicals.get(id)));
}
static Line of(String label, ImmutableList<Long> orderIds) {
return new AutoValue_BsaDiffCreator_Line(label, orderIds);
return new Line(label, orderIds);
}
}
}

View File

@@ -22,6 +22,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.bsa.BsaTransactions.bsaQuery;
import static google.registry.bsa.ReservedDomainsUtils.getAllReservedNames;
import static google.registry.bsa.ReservedDomainsUtils.isReservedDomain;
import static google.registry.bsa.persistence.BsaLabelUtils.isLabelBlocked;
import static google.registry.bsa.persistence.Queries.batchReadBsaLabelText;
import static google.registry.bsa.persistence.Queries.queryMissedRegisteredUnblockables;
import static google.registry.bsa.persistence.Queries.queryUnblockableDomainByLabels;
@@ -81,7 +82,6 @@ public class BsaValidateAction implements Runnable {
private final int transactionBatchSize;
private final Duration maxStaleness;
private final Clock clock;
private final BsaLock bsaLock;
private final Response response;
@Inject
@@ -92,7 +92,6 @@ public class BsaValidateAction implements Runnable {
@Config("bsaTxnBatchSize") int transactionBatchSize,
@Config("bsaValidationMaxStaleness") Duration maxStaleness,
Clock clock,
BsaLock bsaLock,
Response response) {
this.gcsClient = gcsClient;
this.idnChecker = idnChecker;
@@ -100,18 +99,13 @@ public class BsaValidateAction implements Runnable {
this.transactionBatchSize = transactionBatchSize;
this.maxStaleness = maxStaleness;
this.clock = clock;
this.bsaLock = bsaLock;
this.response = response;
}
@Override
public void run() {
try {
if (!bsaLock.executeWithLock(this::runWithinLock)) {
String message = "BSA validation did not run: another BSA related task is running";
logger.atInfo().log("%s.", message);
emailSender.sendNotification(message, /* body= */ "");
}
validate();
} catch (Throwable throwable) {
logger.atWarning().withCause(throwable).log("Failed to validate block lists.");
emailSender.sendNotification("BSA validation aborted", getStackTraceAsString(throwable));
@@ -121,15 +115,15 @@ public class BsaValidateAction implements Runnable {
response.setStatus(SC_OK);
}
/** Executes the validation action while holding the BSA lock. */
Void runWithinLock() {
/** Performs validation of BSA data in the database. */
void validate() {
Optional<String> downloadJobName =
bsaQuery(DownloadScheduler::fetchMostRecentDownloadJobIdIfCompleted);
if (downloadJobName.isEmpty()) {
logger.atInfo().log("Cannot validate: block list downloads not found.");
emailSender.sendNotification(
"BSA validation does not run: block list downloads not found", "");
return null;
return;
}
logger.atInfo().log("Validating BSA with latest download: %s", downloadJobName.get());
@@ -148,7 +142,6 @@ public class BsaValidateAction implements Runnable {
emailValidationResults(resultSummary, downloadJobName.get(), errors);
}
logger.atInfo().log("%s (latest download: %s)", resultSummary, downloadJobName.get());
return null;
}
void emailValidationResults(String subject, String jobName, ImmutableList<String> results) {
@@ -307,7 +300,9 @@ public class BsaValidateAction implements Runnable {
ImmutableList<String> checkForMissingReservedUnblockables(DateTime now) {
ImmutableList.Builder<String> errors = new ImmutableList.Builder<>();
try (Stream<ImmutableList<String>> reservedNames =
toBatches(getAllReservedNames(now), transactionBatchSize)) {
toBatches(
getAllReservedNames(now).filter(BsaValidateAction::isBlockedByBsa),
transactionBatchSize)) {
reservedNames
.map(this::checkOneBatchReservedDomainsForMissingUnblockables)
.forEach(errors::addAll);
@@ -346,6 +341,11 @@ public class BsaValidateAction implements Runnable {
return errors.build();
}
static boolean isBlockedByBsa(String domainInBsaEnrolledTld) {
InternetDomainName domainName = InternetDomainName.from(domainInBsaEnrolledTld);
return isLabelBlocked(domainName.parts().get(0));
}
static String parseBlockListLine(String line) {
int firstComma = line.indexOf(',');
checkArgument(firstComma > 0, "Invalid block list line: %s", line);

View File

@@ -14,7 +14,6 @@
package google.registry.bsa.api;
import com.google.auto.value.AutoValue;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
@@ -24,18 +23,11 @@ import java.util.List;
* A BSA label to block. New domains with matching second-level domain (SLD) will be denied
* registration in TLDs enrolled with BSA.
*/
@AutoValue
public abstract class BlockLabel {
public record BlockLabel(String label, LabelType labelType, ImmutableSet<String> idnTables) {
static final Joiner JOINER = Joiner.on(',');
static final Splitter SPLITTER = Splitter.on(',').trimResults();
public abstract String label();
public abstract LabelType labelType();
public abstract ImmutableSet<String> idnTables();
public String serialize() {
return JOINER.join(label(), labelType().name(), idnTables().stream().sorted().toArray());
}
@@ -43,7 +35,7 @@ public abstract class BlockLabel {
public static BlockLabel deserialize(String text) {
List<String> items = SPLITTER.splitToList(text);
try {
return of(
return create(
items.get(0),
LabelType.valueOf(items.get(1)),
ImmutableSet.copyOf(items.subList(2, items.size())));
@@ -52,8 +44,8 @@ public abstract class BlockLabel {
}
}
public static BlockLabel of(String label, LabelType type, ImmutableSet<String> idnTables) {
return new AutoValue_BlockLabel(label, type, idnTables);
public static BlockLabel create(String label, LabelType type, ImmutableSet<String> idnTables) {
return new BlockLabel(label, type, idnTables);
}
public enum LabelType {

View File

@@ -14,7 +14,6 @@
package google.registry.bsa.api;
import com.google.auto.value.AutoValue;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import java.util.List;
@@ -23,12 +22,7 @@ import java.util.List;
* A BSA order, which are needed when communicating with the BSA API while processing downloaded
* block lists.
*/
@AutoValue
public abstract class BlockOrder {
public abstract long orderId();
public abstract OrderType orderType();
public record BlockOrder(long orderId, OrderType orderType) {
static final Joiner JOINER = Joiner.on(',');
static final Splitter SPLITTER = Splitter.on(',');
@@ -40,14 +34,14 @@ public abstract class BlockOrder {
public static BlockOrder deserialize(String text) {
List<String> items = SPLITTER.splitToList(text);
try {
return of(Long.valueOf(items.get(0)), OrderType.valueOf(items.get(1)));
return create(Long.valueOf(items.get(0)), OrderType.valueOf(items.get(1)));
} catch (NumberFormatException ne) {
throw new IllegalArgumentException(text);
}
}
public static BlockOrder of(long orderId, OrderType orderType) {
return new AutoValue_BlockOrder(orderId, orderType);
public static BlockOrder create(long orderId, OrderType orderType) {
return new BlockOrder(orderId, orderType);
}
public enum OrderType {

View File

@@ -17,8 +17,6 @@ package google.registry.bsa.api;
import static com.google.common.base.Verify.verify;
import static google.registry.bsa.BsaStringUtils.PROPERTY_JOINER;
import com.google.auto.value.AutoValue;
import com.google.auto.value.extension.memoized.Memoized;
import google.registry.bsa.BsaStringUtils;
import google.registry.bsa.api.UnblockableDomain.Reason;
import java.util.List;
@@ -26,8 +24,7 @@ import java.util.Objects;
import java.util.Optional;
/** Change record of an {@link UnblockableDomain}. */
@AutoValue
public abstract class UnblockableDomainChange {
public record UnblockableDomainChange(UnblockableDomain unblockable, Optional<Reason> newReason) {
/**
* The text used in place of an empty {@link #newReason()} when an instance is serialized to
@@ -38,15 +35,10 @@ public abstract class UnblockableDomainChange {
*/
private static final String DELETE_REASON_PLACEHOLDER = "IS_DELETE";
abstract UnblockableDomain unblockable();
abstract Optional<Reason> newReason();
public String domainName() {
return unblockable().domainName();
}
@Memoized
public UnblockableDomain newValue() {
verify(newReason().isPresent(), "Removed unblockable does not have new value.");
return new UnblockableDomain(unblockable().domainName(), newReason().get());
@@ -77,27 +69,28 @@ public abstract class UnblockableDomainChange {
public static UnblockableDomainChange deserialize(String text) {
List<String> items = BsaStringUtils.PROPERTY_SPLITTER.splitToList(text);
return of(
return create(
new UnblockableDomain(items.get(0), Reason.valueOf(items.get(1))),
Objects.equals(items.get(2), DELETE_REASON_PLACEHOLDER)
? Optional.empty()
: Optional.of(Reason.valueOf(items.get(2))));
}
public static UnblockableDomainChange ofNew(UnblockableDomain unblockable) {
return of(unblockable, Optional.of(unblockable.reason()));
public static UnblockableDomainChange createNew(UnblockableDomain unblockable) {
return create(unblockable, Optional.of(unblockable.reason()));
}
public static UnblockableDomainChange ofDeleted(UnblockableDomain unblockable) {
return of(unblockable, Optional.empty());
public static UnblockableDomainChange createDeleted(UnblockableDomain unblockable) {
return create(unblockable, Optional.empty());
}
public static UnblockableDomainChange ofChanged(UnblockableDomain unblockable, Reason newReason) {
return of(unblockable, Optional.of(newReason));
public static UnblockableDomainChange createChanged(
UnblockableDomain unblockable, Reason newReason) {
return create(unblockable, Optional.of(newReason));
}
private static UnblockableDomainChange of(
private static UnblockableDomainChange create(
UnblockableDomain unblockable, Optional<Reason> newReason) {
return new AutoValue_UnblockableDomainChange(unblockable, newReason);
return new UnblockableDomainChange(unblockable, newReason);
}
}

View File

@@ -177,7 +177,7 @@ public final class DomainsRefresher {
BsaUnblockableDomain domain = nameToEntity.get(domainName);
UnblockableDomain unblockable =
UnblockableDomain.of(domain.label, domain.tld, Reason.valueOf(domain.reason.name()));
changes.add(UnblockableDomainChange.ofChanged(unblockable, Reason.REGISTERED));
changes.add(UnblockableDomainChange.createChanged(unblockable, Reason.REGISTERED));
}
// No longer registered: registered -> reserved/NONE
for (String domainName : noLongerRegistered) {
@@ -186,8 +186,8 @@ public final class DomainsRefresher {
UnblockableDomain.of(domain.label, domain.tld, Reason.valueOf(domain.reason.name()));
changes.add(
currReserved.contains(domainName)
? UnblockableDomainChange.ofChanged(unblockable, Reason.RESERVED)
: UnblockableDomainChange.ofDeleted(unblockable));
? UnblockableDomainChange.createChanged(unblockable, Reason.RESERVED)
: UnblockableDomainChange.createDeleted(unblockable));
}
// No longer reserved: reserved -> registered/None (the former duplicates with newly-registered)
for (String domainName : noLongerReserved) {
@@ -195,7 +195,7 @@ public final class DomainsRefresher {
UnblockableDomain unblockable =
UnblockableDomain.of(domain.label, domain.tld, Reason.valueOf(domain.reason.name()));
if (!currRegistered.contains(domainName)) {
changes.add(UnblockableDomainChange.ofDeleted(unblockable));
changes.add(UnblockableDomainChange.createDeleted(unblockable));
}
}
return changes.build();
@@ -230,7 +230,7 @@ public final class DomainsRefresher {
reservedNotCreated.remove(domainName);
if (newCreated.remove(domainName)) {
changes.add(
UnblockableDomainChange.ofChanged(
UnblockableDomainChange.createChanged(
unblockable.toUnblockableDomain(), Reason.REGISTERED));
}
}
@@ -240,10 +240,10 @@ public final class DomainsRefresher {
Streams.concat(
newCreated.stream()
.map(name -> new UnblockableDomain(name, Reason.REGISTERED))
.map(UnblockableDomainChange::ofNew),
.map(UnblockableDomainChange::createNew),
reservedNotCreated.stream()
.map(name -> new UnblockableDomain(name, Reason.RESERVED))
.map(UnblockableDomainChange::ofNew))
.map(UnblockableDomainChange::createNew))
.forEach(changes::add);
return changes.build();
}

View File

@@ -21,33 +21,26 @@ import static google.registry.bsa.DownloadStage.MAKE_ORDER_AND_LABEL_DIFF;
import static google.registry.bsa.DownloadStage.NOP;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableMap;
import google.registry.bsa.BlockListType;
import google.registry.bsa.DownloadStage;
import java.util.Optional;
import org.joda.time.DateTime;
/** Information needed when handling a download from BSA. */
@AutoValue
public abstract class DownloadSchedule {
abstract long jobId();
abstract DateTime jobCreationTime();
public abstract String jobName();
public abstract DownloadStage stage();
/** The most recent job that ended in the {@code DONE} stage. */
public abstract Optional<CompletedJob> latestCompleted();
/**
* Returns true if download should be processed even if the checksums show that it has not changed
* from the previous one.
*/
public abstract boolean alwaysDownload();
/**
* Information needed when handling a download from BSA.
*
* @param latestCompleted The most recent job that ended in the {@code DONE} stage.
* @param alwaysDownload Whether the download should be processed even if the checksums show that it
* has not changed from the previous one.
*/
public record DownloadSchedule(
long jobId,
DateTime jobCreationTime,
String jobName,
DownloadStage stage,
Optional<CompletedJob> latestCompleted,
boolean alwaysDownload) {
/** Updates the current job to the new stage. */
public void updateJobStage(DownloadStage stage) {
@@ -88,12 +81,12 @@ public abstract class DownloadSchedule {
bsaDownload.setStage(stage);
bsaDownload.setChecksums(checksums);
tm().put(bsaDownload);
return of(bsaDownload);
return create(bsaDownload);
});
}
static DownloadSchedule of(BsaDownload currentJob) {
return new AutoValue_DownloadSchedule(
static DownloadSchedule create(BsaDownload currentJob) {
return new DownloadSchedule(
currentJob.getJobId(),
currentJob.getCreationTime(),
currentJob.getJobName(),
@@ -102,9 +95,9 @@ public abstract class DownloadSchedule {
/* alwaysDownload= */ true);
}
static DownloadSchedule of(
static DownloadSchedule create(
BsaDownload currentJob, CompletedJob latestCompleted, boolean alwaysDownload) {
return new AutoValue_DownloadSchedule(
return new DownloadSchedule(
currentJob.getJobId(),
currentJob.getCreationTime(),
currentJob.getJobName(),
@@ -114,15 +107,10 @@ public abstract class DownloadSchedule {
}
/** Information about a completed BSA download job. */
@AutoValue
public abstract static class CompletedJob {
public abstract String jobName();
public record CompletedJob(String jobName, ImmutableMap<BlockListType, String> checksums) {
public abstract ImmutableMap<BlockListType, String> checksums();
static CompletedJob of(BsaDownload completedJob) {
return new AutoValue_DownloadSchedule_CompletedJob(
completedJob.getJobName(), completedJob.getChecksums());
public static CompletedJob create(BsaDownload completedJob) {
return new CompletedJob(completedJob.getJobName(), completedJob.getChecksums());
}
}
}

View File

@@ -100,15 +100,15 @@ public final class DownloadScheduler {
: Optional.empty();
} else if (recentDownloads.size() == 1) {
// First job ever, still in progress
return Optional.of(DownloadSchedule.of(recentDownloads.get(0)));
return Optional.of(DownloadSchedule.create(recentDownloads.get(0)));
} else {
// Job in progress, with completed previous jobs.
BsaDownload prev = recentDownloads.get(1);
verify(prev.getStage().equals(DONE), "Unexpectedly found two ongoing jobs.");
return Optional.of(
DownloadSchedule.of(
DownloadSchedule.create(
mostRecent,
CompletedJob.of(prev),
CompletedJob.create(prev),
isTimeAgain(mostRecent, maxNopInterval)));
}
});
@@ -127,8 +127,9 @@ public final class DownloadScheduler {
return prevJob
.map(
prev ->
DownloadSchedule.of(job, CompletedJob.of(prev), isTimeAgain(prev, maxNopInterval)))
.orElseGet(() -> DownloadSchedule.of(job));
DownloadSchedule.create(
job, CompletedJob.create(prev), isTimeAgain(prev, maxNopInterval)))
.orElseGet(() -> DownloadSchedule.create(job));
}
/**

View File

@@ -17,25 +17,21 @@ package google.registry.bsa.persistence;
import static com.google.common.base.Verify.verify;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.auto.value.AutoValue;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import google.registry.bsa.RefreshStage;
import org.joda.time.DateTime;
/** Information needed when handling a domain refresh. */
@AutoValue
public abstract class RefreshSchedule {
abstract long jobId();
abstract DateTime jobCreationTime();
public abstract String jobName();
public abstract RefreshStage stage();
/** The most recent job that ended in the {@code DONE} stage. */
public abstract DateTime prevRefreshTime();
/**
* Information needed when handling a domain refresh.
*
* @param prevRefreshTime The most recent job that ended in the {@code DONE} stage.
*/
public record RefreshSchedule(
long jobId,
DateTime jobCreationTime,
String jobName,
RefreshStage stage,
DateTime prevRefreshTime) {
/** Updates the current job to the new stage. */
@CanIgnoreReturnValue
@@ -50,12 +46,12 @@ public abstract class RefreshSchedule {
stage);
bsaRefresh.setStage(stage);
tm().put(bsaRefresh);
return of(bsaRefresh, prevRefreshTime());
return create(bsaRefresh, prevRefreshTime());
});
}
static RefreshSchedule of(BsaDomainRefresh job, DateTime prevJobCreationTime) {
return new AutoValue_RefreshSchedule(
static RefreshSchedule create(BsaDomainRefresh job, DateTime prevJobCreationTime) {
return new RefreshSchedule(
job.getJobId(),
job.getCreationTime(),
job.getJobName(),

View File

@@ -68,11 +68,11 @@ public class RefreshScheduler {
RefreshSchedule scheduleNewJob(DateTime prevRefreshTime) {
BsaDomainRefresh newJob = new BsaDomainRefresh();
tm().insert(newJob);
return RefreshSchedule.of(newJob, prevRefreshTime);
return RefreshSchedule.create(newJob, prevRefreshTime);
}
RefreshSchedule rescheduleOngoingJob(BsaDomainRefresh ongoingJob, DateTime prevJobStartTime) {
return RefreshSchedule.of(ongoingJob, prevJobStartTime);
return RefreshSchedule.create(ongoingJob, prevJobStartTime);
}
@VisibleForTesting

View File

@@ -203,6 +203,17 @@ public final class RegistryConfig {
return config.registrarConsole.announcementsEmailAddress;
}
/**
* The DUM file name, used as a file name base for DUM csv file
*
* @see google.registry.ui.server.console.ConsoleDumDownloadAction
*/
@Provides
@Config("dumFileName")
public static String provideDumFileName(RegistryConfigSettings config) {
return config.registrarConsole.dumFileName;
}
/**
* The contact phone number. Used in the "contact-us" section of the registrar console.
*

View File

@@ -185,6 +185,7 @@ public class RegistryConfigSettings {
/** Configuration for the web-based registrar console. */
public static class RegistrarConsole {
public String dumFileName;
public String logoFilename;
public String supportPhoneNumber;
public String supportEmailAddress;

View File

@@ -396,6 +396,9 @@ rde:
sshIdentityEmailAddress: rde@example.com
registrarConsole:
# DUM download file name, excluding the extension
dumFileName: dum_file_name
# Filename of the logo to use in the header of the console. This filename is
# relative to ui/assets/images/
logoFilename: logo.png

View File

@@ -7,8 +7,8 @@
<sessions-enabled>true</sessions-enabled>
<instance-class>B4_1G</instance-class>
<basic-scaling>
<max-instances>100</max-instances>
<idle-timeout>10m</idle-timeout>
<max-instances>3</max-instances>
<idle-timeout>60m</idle-timeout>
</basic-scaling>
<system-properties>

View File

@@ -178,9 +178,9 @@
<url><![CDATA[/_dr/cron/fanout?queue=retryable-cron-tasks&endpoint=/_dr/task/deleteProberData&runInEmpty]]></url>
<name>deleteProberData</name>
<description>
This job clears out data from probers and runs once a week.
This job clears out data from probers and runs daily.
</description>
<schedule>0 14 * * 1</schedule>
<schedule>0 14 * * *</schedule>
</task>
<task>

View File

@@ -7,8 +7,8 @@
<sessions-enabled>true</sessions-enabled>
<instance-class>B4</instance-class>
<basic-scaling>
<max-instances>100</max-instances>
<idle-timeout>10m</idle-timeout>
<max-instances>3</max-instances>
<idle-timeout>60m</idle-timeout>
</basic-scaling>
<system-properties>

View File

@@ -120,9 +120,9 @@
<url><![CDATA[/_dr/cron/fanout?queue=retryable-cron-tasks&endpoint=/_dr/task/deleteProberData&runInEmpty]]></url>
<name>deleteProberData</name>
<description>
This job clears out data from probers and runs once a week.
This job clears out data from probers and runs daily.
</description>
<schedule>0 14 * * 1</schedule>
<schedule>0 14 * * *</schedule>
</task>
<task>

View File

@@ -38,6 +38,8 @@ class SheetSynchronizer {
private static final String SHEET_NAME = "Registrars";
private static final String INVALID_HEADER_TEXT = "Invalid Sheet column header name";
@Inject Sheets sheetsService;
@Inject SheetSynchronizer() {}
@@ -92,10 +94,12 @@ class SheetSynchronizer {
cellRow.add("");
}
for (int j = 0; j < headers.size(); j++) {
// Look for the value corresponding to the row and header indices in data
String dataField = data.get(i).get(headers.get(j));
// If the cell's header matches a data header, and the values aren't equal, mutate it
if (dataField != null && !cellRow.get(j).toString().equals(dataField)) {
// Look for the value corresponding to the row and header indices in data, otherwise write
// out an error so it's clear to a reader of the Google Sheet that the column header is
// invalid.
String dataField = data.get(i).getOrDefault(headers.get(j), INVALID_HEADER_TEXT);
// If the existing cell value is different than the new data, mutate it.
if (!cellRow.get(j).toString().equals(dataField)) {
mutated = true;
originalVals.get(i).set(j, dataField);
}

View File

@@ -14,7 +14,7 @@
package google.registry.flows.custom;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.InternetDomainName;
@@ -22,7 +22,6 @@ import google.registry.flows.EppException;
import google.registry.flows.FlowMetadata;
import google.registry.flows.SessionMetadata;
import google.registry.flows.domain.DomainCheckFlow;
import google.registry.model.ImmutableObject;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.CheckData.DomainCheck;
import google.registry.model.eppoutput.EppResponse.ResponseExtension;
@@ -67,91 +66,83 @@ public class DomainCheckFlowCustomLogic extends BaseFlowCustomLogic {
.build();
}
/** A class to encapsulate parameters for a call to {@link #afterValidation}. */
@AutoValue
public abstract static class AfterValidationParameters extends ImmutableObject {
public abstract ImmutableMap<String, InternetDomainName> domainNames();
/**
* The time to perform the domain check as of. This defaults to the current time, but can be
* overridden in v&gt;=0.12 of the fee extension.
*/
public abstract DateTime asOfDate();
/**
* A record to encapsulate parameters for a call to {@link #afterValidation}.
*
* @param domainNames A map of the domain names being checked, from domain name as string to
* parsed value.
* @param asOfDate The time to perform the domain check as of. This defaults to the current time,
* but can be overridden in v&gt;=0.12 of the fee extension.
*/
public record AfterValidationParameters(
ImmutableMap<String, InternetDomainName> domainNames, DateTime asOfDate) {
public static Builder newBuilder() {
return new AutoValue_DomainCheckFlowCustomLogic_AfterValidationParameters.Builder();
return new AutoBuilder_DomainCheckFlowCustomLogic_AfterValidationParameters_Builder();
}
/** Builder for {@link AfterValidationParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setDomainNames(ImmutableMap<String, InternetDomainName> domainNames);
Builder setDomainNames(ImmutableMap<String, InternetDomainName> domainNames);
public abstract Builder setAsOfDate(DateTime asOfDate);
Builder setAsOfDate(DateTime asOfDate);
public abstract AfterValidationParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #beforeResponse}. */
@AutoValue
public abstract static class BeforeResponseParameters extends ImmutableObject {
public abstract ImmutableList<DomainCheck> domainChecks();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
/**
* The time to perform the domain check as of. This defaults to the current time, but can be
* overridden in v&gt;=0.12 of the fee extension.
*/
public abstract DateTime asOfDate();
public static Builder newBuilder() {
return new AutoValue_DomainCheckFlowCustomLogic_BeforeResponseParameters.Builder();
}
/** Builder for {@link BeforeResponseParameters}. */
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setDomainChecks(ImmutableList<DomainCheck> domainChecks);
public abstract Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract Builder setAsOfDate(DateTime asOfDate);
public abstract BeforeResponseParameters build();
AfterValidationParameters build();
}
}
/**
* A class to encapsulate parameters for the return values from a call to {@link #beforeResponse}.
* A record to encapsulate parameters for a call to {@link #beforeResponse}.
*
* @param asOfDate The time to perform the domain check as of. This defaults to the current time,
* but can be overridden in v&gt;=0.12 of the fee extension.
*/
@AutoValue
public abstract static class BeforeResponseReturnData extends ImmutableObject {
public abstract ImmutableList<DomainCheck> domainChecks();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
public record BeforeResponseParameters(
ImmutableList<DomainCheck> domainChecks,
ImmutableList<? extends ResponseExtension> responseExtensions,
DateTime asOfDate) {
public static Builder newBuilder() {
return new AutoValue_DomainCheckFlowCustomLogic_BeforeResponseReturnData.Builder();
return new AutoBuilder_DomainCheckFlowCustomLogic_BeforeResponseParameters_Builder();
}
/** Builder for {@link BeforeResponseParameters}. */
@AutoBuilder
public interface Builder {
Builder setDomainChecks(ImmutableList<DomainCheck> domainChecks);
Builder setResponseExtensions(ImmutableList<? extends ResponseExtension> responseExtensions);
Builder setAsOfDate(DateTime asOfDate);
BeforeResponseParameters build();
}
}
/**
* A record to encapsulate parameters for the return values from a call to {@link
* #beforeResponse}.
*/
public record BeforeResponseReturnData(
ImmutableList<DomainCheck> domainChecks,
ImmutableList<? extends ResponseExtension> responseExtensions) {
public static Builder newBuilder() {
return new AutoBuilder_DomainCheckFlowCustomLogic_BeforeResponseReturnData_Builder();
}
/** Builder for {@link BeforeResponseReturnData}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setDomainChecks(ImmutableList<DomainCheck> domainChecks);
Builder setDomainChecks(ImmutableList<DomainCheck> domainChecks);
public abstract Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
Builder setResponseExtensions(ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseReturnData build();
BeforeResponseReturnData build();
}
}
}

View File

@@ -14,14 +14,13 @@
package google.registry.flows.custom;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.net.InternetDomainName;
import google.registry.flows.EppException;
import google.registry.flows.FlowMetadata;
import google.registry.flows.SessionMetadata;
import google.registry.flows.domain.DomainCreateFlow;
import google.registry.model.ImmutableObject;
import google.registry.model.domain.Domain;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppResponse.ResponseData;
@@ -81,147 +80,114 @@ public class DomainCreateFlowCustomLogic extends BaseFlowCustomLogic {
.build();
}
/** A class to encapsulate parameters for a call to {@link #afterValidation}. */
@AutoValue
public abstract static class AfterValidationParameters extends ImmutableObject {
/** The parsed domain name of the domain that is requested to be created. */
public abstract InternetDomainName domainName();
/**
* The number of years that the domain name will be registered for.
*
* <p>On standard TLDs, this is usually 1.
*/
public abstract int years();
/**
* The ID of the validated signed mark.
*
* <p>If a signed mark was not supplied, this value will be absent.
*/
public abstract Optional<String> signedMarkId();
/**
* A record to encapsulate parameters for a call to {@link #afterValidation}.
*
* @param domainName The parsed domain name of the domain that is requested to be created.
* @param years The number of years that the domain name will be registered for (typically 1).
* @param signedMarkId The ID of the validated signed mark, or absent if not supplied.
*/
public record AfterValidationParameters(
InternetDomainName domainName, int years, Optional<String> signedMarkId) {
public static Builder newBuilder() {
return new AutoValue_DomainCreateFlowCustomLogic_AfterValidationParameters.Builder();
return new AutoBuilder_DomainCreateFlowCustomLogic_AfterValidationParameters_Builder();
}
/** Builder for {@link AfterValidationParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setDomainName(InternetDomainName domainName);
Builder setDomainName(InternetDomainName domainName);
public abstract Builder setYears(int years);
Builder setYears(int years);
public abstract Builder setSignedMarkId(Optional<String> signedMarkId);
Builder setSignedMarkId(Optional<String> signedMarkId);
public abstract AfterValidationParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #beforeSave}. */
@AutoValue
public abstract static class BeforeSaveParameters extends ImmutableObject {
/**
* The new {@link Domain} entity that is going to be persisted at the end of the transaction.
*/
public abstract Domain newDomain();
/**
* The new {@link HistoryEntry} entity for the domain's creation that is going to be persisted
* at the end of the transaction.
*/
public abstract HistoryEntry historyEntry();
/**
* The collection of {@link EntityChanges} (including new entities and those to delete) that
* will be persisted at the end of the transaction.
*
* <p>Note that the new domain and history entry are also included as saves in this collection,
* and are separated out above solely for convenience, as they are most likely to need to be
* changed. Removing them from the collection will cause them not to be saved, which is most
* likely not what you intended.
*/
public abstract EntityChanges entityChanges();
/**
* The number of years that the domain name will be registered for.
*
* <p>On standard TLDs, this is usually 1.
*/
public abstract int years();
public static Builder newBuilder() {
return new AutoValue_DomainCreateFlowCustomLogic_BeforeSaveParameters.Builder();
}
/** Builder for {@link BeforeSaveParameters}. */
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setNewDomain(Domain newDomain);
public abstract Builder setHistoryEntry(HistoryEntry historyEntry);
public abstract Builder setEntityChanges(EntityChanges entityChanges);
public abstract Builder setYears(int years);
public abstract BeforeSaveParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #beforeResponse}. */
@AutoValue
public abstract static class BeforeResponseParameters extends ImmutableObject {
public abstract ResponseData resData();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
public static BeforeResponseParameters.Builder newBuilder() {
return new AutoValue_DomainCreateFlowCustomLogic_BeforeResponseParameters.Builder();
}
/** Builder for {@link DomainCreateFlowCustomLogic.BeforeResponseParameters}. */
@AutoValue.Builder
public abstract static class Builder {
public abstract BeforeResponseParameters.Builder setResData(ResponseData resData);
public abstract BeforeResponseParameters.Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseParameters build();
AfterValidationParameters build();
}
}
/**
* A class to encapsulate parameters for the return values from a call to {@link #beforeResponse}.
* A record to encapsulate parameters for a call to {@link #beforeSave}.
*
* @param newDomain The new {@link Domain} entity that is going to be persisted at the end of the
* transaction.
* @param historyEntry The new {@link HistoryEntry} entity for the domain's creation that is going
* to be persisted at the end of the transaction.
* @param entityChanges The collection of {@link EntityChanges} (including new entities and those
* to delete) that will be persisted at the end of the transaction.
* <p>Note that the new domain and history entry are also included as saves in this
* collection, and are separated out above solely for convenience, as they are most likely to
* need to be changed. Removing them from the collection will cause them not to be saved,
* which is most likely not what you intended.
* @param years The number of years that the domain name will be registered for (typically 1).
*/
@AutoValue
public abstract static class BeforeResponseReturnData extends ImmutableObject {
public record BeforeSaveParameters(
Domain newDomain, HistoryEntry historyEntry, EntityChanges entityChanges, int years) {
public abstract ResponseData resData();
public static Builder newBuilder() {
return new AutoBuilder_DomainCreateFlowCustomLogic_BeforeSaveParameters_Builder();
}
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
/** Builder for {@link BeforeSaveParameters}. */
@AutoBuilder
public interface Builder {
Builder setNewDomain(Domain newDomain);
Builder setHistoryEntry(HistoryEntry historyEntry);
Builder setEntityChanges(EntityChanges entityChanges);
Builder setYears(int years);
BeforeSaveParameters build();
}
}
/** A record to encapsulate parameters for a call to {@link #beforeResponse}. */
public record BeforeResponseParameters(
ResponseData resData, ImmutableList<? extends ResponseExtension> responseExtensions) {
public static BeforeResponseParameters.Builder newBuilder() {
return new AutoBuilder_DomainCreateFlowCustomLogic_BeforeResponseParameters_Builder();
}
/** Builder for {@link DomainCreateFlowCustomLogic.BeforeResponseParameters}. */
@AutoBuilder
public interface Builder {
BeforeResponseParameters.Builder setResData(ResponseData resData);
BeforeResponseParameters.Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
BeforeResponseParameters build();
}
}
/**
* A record to encapsulate parameters for the return values from a call to {@link
* #beforeResponse}.
*/
public record BeforeResponseReturnData(
ResponseData resData, ImmutableList<? extends ResponseExtension> responseExtensions) {
public static BeforeResponseReturnData.Builder newBuilder() {
return new AutoValue_DomainCreateFlowCustomLogic_BeforeResponseReturnData.Builder();
return new AutoBuilder_DomainCreateFlowCustomLogic_BeforeResponseReturnData_Builder();
}
/** Builder for {@link DomainCreateFlowCustomLogic.BeforeResponseReturnData}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract BeforeResponseReturnData.Builder setResData(ResponseData resData);
BeforeResponseReturnData.Builder setResData(ResponseData resData);
public abstract BeforeResponseReturnData.Builder setResponseExtensions(
BeforeResponseReturnData.Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseReturnData build();
BeforeResponseReturnData build();
}
}
}

View File

@@ -14,13 +14,12 @@
package google.registry.flows.custom;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableList;
import google.registry.flows.EppException;
import google.registry.flows.FlowMetadata;
import google.registry.flows.SessionMetadata;
import google.registry.flows.domain.DomainDeleteFlow;
import google.registry.model.ImmutableObject;
import google.registry.model.domain.Domain;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppResponse.ResponseExtension;
@@ -79,112 +78,96 @@ public class DomainDeleteFlowCustomLogic extends BaseFlowCustomLogic {
.build();
}
/** A class to encapsulate parameters for a call to {@link #afterValidation}. */
@AutoValue
public abstract static class AfterValidationParameters extends ImmutableObject {
public abstract Domain existingDomain();
/** A record to encapsulate parameters for a call to {@link #afterValidation}. */
public record AfterValidationParameters(Domain existingDomain) {
public static Builder newBuilder() {
return new AutoValue_DomainDeleteFlowCustomLogic_AfterValidationParameters.Builder();
return new AutoBuilder_DomainDeleteFlowCustomLogic_AfterValidationParameters_Builder();
}
/** Builder for {@link AfterValidationParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setExistingDomain(Domain existingDomain);
Builder setExistingDomain(Domain existingDomain);
public abstract AfterValidationParameters build();
AfterValidationParameters build();
}
}
/**
* A class to encapsulate parameters for a call to {@link #beforeSave}.
* A record to encapsulate parameters for a call to {@link #beforeSave}.
*
* <p>Note that both newDomain and historyEntry are included in entityChanges. They are also
* passed separately for convenience, but they are the same instance, and changes to them will
* also affect what is persisted from entityChanges.
*/
@AutoValue
public abstract static class BeforeSaveParameters extends ImmutableObject {
public abstract Domain existingDomain();
public abstract Domain newDomain();
public abstract HistoryEntry historyEntry();
public abstract EntityChanges entityChanges();
public record BeforeSaveParameters(
Domain existingDomain,
Domain newDomain,
HistoryEntry historyEntry,
EntityChanges entityChanges) {
public static Builder newBuilder() {
return new AutoValue_DomainDeleteFlowCustomLogic_BeforeSaveParameters.Builder();
return new AutoBuilder_DomainDeleteFlowCustomLogic_BeforeSaveParameters_Builder();
}
/** Builder for {@link BeforeSaveParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setExistingDomain(Domain existingDomain);
Builder setExistingDomain(Domain existingDomain);
public abstract Builder setNewDomain(Domain newDomain);
Builder setNewDomain(Domain newDomain);
public abstract Builder setHistoryEntry(HistoryEntry historyEntry);
Builder setHistoryEntry(HistoryEntry historyEntry);
public abstract Builder setEntityChanges(EntityChanges entityChanges);
Builder setEntityChanges(EntityChanges entityChanges);
public abstract BeforeSaveParameters build();
BeforeSaveParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #beforeResponse}. */
@AutoValue
public abstract static class BeforeResponseParameters extends ImmutableObject {
public abstract Result.Code resultCode();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
/** A record to encapsulate parameters for a call to {@link #beforeResponse}. */
public record BeforeResponseParameters(
Result.Code resultCode, ImmutableList<? extends ResponseExtension> responseExtensions) {
public static Builder newBuilder() {
return new AutoValue_DomainDeleteFlowCustomLogic_BeforeResponseParameters.Builder();
return new AutoBuilder_DomainDeleteFlowCustomLogic_BeforeResponseParameters_Builder();
}
/** Builder for {@link BeforeResponseParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setResultCode(Result.Code resultCode);
Builder setResultCode(Result.Code resultCode);
public abstract Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
Builder setResponseExtensions(ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseParameters build();
BeforeResponseParameters build();
}
}
/**
* A class to encapsulate parameters for the return values from a call to {@link #beforeResponse}.
* A record to encapsulate parameters for the return values from a call to {@link
* #beforeResponse}.
*/
@AutoValue
public abstract static class BeforeResponseReturnData extends ImmutableObject {
public abstract Result.Code resultCode();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
public record BeforeResponseReturnData(
Result.Code resultCode, ImmutableList<? extends ResponseExtension> responseExtensions) {
public static Builder newBuilder() {
return new AutoValue_DomainDeleteFlowCustomLogic_BeforeResponseReturnData.Builder();
return new AutoBuilder_DomainDeleteFlowCustomLogic_BeforeResponseReturnData_Builder();
}
/** Builder for {@link BeforeResponseReturnData}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setResultCode(Result.Code resultCode);
Builder setResultCode(Result.Code resultCode);
public abstract Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
Builder setResponseExtensions(ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseReturnData build();
BeforeResponseReturnData build();
}
}
}

View File

@@ -14,13 +14,12 @@
package google.registry.flows.custom;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableList;
import google.registry.flows.EppException;
import google.registry.flows.FlowMetadata;
import google.registry.flows.SessionMetadata;
import google.registry.flows.domain.DomainInfoFlow;
import google.registry.model.ImmutableObject;
import google.registry.model.domain.Domain;
import google.registry.model.domain.DomainInfoData;
import google.registry.model.eppinput.EppInput;
@@ -65,79 +64,67 @@ public class DomainInfoFlowCustomLogic extends BaseFlowCustomLogic {
.build();
}
/** A class to encapsulate parameters for a call to {@link #afterValidation}. */
@AutoValue
public abstract static class AfterValidationParameters extends ImmutableObject {
public abstract Domain domain();
/** A record to encapsulate parameters for a call to {@link #afterValidation}. */
public record AfterValidationParameters(Domain domain) {
public static Builder newBuilder() {
return new AutoValue_DomainInfoFlowCustomLogic_AfterValidationParameters.Builder();
return new AutoBuilder_DomainInfoFlowCustomLogic_AfterValidationParameters_Builder();
}
/** Builder for {@link AfterValidationParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setDomain(Domain domain);
Builder setDomain(Domain domain);
public abstract AfterValidationParameters build();
AfterValidationParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #beforeResponse}. */
@AutoValue
public abstract static class BeforeResponseParameters extends ImmutableObject {
public abstract Domain domain();
public abstract DomainInfoData resData();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
/** A record to encapsulate parameters for a call to {@link #beforeResponse}. */
public record BeforeResponseParameters(
Domain domain,
DomainInfoData resData,
ImmutableList<? extends ResponseExtension> responseExtensions) {
public static Builder newBuilder() {
return new AutoValue_DomainInfoFlowCustomLogic_BeforeResponseParameters.Builder();
return new AutoBuilder_DomainInfoFlowCustomLogic_BeforeResponseParameters_Builder();
}
/** Builder for {@link BeforeResponseParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setDomain(Domain domain);
Builder setDomain(Domain domain);
public abstract Builder setResData(DomainInfoData resData);
Builder setResData(DomainInfoData resData);
public abstract Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
Builder setResponseExtensions(ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseParameters build();
BeforeResponseParameters build();
}
}
/**
* A class to encapsulate parameters for the return values from a call to {@link #beforeResponse}.
* A record to encapsulate parameters for the return values from a call to {@link
* #beforeResponse}.
*/
@AutoValue
public abstract static class BeforeResponseReturnData extends ImmutableObject {
public abstract DomainInfoData resData();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
public record BeforeResponseReturnData(
DomainInfoData resData, ImmutableList<? extends ResponseExtension> responseExtensions) {
public static Builder newBuilder() {
return new AutoValue_DomainInfoFlowCustomLogic_BeforeResponseReturnData.Builder();
return new AutoBuilder_DomainInfoFlowCustomLogic_BeforeResponseReturnData_Builder();
}
/** Builder for {@link BeforeResponseReturnData}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setResData(DomainInfoData resData);
Builder setResData(DomainInfoData resData);
public abstract Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
Builder setResponseExtensions(ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseReturnData build();
BeforeResponseReturnData build();
}
}
}

View File

@@ -14,14 +14,13 @@
package google.registry.flows.custom;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import com.google.common.net.InternetDomainName;
import google.registry.flows.EppException;
import google.registry.flows.FlowMetadata;
import google.registry.flows.SessionMetadata;
import google.registry.flows.domain.DomainPricingLogic;
import google.registry.flows.domain.FeesAndCredits;
import google.registry.model.ImmutableObject;
import google.registry.model.eppinput.EppInput;
import google.registry.model.tld.Tld;
import javax.annotation.Nullable;
@@ -75,171 +74,135 @@ public class DomainPricingCustomLogic extends BaseFlowCustomLogic {
return priceParameters.feesAndCredits();
}
/** A class to encapsulate parameters for a call to {@link #customizeCreatePrice} . */
@AutoValue
public abstract static class CreatePriceParameters extends ImmutableObject {
public abstract FeesAndCredits feesAndCredits();
public abstract Tld tld();
public abstract InternetDomainName domainName();
public abstract DateTime asOfDate();
public abstract int years();
/** A record to encapsulate parameters for a call to {@link #customizeCreatePrice} . */
public record CreatePriceParameters(
FeesAndCredits feesAndCredits,
Tld tld,
InternetDomainName domainName,
DateTime asOfDate,
int years) {
public static Builder newBuilder() {
return new AutoValue_DomainPricingCustomLogic_CreatePriceParameters.Builder();
return new AutoBuilder_DomainPricingCustomLogic_CreatePriceParameters_Builder();
}
/** Builder for {@link CreatePriceParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
public abstract Builder setTld(Tld tld);
Builder setTld(Tld tld);
public abstract Builder setDomainName(InternetDomainName domainName);
Builder setDomainName(InternetDomainName domainName);
public abstract Builder setAsOfDate(DateTime asOfDate);
Builder setAsOfDate(DateTime asOfDate);
public abstract Builder setYears(int years);
Builder setYears(int years);
public abstract CreatePriceParameters build();
CreatePriceParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #customizeRenewPrice} . */
@AutoValue
public abstract static class RenewPriceParameters extends ImmutableObject {
public abstract FeesAndCredits feesAndCredits();
public abstract Tld tld();
public abstract InternetDomainName domainName();
public abstract DateTime asOfDate();
public abstract int years();
/** A record to encapsulate parameters for a call to {@link #customizeRenewPrice} . */
public record RenewPriceParameters(
FeesAndCredits feesAndCredits,
Tld tld,
InternetDomainName domainName,
DateTime asOfDate,
int years) {
public static Builder newBuilder() {
return new AutoValue_DomainPricingCustomLogic_RenewPriceParameters.Builder();
return new AutoBuilder_DomainPricingCustomLogic_RenewPriceParameters_Builder();
}
/** Builder for {@link RenewPriceParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
public abstract Builder setTld(Tld tld);
Builder setTld(Tld tld);
public abstract Builder setDomainName(InternetDomainName domainName);
Builder setDomainName(InternetDomainName domainName);
public abstract Builder setAsOfDate(DateTime asOfDate);
Builder setAsOfDate(DateTime asOfDate);
public abstract Builder setYears(int years);
Builder setYears(int years);
public abstract RenewPriceParameters build();
RenewPriceParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #customizeRestorePrice} . */
@AutoValue
public abstract static class RestorePriceParameters extends ImmutableObject {
public abstract FeesAndCredits feesAndCredits();
public abstract Tld tld();
public abstract InternetDomainName domainName();
public abstract DateTime asOfDate();
/** A record to encapsulate parameters for a call to {@link #customizeRestorePrice} . */
public record RestorePriceParameters(
FeesAndCredits feesAndCredits, Tld tld, InternetDomainName domainName, DateTime asOfDate) {
public static Builder newBuilder() {
return new AutoValue_DomainPricingCustomLogic_RestorePriceParameters.Builder();
return new AutoBuilder_DomainPricingCustomLogic_RestorePriceParameters_Builder();
}
/** Builder for {@link RestorePriceParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
public abstract Builder setTld(Tld tld);
Builder setTld(Tld tld);
public abstract Builder setDomainName(InternetDomainName domainName);
Builder setDomainName(InternetDomainName domainName);
public abstract Builder setAsOfDate(DateTime asOfDate);
Builder setAsOfDate(DateTime asOfDate);
public abstract RestorePriceParameters build();
RestorePriceParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #customizeTransferPrice} . */
@AutoValue
public abstract static class TransferPriceParameters extends ImmutableObject {
public abstract FeesAndCredits feesAndCredits();
public abstract Tld tld();
public abstract InternetDomainName domainName();
public abstract DateTime asOfDate();
/** A record to encapsulate parameters for a call to {@link #customizeTransferPrice} . */
public record TransferPriceParameters(
FeesAndCredits feesAndCredits, Tld tld, InternetDomainName domainName, DateTime asOfDate) {
public static Builder newBuilder() {
return new AutoValue_DomainPricingCustomLogic_TransferPriceParameters.Builder();
return new AutoBuilder_DomainPricingCustomLogic_TransferPriceParameters_Builder();
}
/** Builder for {@link TransferPriceParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
public abstract Builder setTld(Tld tld);
Builder setTld(Tld tld);
public abstract Builder setDomainName(InternetDomainName domainName);
Builder setDomainName(InternetDomainName domainName);
public abstract Builder setAsOfDate(DateTime asOfDate);
Builder setAsOfDate(DateTime asOfDate);
public abstract TransferPriceParameters build();
TransferPriceParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #customizeUpdatePrice} . */
@AutoValue
public abstract static class UpdatePriceParameters extends ImmutableObject {
public abstract FeesAndCredits feesAndCredits();
public abstract Tld tld();
public abstract InternetDomainName domainName();
public abstract DateTime asOfDate();
/** A record to encapsulate parameters for a call to {@link #customizeUpdatePrice} . */
public record UpdatePriceParameters(
FeesAndCredits feesAndCredits, Tld tld, InternetDomainName domainName, DateTime asOfDate) {
public static Builder newBuilder() {
return new AutoValue_DomainPricingCustomLogic_UpdatePriceParameters.Builder();
return new AutoBuilder_DomainPricingCustomLogic_UpdatePriceParameters_Builder();
}
/** Builder for {@link UpdatePriceParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
Builder setFeesAndCredits(FeesAndCredits feesAndCredits);
public abstract Builder setTld(Tld tld);
Builder setTld(Tld tld);
public abstract Builder setDomainName(InternetDomainName domainName);
Builder setDomainName(InternetDomainName domainName);
public abstract Builder setAsOfDate(DateTime asOfDate);
Builder setAsOfDate(DateTime asOfDate);
public abstract UpdatePriceParameters build();
UpdatePriceParameters build();
}
}
}

View File

@@ -15,13 +15,11 @@
package google.registry.flows.custom;
import com.google.auto.value.AutoBuilder;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import google.registry.flows.EppException;
import google.registry.flows.FlowMetadata;
import google.registry.flows.SessionMetadata;
import google.registry.flows.domain.DomainRenewFlow;
import google.registry.model.ImmutableObject;
import google.registry.model.domain.Domain;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppResponse.ResponseData;
@@ -103,103 +101,89 @@ public class DomainRenewFlowCustomLogic extends BaseFlowCustomLogic {
}
/**
* A class to encapsulate parameters for a call to {@link #beforeSave}.
* A record to encapsulate parameters for a call to {@link #beforeSave}.
*
* <p>Note that both newDomain and historyEntry are included in entityChanges. They are also
* passed separately for convenience, but they are the same instance, and changes to them will
* also affect what is persisted from entityChanges.
*/
@AutoValue
public abstract static class BeforeSaveParameters extends ImmutableObject {
public abstract Domain existingDomain();
public abstract Domain newDomain();
public abstract HistoryEntry historyEntry();
public abstract EntityChanges entityChanges();
public abstract int years();
public abstract DateTime now();
public record BeforeSaveParameters(
Domain existingDomain,
Domain newDomain,
HistoryEntry historyEntry,
EntityChanges entityChanges,
int years,
DateTime now) {
public static Builder newBuilder() {
return new AutoValue_DomainRenewFlowCustomLogic_BeforeSaveParameters.Builder();
return new AutoBuilder_DomainRenewFlowCustomLogic_BeforeSaveParameters_Builder();
}
/** Builder for {@link BeforeSaveParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setExistingDomain(Domain existingDomain);
Builder setExistingDomain(Domain existingDomain);
public abstract Builder setNewDomain(Domain newDomain);
Builder setNewDomain(Domain newDomain);
public abstract Builder setHistoryEntry(HistoryEntry historyEntry);
Builder setHistoryEntry(HistoryEntry historyEntry);
public abstract Builder setEntityChanges(EntityChanges entityChanges);
Builder setEntityChanges(EntityChanges entityChanges);
public abstract Builder setYears(int years);
Builder setYears(int years);
public abstract Builder setNow(DateTime now);
Builder setNow(DateTime now);
public abstract BeforeSaveParameters build();
BeforeSaveParameters build();
}
}
/** A class to encapsulate parameters for a call to {@link #beforeResponse}. */
@AutoValue
public abstract static class BeforeResponseParameters extends ImmutableObject {
public abstract Domain domain();
public abstract ResponseData resData();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
/** A record to encapsulate parameters for a call to {@link #beforeResponse}. */
public record BeforeResponseParameters(
Domain domain,
ResponseData resData,
ImmutableList<? extends ResponseExtension> responseExtensions) {
public static BeforeResponseParameters.Builder newBuilder() {
return new AutoValue_DomainRenewFlowCustomLogic_BeforeResponseParameters.Builder();
return new AutoBuilder_DomainRenewFlowCustomLogic_BeforeResponseParameters_Builder();
}
/** Builder for {@link BeforeResponseParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract BeforeResponseParameters.Builder setDomain(Domain domain);
BeforeResponseParameters.Builder setDomain(Domain domain);
public abstract BeforeResponseParameters.Builder setResData(ResponseData resData);
BeforeResponseParameters.Builder setResData(ResponseData resData);
public abstract BeforeResponseParameters.Builder setResponseExtensions(
BeforeResponseParameters.Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseParameters build();
BeforeResponseParameters build();
}
}
/**
* A class to encapsulate parameters for the return values from a call to {@link #beforeResponse}.
* A record to encapsulate parameters for the return values from a call to {@link
* #beforeResponse}.
*/
@AutoValue
public abstract static class BeforeResponseReturnData extends ImmutableObject {
public abstract ResponseData resData();
public abstract ImmutableList<? extends ResponseExtension> responseExtensions();
public record BeforeResponseReturnData(
ResponseData resData, ImmutableList<? extends ResponseExtension> responseExtensions) {
public static Builder newBuilder() {
return new AutoValue_DomainRenewFlowCustomLogic_BeforeResponseReturnData.Builder();
return new AutoBuilder_DomainRenewFlowCustomLogic_BeforeResponseReturnData_Builder();
}
/** Builder for {@link BeforeResponseReturnData}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setResData(ResponseData resData);
Builder setResData(ResponseData resData);
public abstract Builder setResponseExtensions(
ImmutableList<? extends ResponseExtension> responseExtensions);
Builder setResponseExtensions(ImmutableList<? extends ResponseExtension> responseExtensions);
public abstract BeforeResponseReturnData build();
BeforeResponseReturnData build();
}
}
}

View File

@@ -14,12 +14,11 @@
package google.registry.flows.custom;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import google.registry.flows.EppException;
import google.registry.flows.FlowMetadata;
import google.registry.flows.SessionMetadata;
import google.registry.flows.domain.DomainUpdateFlow;
import google.registry.model.ImmutableObject;
import google.registry.model.domain.Domain;
import google.registry.model.eppinput.EppInput;
import google.registry.model.reporting.HistoryEntry;
@@ -61,61 +60,53 @@ public class DomainUpdateFlowCustomLogic extends BaseFlowCustomLogic {
return parameters.entityChanges();
}
/** A class to encapsulate parameters for a call to {@link #afterValidation}. */
@AutoValue
public abstract static class AfterValidationParameters extends ImmutableObject {
public abstract Domain existingDomain();
/** A record to encapsulate parameters for a call to {@link #afterValidation}. */
public record AfterValidationParameters(Domain existingDomain) {
public static Builder newBuilder() {
return new AutoValue_DomainUpdateFlowCustomLogic_AfterValidationParameters.Builder();
return new AutoBuilder_DomainUpdateFlowCustomLogic_AfterValidationParameters_Builder();
}
/** Builder for {@link AfterValidationParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setExistingDomain(Domain existingDomain);
Builder setExistingDomain(Domain existingDomain);
public abstract AfterValidationParameters build();
AfterValidationParameters build();
}
}
/**
* A class to encapsulate parameters for a call to {@link #beforeSave}.
* A record to encapsulate parameters for a call to {@link #beforeSave}.
*
* <p>Note that both newDomain and historyEntry are included in entityChanges. They are also
* passed separately for convenience, but they are the same instance, and changes to them will
* also affect what is persisted from entityChanges.
*/
@AutoValue
public abstract static class BeforeSaveParameters extends ImmutableObject {
public abstract Domain existingDomain();
public abstract Domain newDomain();
public abstract HistoryEntry historyEntry();
public abstract EntityChanges entityChanges();
public record BeforeSaveParameters(
Domain existingDomain,
Domain newDomain,
HistoryEntry historyEntry,
EntityChanges entityChanges) {
public static Builder newBuilder() {
return new AutoValue_DomainUpdateFlowCustomLogic_BeforeSaveParameters.Builder();
return new AutoBuilder_DomainUpdateFlowCustomLogic_BeforeSaveParameters_Builder();
}
/** Builder for {@link BeforeSaveParameters}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setExistingDomain(Domain existingDomain);
Builder setExistingDomain(Domain existingDomain);
public abstract Builder setNewDomain(Domain newDomain);
Builder setNewDomain(Domain newDomain);
public abstract Builder setHistoryEntry(HistoryEntry historyEntry);
Builder setHistoryEntry(HistoryEntry historyEntry);
public abstract Builder setEntityChanges(EntityChanges entityChanges);
Builder setEntityChanges(EntityChanges entityChanges);
public abstract BeforeSaveParameters build();
BeforeSaveParameters build();
}
}
}

View File

@@ -14,49 +14,55 @@
package google.registry.flows.custom;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableSet;
import google.registry.model.ImmutableObject;
import google.registry.persistence.VKey;
/** A wrapper class that encapsulates database entities to both save and delete. */
@AutoValue
public abstract class EntityChanges {
/** A record that encapsulates database entities to both save and delete. */
public record EntityChanges(
ImmutableSet<ImmutableObject> saves, ImmutableSet<VKey<ImmutableObject>> deletes) {
public abstract ImmutableSet<ImmutableObject> getSaves();
public ImmutableSet<ImmutableObject> getSaves() {
return saves;
}
;
public abstract ImmutableSet<VKey<ImmutableObject>> getDeletes();
public ImmutableSet<VKey<ImmutableObject>> getDeletes() {
return deletes;
}
;
public static Builder newBuilder() {
// Default both entities to save and entities to delete to empty sets, so that the build()
// method won't subsequently throw an exception if one doesn't end up being applicable.
return new AutoValue_EntityChanges.Builder()
return new AutoBuilder_EntityChanges_Builder()
.setSaves(ImmutableSet.of())
.setDeletes(ImmutableSet.of());
}
/** Builder for {@link EntityChanges}. */
@AutoValue.Builder
public abstract static class Builder {
@AutoBuilder
public interface Builder {
public abstract Builder setSaves(ImmutableSet<ImmutableObject> entitiesToSave);
Builder setSaves(ImmutableSet<ImmutableObject> entitiesToSave);
public abstract ImmutableSet.Builder<ImmutableObject> savesBuilder();
ImmutableSet.Builder<ImmutableObject> savesBuilder();
public Builder addSave(ImmutableObject entityToSave) {
default Builder addSave(ImmutableObject entityToSave) {
savesBuilder().add(entityToSave);
return this;
}
public abstract Builder setDeletes(ImmutableSet<VKey<ImmutableObject>> entitiesToDelete);
Builder setDeletes(ImmutableSet<VKey<ImmutableObject>> entitiesToDelete);
public abstract ImmutableSet.Builder<VKey<ImmutableObject>> deletesBuilder();
ImmutableSet.Builder<VKey<ImmutableObject>> deletesBuilder();
public Builder addDelete(VKey<ImmutableObject> entityToDelete) {
default Builder addDelete(VKey<ImmutableObject> entityToDelete) {
deletesBuilder().add(entityToDelete);
return this;
}
public abstract EntityChanges build();
EntityChanges build();
}
}

View File

@@ -57,7 +57,6 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InternetDomainName;
@@ -698,18 +697,13 @@ public final class DomainCreateFlow implements MutatingFlow {
}
}
/** A class to store renewal info used in {@link BillingRecurrence} billing events. */
@AutoValue
public abstract static class RenewalPriceInfo {
static DomainCreateFlow.RenewalPriceInfo create(
/** A record to store renewal info used in {@link BillingRecurrence} billing events. */
public record RenewalPriceInfo(
RenewalPriceBehavior renewalPriceBehavior, @Nullable Money renewalPrice) {
static RenewalPriceInfo create(
RenewalPriceBehavior renewalPriceBehavior, @Nullable Money renewalPrice) {
return new AutoValue_DomainCreateFlow_RenewalPriceInfo(renewalPriceBehavior, renewalPrice);
return new RenewalPriceInfo(renewalPriceBehavior, renewalPrice);
}
public abstract RenewalPriceBehavior renewalPriceBehavior();
@Nullable
public abstract Money renewalPrice();
}
private static ImmutableList<FeeTransformResponseExtension> createResponseExtensions(

View File

@@ -14,23 +14,11 @@
package google.registry.flows.domain.token;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.InternetDomainName;
import google.registry.model.domain.token.AllocationToken;
import java.util.Optional;
/** Value class to represent the result of loading a token and checking domains with it. */
@AutoValue
public abstract class AllocationTokenDomainCheckResults {
public abstract Optional<AllocationToken> token();
public abstract ImmutableMap<InternetDomainName, String> domainCheckResults();
public static AllocationTokenDomainCheckResults create(
Optional<AllocationToken> allocationToken,
ImmutableMap<InternetDomainName, String> domainCheckResults) {
return new AutoValue_AllocationTokenDomainCheckResults(allocationToken, domainCheckResults);
}
}
/** Record to represent the result of loading a token and checking domains with it. */
public record AllocationTokenDomainCheckResults(
Optional<AllocationToken> token, ImmutableMap<InternetDomainName, String> domainCheckResults) {}

View File

@@ -69,9 +69,8 @@ public class AllocationTokenFlowUtils {
try {
tokenEntity = loadToken(token);
} catch (EppException e) {
return AllocationTokenDomainCheckResults.create(
Optional.empty(),
ImmutableMap.copyOf(Maps.toMap(domainNames, ignored -> e.getMessage())));
return new AllocationTokenDomainCheckResults(
Optional.empty(), Maps.toMap(domainNames, ignored -> e.getMessage()));
}
// If the token is only invalid for some domain names (e.g. an invalid TLD), include those error
@@ -97,8 +96,7 @@ public class AllocationTokenFlowUtils {
resultsBuilder.putAll(
tokenCustomLogic.checkDomainsWithToken(
validDomainNames.build(), tokenEntity, registrarId, now));
return AllocationTokenDomainCheckResults.create(
Optional.of(tokenEntity), resultsBuilder.build());
return new AllocationTokenDomainCheckResults(Optional.of(tokenEntity), resultsBuilder.build());
}
/** Redeems a SINGLE_USE {@link AllocationToken}, returning the redeemed copy. */

View File

@@ -23,7 +23,6 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -221,15 +220,10 @@ public final class ForeignKeyUtils {
e -> VKey.create(clazz, e.getValue().get().repoId())));
}
@AutoValue
abstract static class MostRecentResource {
abstract String repoId();
abstract DateTime deletionTime();
record MostRecentResource(String repoId, DateTime deletionTime) {
static MostRecentResource create(String repoId, DateTime deletionTime) {
return new AutoValue_ForeignKeyUtils_MostRecentResource(repoId, deletionTime);
return new MostRecentResource(repoId, deletionTime);
}
}
}

View File

@@ -15,6 +15,7 @@
package google.registry.model.server;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.persistence.PersistenceModule.TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.isAtOrAfter;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
@@ -196,7 +197,20 @@ public class Lock extends ImmutableObject implements Serializable {
return new AcquireResult(now, lock, newLock, lockState);
};
AcquireResult acquireResult = tm().transact(lockAcquirer);
/*
* Use REPEATABLE READ to avoid write conflicts with other locks.
*
* <p>Since the Lock table is small, Postgresql may choose table scan instead of PK lookup. At
* the SERIALIZABLE level this can cause conflicts with other locks. There is no way to forbid
* table scan on a per-query or per-table basis.
*
* <p>Using REPEATABLE READ is safe since Lock acquire/release only accesses one row. Note that
* passing the isolation level to the `transact` method requires that it is not a nested
* transaction. As of the time of this change this is the case.
*
* <p>See b/333537928 for more information.
*/
AcquireResult acquireResult = tm().transact(TRANSACTION_REPEATABLE_READ, lockAcquirer);
logAcquireResult(acquireResult);
lockMetrics.recordAcquire(resourceName, scope, acquireResult.lockState());
@@ -232,7 +246,8 @@ public class Lock extends ImmutableObject implements Serializable {
"Not deleting lock: %s - someone else has it: %s", lockId, loadedLock);
}
};
tm().transact(lockReleaser);
// See comments in the `acquire` method for this isolation level.
tm().transact(TRANSACTION_REPEATABLE_READ, lockReleaser);
}
static class LockId extends ImmutableObject implements Serializable {

View File

@@ -458,10 +458,10 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
@JsonDeserialize(using = CurrencyDeserializer.class)
CurrencyUnit currency = DEFAULT_CURRENCY;
// TODO(sarahbot@): Remove this field and make createBillingCostTransitions not-null once all TLDs
// are populated with a create cost transition map
// TODO(sarahbot@): Remove this field once all saved configuration files have this field removed
/** The per-year billing cost for registering a new domain name. */
@Deprecated
@JsonIgnore
@Type(type = JodaMoneyType.TYPE_NAME)
@Columns(
columns = {
@@ -470,10 +470,10 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
})
Money createBillingCost = DEFAULT_CREATE_BILLING_COST;
// TODO(sarahbot@): Make this field not null in the database
// TODO(sarahbot@): Rename this field to createBillingCost once the old createBillingCost has been
// removed
/** A property that transitions to different create billing costs at different times. */
@Column(nullable = false)
@JsonDeserialize(using = TimedTransitionPropertyMoneyDeserializer.class)
TimedTransitionProperty<Money> createBillingCostTransitions =
TimedTransitionProperty.withInitialValue(DEFAULT_CREATE_BILLING_COST);
@@ -1165,10 +1165,6 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
// here to catch cases where we loaded an invalid TimedTransitionProperty from the database
// and cloned it into a new builder, to block re-building a Tld in an invalid state.
instance.tldStateTransitions.checkValidity();
// TODO(sarahbot@): Remove null check when createBillingCostTransitions field is made not-null
checkArgumentNotNull(
instance.getCreateBillingCostTransitions(),
"CreateBillingCostTransitions cannot be null");
instance.createBillingCostTransitions.checkValidity();
instance.renewBillingCostTransitions.checkValidity();
instance.eapFeeSchedule.checkValidity();

View File

@@ -14,7 +14,6 @@
package google.registry.model.tld.label;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.monitoring.metrics.EventMetric;
@@ -43,16 +42,11 @@ class DomainLabelMetrics {
UNCACHED_POSITIVE
}
@AutoValue
abstract static class MetricsReservedListMatch {
record MetricsReservedListMatch(String reservedListName, ReservationType reservationType) {
static MetricsReservedListMatch create(
String reservedListName, ReservationType reservationType) {
return new AutoValue_DomainLabelMetrics_MetricsReservedListMatch(
reservedListName, reservationType);
return new MetricsReservedListMatch(reservedListName, reservationType);
}
abstract String reservedListName();
abstract ReservationType reservationType();
}
/**

View File

@@ -23,7 +23,6 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.util.CollectionUtils.isNullOrEmpty;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -236,14 +235,10 @@ public final class PremiumListDao {
.collect(toImmutableList());
}
@AutoValue
abstract static class RevisionIdAndLabel {
abstract long revisionId();
abstract String label();
record RevisionIdAndLabel(long revisionId, String label) {
static RevisionIdAndLabel create(long revisionId, String label) {
return new AutoValue_PremiumListDao_RevisionIdAndLabel(revisionId, label);
return new RevisionIdAndLabel(revisionId, label);
}
}

View File

@@ -110,6 +110,8 @@ import google.registry.tools.server.ToolsServerModule;
import google.registry.tools.server.VerifyOteAction;
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.ConsoleUserDataAction;
import google.registry.ui.server.console.RegistrarsAction;
import google.registry.ui.server.console.settings.ContactAction;
@@ -178,6 +180,8 @@ interface RequestComponent {
ConsoleDomainListAction consoleDomainListAction();
ConsoleEppPasswordAction consoleEppPasswordAction();
ConsoleOteSetupAction consoleOteSetupAction();
ConsoleRegistrarCreatorAction consoleRegistrarCreatorAction();
@@ -186,6 +190,8 @@ interface RequestComponent {
ConsoleUserDataAction consoleUserDataAction();
ConsoleDumDownloadAction ConsoleDumDownloadAction();
ContactAction contactAction();
CopyDetailReportsAction copyDetailReportAction();

View File

@@ -27,6 +27,8 @@ import google.registry.request.RequestModule;
import google.registry.request.RequestScope;
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.ConsoleUserDataAction;
import google.registry.ui.server.console.RegistrarsAction;
import google.registry.ui.server.console.settings.ContactAction;
@@ -58,12 +60,16 @@ public interface FrontendRequestComponent {
ConsoleDomainListAction consoleDomainListAction();
ConsoleEppPasswordAction consoleEppPasswordAction();
ConsoleOteSetupAction consoleOteSetupAction();
ConsoleRegistrarCreatorAction consoleRegistrarCreatorAction();
ConsoleUiAction consoleUiAction();
ConsoleUserDataAction consoleUserDataAction();
ConsoleDumDownloadAction ConsoleDumDownloadAction();
ContactAction contactAction();
EppTlsAction eppTlsAction();

View File

@@ -16,14 +16,18 @@ package google.registry.monitoring.whitebox;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import google.registry.util.Clock;
import java.util.Optional;
import org.joda.time.DateTime;
/** A value class for recording attributes of a domain check metric. */
@AutoValue
public abstract class CheckApiMetric {
/** A record for recording attributes of a domain check metric. */
public record CheckApiMetric(
DateTime startTimestamp,
DateTime endTimestamp,
Status status,
Optional<Tier> tier,
Optional<Availability> availability) {
/** Price tier of a domain name. */
public enum Tier {
@@ -77,24 +81,13 @@ public abstract class CheckApiMetric {
}
}
public abstract DateTime startTimestamp();
public abstract DateTime endTimestamp();
public abstract Status status();
public abstract Optional<Tier> tier();
public abstract Optional<Availability> availability();
public static Builder builder(Clock clock) {
return new AutoValue_CheckApiMetric.Builder().startTimestamp(clock.nowUtc()).setClock(clock);
return new AutoBuilder_CheckApiMetric_Builder().startTimestamp(clock.nowUtc()).setClock(clock);
}
CheckApiMetric() {}
/** Builder for {@link CheckApiMetric}. */
@AutoValue.Builder
@AutoBuilder
public abstract static class Builder {
private Clock clock;

View File

@@ -16,7 +16,7 @@ package google.registry.monitoring.whitebox;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import google.registry.model.eppoutput.Result.Code;
@@ -25,30 +25,23 @@ import google.registry.util.Clock;
import java.util.Optional;
import org.joda.time.DateTime;
/** A value class for recording attributes of an EPP metric. */
@AutoValue
public abstract class EppMetric {
/** A record for recording attributes of an EPP metric. */
public record EppMetric(
DateTime startTimestamp,
DateTime endTimestamp,
Optional<String> commandName,
Optional<String> registrarId,
Optional<String> tld,
Optional<Code> status) {
public abstract DateTime getStartTimestamp();
public abstract DateTime getEndTimestamp();
public abstract Optional<String> getCommandName();
public abstract Optional<String> getRegistrarId();
public abstract Optional<String> getTld();
public abstract Optional<Code> getStatus();
/** Create an {@link EppMetric.Builder}. */
/** Create an {@link Builder}. */
public static Builder builder() {
return new AutoValue_EppMetric.Builder();
return new AutoBuilder_EppMetric_Builder();
}
/**
* Create an {@link EppMetric.Builder} for a request context, with the given request ID and
* with start and end timestamps taken from the given clock.
* Create an {@link Builder} for a request context, with the given request ID and with start and
* end timestamps taken from the given clock.
*
* <p>The start timestamp is recorded now, and the end timestamp at {@code build()}.
*/
@@ -58,8 +51,32 @@ public abstract class EppMetric {
.setClock(clock);
}
public DateTime getStartTimestamp() {
return startTimestamp;
}
public DateTime getEndTimestamp() {
return endTimestamp;
}
public Optional<String> getCommandName() {
return commandName;
}
public Optional<String> getRegistrarId() {
return registrarId;
}
public Optional<String> getTld() {
return tld;
}
public Optional<Code> getStatus() {
return status;
}
/** A builder to create instances of {@link EppMetric}. */
@AutoValue.Builder
@AutoBuilder
public abstract static class Builder {
/** Builder-only clock to support automatic recording of endTimestamp on {@link #build()}. */
@@ -97,18 +114,14 @@ public abstract class EppMetric {
*/
public Builder setTlds(ImmutableSet<String> tlds) {
switch (tlds.size()) {
case 0:
setTld(Optional.empty());
break;
case 1:
case 0 -> setTld(Optional.empty());
case 1 -> {
String tld = Iterables.getOnlyElement(tlds);
// Only record TLDs that actually exist, otherwise we can blow up cardinality by recording
// an arbitrarily large number of strings.
setTld(Optional.ofNullable(Tlds.getTlds().contains(tld) ? tld : "_invalid"));
break;
default:
setTld("_various");
break;
}
default -> setTld("_various");
}
return this;
}

View File

@@ -14,7 +14,6 @@
package google.registry.privileges.secretmanager;
import com.google.auto.value.AutoValue;
import com.google.cloud.secretmanager.v1.SecretVersion;
import com.google.common.collect.Streams;
import java.util.Optional;
@@ -116,18 +115,11 @@ public interface SecretManagerClient {
void deleteSecret(String secretId);
/** Contains the {@link SecretVersion.State State} of an secret version. */
@AutoValue
abstract class SecretVersionState {
record SecretVersionState(String secretId, String version, SecretVersion.State state) {
public abstract String secretId();
public abstract String version();
public abstract SecretVersion.State state();
public static SecretVersionState of(
public static SecretVersionState create(
String secretId, String version, SecretVersion.State state) {
return new AutoValue_SecretManagerClient_SecretVersionState(secretId, version, state);
return new SecretVersionState(secretId, version, state);
}
}

View File

@@ -94,7 +94,7 @@ public class SecretManagerClientImpl implements SecretManagerClient {
private static SecretVersionState toSecretVersionState(SecretVersion secretVersion) {
SecretVersionName name = SecretVersionName.parse(secretVersion.getName());
return SecretVersionState.of(
return SecretVersionState.create(
name.getSecret(), name.getSecretVersion(), secretVersion.getState());
}

View File

@@ -16,7 +16,6 @@ package google.registry.privileges.secretmanager;
import static avro.shaded.com.google.common.base.Preconditions.checkState;
import com.google.auto.value.AutoValue;
import java.util.List;
/**
@@ -24,32 +23,27 @@ import java.util.List;
*
* <p>User must take care not to include the {@link #SEPARATOR} in property values.
*/
@AutoValue
public abstract class SqlCredential {
public record SqlCredential(String login, String password) {
public static final Character SEPARATOR = ' ';
public abstract String login();
public abstract String password();
@Override
public final String toString() {
// Use Object.toString(), which does not show object data.
return super.toString();
public String toString() {
// Use the Object.toString() implementation, which does not show the sensitive date in fields.
return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
}
public final String toFormattedString() {
public String toFormattedString() {
return String.format("%s%c%s", login(), SEPARATOR, password());
}
public static SqlCredential fromFormattedString(String sqlCredential) {
List<String> items = com.google.common.base.Splitter.on(SEPARATOR).splitToList(sqlCredential);
checkState(items.size() == 2, "Invalid SqlCredential string.");
return of(items.get(0), items.get(1));
return create(items.get(0), items.get(1));
}
public static SqlCredential of(String login, String password) {
return new AutoValue_SqlCredential(login, password);
public static SqlCredential create(String login, String password) {
return new SqlCredential(login, password);
}
}

View File

@@ -79,7 +79,7 @@ public class SqlCredentialStore {
String credentialVersion =
csmClient.addSecretVersion(
credentialDataSecretId,
SqlCredential.of(createDatabaseLoginName(user), password).toFormattedString());
SqlCredential.create(createDatabaseLoginName(user), password).toFormattedString());
return SecretVersionName.of(csmClient.getProject(), credentialDataSecretId, credentialVersion);
}

View File

@@ -14,13 +14,16 @@
package google.registry.rdap;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import google.registry.model.ImmutableObject;
/** Authorization information for RDAP data access. */
@AutoValue
public abstract class RdapAuthorization extends ImmutableObject {
/**
* Authorization information for RDAP data access.
*
* @param role The role to be used for access.
* @param registrarIds The registrar client IDs for which access is granted (used only if the role
* is REGISTRAR.
*/
public record RdapAuthorization(Role role, ImmutableSet<String> registrarIds) {
enum Role {
ADMINISTRATOR,
@@ -28,29 +31,20 @@ public abstract class RdapAuthorization extends ImmutableObject {
PUBLIC
}
/** The role to be used for access. */
public abstract Role role();
/** The registrar client IDs for which access is granted (used only if the role is REGISTRAR. */
public abstract ImmutableSet<String> registrarIds();
static RdapAuthorization create(Role role, String registrarId) {
return new AutoValue_RdapAuthorization(role, ImmutableSet.of(registrarId));
return create(role, ImmutableSet.of(registrarId));
}
static RdapAuthorization create(Role role, ImmutableSet<String> clientIds) {
return new AutoValue_RdapAuthorization(role, clientIds);
return new RdapAuthorization(role, clientIds);
}
boolean isAuthorizedForRegistrar(String registrarId) {
switch (role()) {
case ADMINISTRATOR:
return true;
case REGISTRAR:
return registrarIds().contains(registrarId);
default:
return false;
}
return switch (role()) {
case ADMINISTRATOR -> true;
case REGISTRAR -> registrarIds().contains(registrarId);
default -> false;
};
}
public static final RdapAuthorization PUBLIC_AUTHORIZATION =

View File

@@ -14,22 +14,16 @@
package google.registry.rde;
import com.google.auto.value.AutoValue;
import java.io.Serial;
import java.io.Serializable;
/** Container of RDE resource marshalled by {@link RdeMarshaller}. */
@AutoValue
public abstract class DepositFragment implements Serializable {
public record DepositFragment(RdeResourceType type, String xml, String error)
implements Serializable {
private static final long serialVersionUID = -5241410684255467454L;
public abstract RdeResourceType type();
public abstract String xml();
public abstract String error();
@Serial private static final long serialVersionUID = -5241410684255467454L;
public static DepositFragment create(RdeResourceType type, String xml, String error) {
return new AutoValue_DepositFragment(type, xml, error);
return new DepositFragment(type, xml, error);
}
DepositFragment() {}
}

View File

@@ -16,7 +16,6 @@ package google.registry.rde;
import static com.google.common.base.Preconditions.checkState;
import com.google.auto.value.AutoValue;
import google.registry.model.common.Cursor.CursorType;
import google.registry.model.rde.RdeMode;
import java.io.IOException;
@@ -46,52 +45,35 @@ import org.joda.time.Duration;
* arguments (see {@code RdePipeline#decodePendingDeposits}). The latter requires safe
* deserialization because the data crosses credential boundaries (See {@code
* SafeObjectInputStream}).
*
* @param manual True if deposits should be generated via manual operation, which does not update
* the cursor, and saves the generated deposits in a special manual subdirectory tree.
* @param tld TLD for which a deposit should be generated.
* @param watermark Watermark date for which a deposit should be generated.
* @param mode Which type of deposit to generate: full (RDE) or thin (BRDA).
* @param cursor The cursor type to update (not used in manual operation).
* @param interval Amount of time to increment the cursor (not used in manual operation).
* @param directoryWithTrailingSlash Subdirectory of bucket/manual in which files should be placed,
* including a trailing slash (used only in manual operation).
* @param revision Revision number for generated files; if absent, use the next available in the
* sequence (used only in manual operation).
*/
@AutoValue
public abstract class PendingDeposit implements Serializable {
public record PendingDeposit(
boolean manual,
String tld,
DateTime watermark,
RdeMode mode,
CursorType cursor,
Duration interval,
String directoryWithTrailingSlash,
@Nullable Integer revision)
implements Serializable {
private static final long serialVersionUID = 3141095605225904433L;
/**
* True if deposits should be generated via manual operation, which does not update the cursor,
* and saves the generated deposits in a special manual subdirectory tree.
*/
public abstract boolean manual();
/** TLD for which a deposit should be generated. */
public abstract String tld();
/** Watermark date for which a deposit should be generated. */
public abstract DateTime watermark();
/** Which type of deposit to generate: full (RDE) or thin (BRDA). */
public abstract RdeMode mode();
/** The cursor type to update (not used in manual operation). */
@Nullable
public abstract CursorType cursor();
/** Amount of time to increment the cursor (not used in manual operation). */
@Nullable
public abstract Duration interval();
/**
* Subdirectory of bucket/manual in which files should be placed, including a trailing slash (used
* only in manual operation).
*/
@Nullable
public abstract String directoryWithTrailingSlash();
/**
* Revision number for generated files; if absent, use the next available in the sequence (used
* only in manual operation).
*/
@Nullable
public abstract Integer revision();
public static PendingDeposit create(
String tld, DateTime watermark, RdeMode mode, CursorType cursor, Duration interval) {
return new AutoValue_PendingDeposit(false, tld, watermark, mode, cursor, interval, null, null);
return new PendingDeposit(false, tld, watermark, mode, cursor, interval, null, null);
}
public static PendingDeposit createInManualOperation(
@@ -100,15 +82,13 @@ public abstract class PendingDeposit implements Serializable {
RdeMode mode,
String directoryWithTrailingSlash,
@Nullable Integer revision) {
return new AutoValue_PendingDeposit(
return new PendingDeposit(
true, tld, watermark, mode, null, null, directoryWithTrailingSlash, revision);
}
PendingDeposit() {}
/**
* Specifies that {@link SerializedForm} be used for {@code SafeObjectInputStream}-compatible
* custom-serialization of {@link AutoValue_PendingDeposit the AutoValue implementation class}.
* custom-serialization of {@link PendingDeposit the AutoValue implementation class}.
*
* <p>This method is package-protected so that the AutoValue implementation class inherits this
* behavior.
@@ -193,7 +173,7 @@ public abstract class PendingDeposit implements Serializable {
@Override
public PendingDeposit decode(InputStream inStream) throws IOException {
return new AutoValue_PendingDeposit(
return new PendingDeposit(
BooleanCoder.of().decode(inStream),
StringUtf8Coder.of().decode(inStream),
DateTime.parse(StringUtf8Coder.of().decode(inStream)),

View File

@@ -17,7 +17,6 @@ package google.registry.rde;
import static google.registry.model.EppResourceUtils.loadAtPointInTime;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableMap;
import google.registry.model.EppResource;
import google.registry.model.contact.Contact;
@@ -96,14 +95,10 @@ public class RdeFragmenter {
}
/** Map key for {@link RdeFragmenter} cache. */
@AutoValue
abstract static class WatermarkModePair {
abstract DateTime watermark();
abstract RdeMode mode();
record WatermarkModePair(DateTime watermark, RdeMode mode) {
static WatermarkModePair create(DateTime watermark, RdeMode mode) {
return new AutoValue_RdeFragmenter_WatermarkModePair(watermark, mode);
return new WatermarkModePair(watermark, mode);
}
}
}

View File

@@ -14,20 +14,14 @@
package google.registry.reporting.spec11;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import google.registry.beam.spec11.ThreatMatch;
import java.util.List;
/** Value class representing the registrar and list-of-threat-matches pair stored in GCS. */
@AutoValue
public abstract class RegistrarThreatMatches {
public abstract String clientId();
public abstract ImmutableList<ThreatMatch> threatMatches();
/** Value record representing the registrar and list-of-threat-matches pair stored in GCS. */
public record RegistrarThreatMatches(String clientId, ImmutableList<ThreatMatch> threatMatches) {
static RegistrarThreatMatches create(String clientId, List<ThreatMatch> threatMatches) {
return new AutoValue_RegistrarThreatMatches(clientId, ImmutableList.copyOf(threatMatches));
return new RegistrarThreatMatches(clientId, ImmutableList.copyOf(threatMatches));
}
}

View File

@@ -17,6 +17,8 @@ package google.registry.request;
import com.google.common.net.MediaType;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import org.joda.time.DateTime;
/**
@@ -59,4 +61,6 @@ public interface Response {
* @see HttpServletResponse#addCookie(Cookie)
*/
void addCookie(Cookie cookie);
PrintWriter getWriter() throws IOException;
}

View File

@@ -18,6 +18,7 @@ import com.google.common.net.MediaType;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import javax.inject.Inject;
import org.joda.time.DateTime;
@@ -64,4 +65,9 @@ public final class ResponseImpl implements Response {
public void addCookie(Cookie cookie) {
rsp.addCookie(cookie);
}
@Override
public PrintWriter getWriter() throws IOException {
return rsp.getWriter();
}
}

View File

@@ -14,7 +14,6 @@
package google.registry.request;
import com.google.auto.value.AutoValue;
import java.util.function.Function;
/**
@@ -22,18 +21,13 @@ import java.util.function.Function;
*
* @see Router
*/
@AutoValue
abstract class Route {
record Route(Action action, Function<Object, Runnable> instantiator, Class<?> actionClass) {
static Route create(
Action action, Function<Object, Runnable> instantiator, Class<?> actionClass) {
return new AutoValue_Route(action, instantiator, actionClass);
return new Route(action, instantiator, actionClass);
}
abstract Action action();
abstract Function<Object, Runnable> instantiator();
abstract Class<?> actionClass();
boolean isMethodAllowed(Action.Method requestMethod) {
for (Action.Method method : action().method()) {
if (method == requestMethod) {

View File

@@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.request.auth.AuthSettings.AuthLevel.APP;
import static google.registry.request.auth.AuthSettings.AuthLevel.USER;
import com.google.auto.value.AutoValue;
import google.registry.request.auth.AuthSettings.AuthLevel;
import java.util.Optional;
import javax.annotation.Nullable;
@@ -26,18 +25,13 @@ import javax.annotation.Nullable;
/**
* Results of authentication for a given HTTP request, as emitted by an {@link
* AuthenticationMechanism}.
*
* @param userAuthInfo Information about the authenticated user, if there is one.
* @param appServiceAccount Service account email of the authenticated app, if there is one. This
* will be logged upon successful login.
*/
@AutoValue
public abstract class AuthResult {
public abstract AuthLevel authLevel();
/** Information about the authenticated user, if there is one. */
public abstract Optional<UserAuthInfo> userAuthInfo();
/** Service account email of the authenticated app, if there is one. */
@SuppressWarnings("unused") // The service account will be logged upon successful login.
public abstract Optional<String> appServiceAccount();
public record AuthResult(
AuthLevel authLevel, Optional<UserAuthInfo> userAuthInfo, Optional<String> appServiceAccount) {
public boolean isAuthenticated() {
return authLevel() != AuthLevel.NONE;
@@ -72,8 +66,7 @@ public abstract class AuthResult {
checkArgument(
authLevel != APP || email != null,
"Service account email must be specified for auth level APP");
return new AutoValue_AuthResult(
authLevel, Optional.ofNullable(userAuthInfo), Optional.ofNullable(email));
return new AuthResult(authLevel, Optional.ofNullable(userAuthInfo), Optional.ofNullable(email));
}
/**

View File

@@ -14,7 +14,6 @@
package google.registry.request.auth;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.Immutable;
import google.registry.model.console.UserRoles;
@@ -26,18 +25,12 @@ import google.registry.model.console.UserRoles;
* values.
*/
@Immutable
@AutoValue
public abstract class AuthSettings {
public abstract ImmutableList<AuthMethod> methods();
public abstract AuthLevel minimumLevel();
public abstract UserPolicy userPolicy();
public record AuthSettings(
ImmutableList<AuthMethod> methods, AuthLevel minimumLevel, UserPolicy userPolicy) {
static AuthSettings create(
ImmutableList<AuthMethod> methods, AuthLevel minimumLevel, UserPolicy userPolicy) {
return new AutoValue_AuthSettings(methods, minimumLevel, userPolicy);
return new AuthSettings(methods, minimumLevel, userPolicy);
}
/** Available methods for authentication. */

View File

@@ -15,26 +15,21 @@
package google.registry.request.auth;
import com.google.appengine.api.users.User;
import com.google.auto.value.AutoValue;
import java.util.Optional;
/** Extra information provided by the authentication mechanism about the user. */
@AutoValue
public abstract class UserAuthInfo {
public abstract Optional<google.registry.model.console.User> consoleUser();
/** User object from the AppEngine Users API. */
public abstract Optional<User> appEngineUser();
/**
* Whether the user is an admin.
*
* <p>Note that, in App Engine parlance, an admin is any user who is a project owner, editor, OR
* viewer (as well as the specific role App Engine Admin). So even users with read-only access to
* the App Engine product qualify as an "admin".
*/
public abstract boolean isUserAdmin();
/**
* Extra information provided by the authentication mechanism about the user.
*
* @param appEngineUser User object from the AppEngine Users API.
* @param isUserAdmin Whether the user is an admin.
* <p>Note that, in App Engine parlance, an admin is any user who is a project owner, editor, OR
* viewer (as well as the specific role App Engine Admin). So even users with read-only access
* to the App Engine product qualify as an "admin".
*/
public record UserAuthInfo(
Optional<google.registry.model.console.User> consoleUser,
Optional<User> appEngineUser,
boolean isUserAdmin) {
public String getEmailAddress() {
return appEngineUser()
@@ -49,11 +44,10 @@ public abstract class UserAuthInfo {
}
public static UserAuthInfo create(User user, boolean isUserAdmin) {
return new AutoValue_UserAuthInfo(Optional.empty(), Optional.of(user), isUserAdmin);
return new UserAuthInfo(Optional.empty(), Optional.of(user), isUserAdmin);
}
public static UserAuthInfo create(google.registry.model.console.User user) {
return new AutoValue_UserAuthInfo(
Optional.of(user), Optional.empty(), user.getUserRoles().isAdmin());
return new UserAuthInfo(Optional.of(user), Optional.empty(), user.getUserRoles().isAdmin());
}
}

View File

@@ -31,7 +31,6 @@ import javax.annotation.Nullable;
/** Shared base class for commands that create or modify a {@link User}. */
public abstract class CreateOrUpdateUserCommand extends ConfirmingCommand {
@Nullable
@Parameter(names = "--email", description = "Email address of the user", required = true)
String email;
@@ -61,7 +60,7 @@ public abstract class CreateOrUpdateUserCommand extends ConfirmingCommand {
abstract User getExistingUser(String email);
@Override
protected final String execute() throws Exception {
protected String execute() throws Exception {
checkArgumentNotNull(email, "Email must be provided");
tm().transact(this::executeInTransaction);
return String.format("Saved user with email %s", email);

View File

@@ -20,15 +20,27 @@ import com.beust.jcommander.Parameters;
import google.registry.model.console.User;
import google.registry.model.console.UserDao;
import javax.annotation.Nullable;
import javax.inject.Inject;
/** Command to create a new User. */
@Parameters(separators = " =", commandDescription = "Update a user account")
public class CreateUserCommand extends CreateOrUpdateUserCommand {
static final String IAP_SECURED_WEB_APP_USER_ROLE = "roles/iap.httpsResourceAccessor";
@Inject IamClient iamClient;
@Nullable
@Override
User getExistingUser(String email) {
checkArgument(UserDao.loadUser(email).isEmpty(), "A user with email %s already exists", email);
return null;
}
@Override
protected String execute() throws Exception {
String ret = super.execute();
iamClient.addBinding(email, IAP_SECURED_WEB_APP_USER_ROLE);
return ret;
}
}

View File

@@ -15,6 +15,7 @@
package google.registry.tools;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.tools.CreateUserCommand.IAP_SECURED_WEB_APP_USER_ROLE;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
@@ -24,11 +25,14 @@ import google.registry.model.console.User;
import google.registry.model.console.UserDao;
import java.util.Optional;
import javax.annotation.Nullable;
import javax.inject.Inject;
/** Deletes a {@link User}. */
@Parameters(separators = " =", commandDescription = "Delete a user account")
public class DeleteUserCommand extends ConfirmingCommand {
@Inject IamClient iamClient;
@Nullable
@Parameter(names = "--email", description = "Email address of the user", required = true)
String email;
@@ -48,6 +52,7 @@ public class DeleteUserCommand extends ConfirmingCommand {
checkArgumentPresent(optionalUser, "Email no longer corresponds to a valid user");
tm().delete(optionalUser.get());
});
iamClient.removeBinding(email, IAP_SECURED_WEB_APP_USER_ROLE);
return String.format("Deleted user with email %s", email);
}
}

View File

@@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
import com.beust.jcommander.IStringConverter;
import com.google.auto.value.AutoValue;
import com.google.common.base.Ascii;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
@@ -29,18 +28,10 @@ import com.google.template.soy.data.SoyMapData;
import google.registry.flows.domain.DomainFlowUtils;
import java.util.List;
@AutoValue
abstract class DsRecord {
record DsRecord(int keyTag, int alg, int digestType, String digest) {
private static final Splitter SPLITTER = Splitter.on(CharMatcher.whitespace()).omitEmptyStrings();
public abstract int keyTag();
public abstract int alg();
public abstract int digestType();
public abstract String digest();
private static DsRecord create(int keyTag, int alg, int digestType, String digest) {
digest = Ascii.toUpperCase(digest);
checkArgument(
@@ -62,7 +53,7 @@ abstract class DsRecord {
String.format("DS record uses an unrecognized algorithm: %d", alg));
}
return new AutoValue_DsRecord(keyTag, alg, digestType, digest);
return new DsRecord(keyTag, alg, digestType, digest);
}
/**

View File

@@ -0,0 +1,132 @@
// Copyright 2024 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.tools;
import com.google.api.services.cloudresourcemanager.CloudResourceManager;
import com.google.api.services.cloudresourcemanager.model.Binding;
import com.google.api.services.cloudresourcemanager.model.GetIamPolicyRequest;
import com.google.api.services.cloudresourcemanager.model.Policy;
import com.google.api.services.cloudresourcemanager.model.SetIamPolicyRequest;
import com.google.common.base.Ascii;
import google.registry.config.CredentialModule.LocalCredential;
import google.registry.config.RegistryConfig.Config;
import google.registry.util.GoogleCredentialsBundle;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class IamClient {
private static final String MEMBER_FORMAT = "user:%s";
private final CloudResourceManager resourceManager;
private final String projectId;
@Inject
public IamClient(
@LocalCredential GoogleCredentialsBundle credentialsBundle,
@Config("projectId") String projectId) {
this(
new CloudResourceManager.Builder(
credentialsBundle.getHttpTransport(),
credentialsBundle.getJsonFactory(),
credentialsBundle.getHttpRequestInitializer())
.setApplicationName(projectId)
.build(),
projectId);
}
protected IamClient(CloudResourceManager resourceManager, String projectId) {
this.resourceManager = resourceManager;
this.projectId = projectId;
}
/**
* Bind the given role to the account.
*
* <p>No-op if the role is already bound to the account.
*/
public void addBinding(String account, String role) {
String member = String.format(MEMBER_FORMAT, account);
Policy policy = getPolicy();
Binding binding =
policy.getBindings().stream()
.filter(b -> b.getRole().equals(role))
.findFirst()
.orElseGet(
() -> {
Binding newBinding = new Binding().setRole(role).setMembers(new ArrayList<>());
policy.getBindings().add(newBinding);
return newBinding;
});
if (findMember(binding, member).isEmpty()) {
binding.getMembers().add(member);
setPolicy(policy);
}
}
/**
* Remove the given role to the account.
*
* <p>No-op if the role is not bound to the account.
*/
public void removeBinding(String account, String role) {
String member = String.format(MEMBER_FORMAT, account);
Policy policy = getPolicy();
policy.getBindings().stream()
.filter(b -> b.getRole().equals(role))
.findFirst()
.ifPresent(
b ->
findMember(b, member)
.ifPresent(
m -> {
b.getMembers().remove(m);
if (b.getMembers().isEmpty()) {
policy.getBindings().remove(b);
}
setPolicy(policy);
}));
}
protected static Optional<String> findMember(Binding binding, String member) {
return binding.getMembers().stream()
// Standardize email addresses for comparison.
.filter(m -> Ascii.toLowerCase(m).equals(Ascii.toLowerCase(member)))
.findFirst();
}
private Policy getPolicy() {
try {
GetIamPolicyRequest request = new GetIamPolicyRequest();
return resourceManager.projects().getIamPolicy(projectId, request).execute();
} catch (IOException e) {
throw new RuntimeException(String.format("Cannot get policy for project %s", projectId), e);
}
}
private void setPolicy(Policy policy) {
try {
SetIamPolicyRequest request = new SetIamPolicyRequest();
request.setPolicy(policy);
resourceManager.projects().setIamPolicy(projectId, request).execute();
} catch (IOException e) {
throw new RuntimeException(
String.format("Cannot set policy %s for project %s", policy, projectId), e);
}
}
}

View File

@@ -101,6 +101,10 @@ interface RegistryToolComponent {
void inject(CreateRegistrarCommand command);
void inject(CreateUserCommand command);
void inject(DeleteUserCommand command);
void inject(EncryptEscrowDepositCommand command);
void inject(EnqueuePollMessageCommand command);

View File

@@ -16,14 +16,12 @@ package google.registry.tools;
import static com.google.common.base.StandardSystemProperty.USER_HOME;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterDescription;
import com.beust.jcommander.Parameters;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
@@ -32,28 +30,31 @@ import com.google.common.escape.Escaper;
import com.google.common.escape.Escapers;
import google.registry.util.Clock;
import google.registry.util.SystemClock;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import jline.Completor;
import jline.ConsoleReader;
import jline.ConsoleReaderInputStream;
import jline.FileNameCompletor;
import jline.History;
import org.jline.builtins.Completers.FileNameCompleter;
import org.jline.reader.Candidate;
import org.jline.reader.Completer;
import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.ParsedLine;
import org.jline.reader.UserInterruptException;
import org.jline.reader.impl.LineReaderImpl;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import org.jline.terminal.impl.DumbTerminal;
import org.joda.time.DateTime;
import org.joda.time.Duration;
@@ -87,87 +88,64 @@ public class ShellCommand implements Command {
* The runner we received in the constructor.
*
* <p>We might want to update this runner based on flags (e.g. --encapsulate_output), but these
* flags aren't available in the constructor so we have to do it in the {@link #run} function.
* flags aren't available in the constructor, so we have to do it in the {@link #run} function.
*/
private final CommandRunner originalRunner;
private final BufferedReader lineReader;
private final ConsoleReader consoleReader;
private final LineReader lineReader;
private final Clock clock;
private String prompt = null;
@Parameter(
names = {"--dont_exit_on_idle"},
description =
"Prevents the shell from exiting on PROD after the 1 hour idle delay. "
+ "Will instead warn you and require re-running the command.")
"""
Prevents the shell from exiting on PROD after the 1 hour idle delay.
Will instead warn you and require re-running the command.""")
boolean dontExitOnIdle = false;
@Parameter(
names = {"--encapsulate_output"},
description =
"Encapsulate command standard output and error by combining the two streams to standard "
+ "output and inserting a prefix ('out:' or 'err:') at the beginning of every line "
+ "of normal output and adding a line consisting of either 'SUCCESS' or "
+ "'FAILURE <exception-name> <error-message>' at the end of the output for a "
+ "command, allowing the output to be easily parsed by wrapper scripts.")
"""
Encapsulate command standard output and error by combining the two streams to
standard output and inserting a prefix ('out:' or 'err:') at the beginning of every
line of normal output and adding a line consisting of either 'SUCCESS' or
'FAILURE <exception-name> <error-message>' at the end of the output for a
command, allowing the output to be easily parsed by wrapper scripts.""")
boolean encapsulateOutput = false;
public ShellCommand(CommandRunner runner) throws IOException {
this.originalRunner = runner;
InputStream in = System.in;
if (System.console() != null) {
consoleReader = new ConsoleReader();
// There are 104 different commands. We want the threshold to be more than that
consoleReader.setAutoprintThreshhold(200);
consoleReader.setDefaultPrompt("nom > ");
consoleReader.setHistory(new History(new File(USER_HOME.value(), HISTORY_FILE)));
in = new ConsoleReaderInputStream(consoleReader);
} else {
consoleReader = null;
}
this.lineReader = new BufferedReader(new InputStreamReader(in, US_ASCII));
this.clock = new SystemClock();
ShellCommand(CommandRunner runner) throws IOException {
this(TerminalBuilder.terminal(), new SystemClock(), runner);
prompt = "nom > ";
lineReader.variable(LineReader.HISTORY_FILE, Path.of(USER_HOME.value(), HISTORY_FILE));
}
@VisibleForTesting
ShellCommand(BufferedReader bufferedReader, Clock clock, CommandRunner runner) {
ShellCommand(Terminal terminal, Clock clock, CommandRunner runner) {
this.originalRunner = runner;
this.lineReader = bufferedReader;
this.lineReader = LineReaderBuilder.builder().terminal(terminal).build();
this.clock = clock;
this.consoleReader = null;
}
private void setPrompt(RegistryToolEnvironment environment, boolean alert) {
if (consoleReader == null) {
// Do not set the prompt in tests.
if (lineReader.getTerminal() instanceof DumbTerminal) {
return;
}
if (alert) {
consoleReader.setDefaultPrompt(
String.format("nom@%s%s%s > ", ALERT_COLOR, environment, RESET));
} else {
consoleReader.setDefaultPrompt(
String.format(
"nom@%s%s%s > ", NON_ALERT_COLOR, Ascii.toLowerCase(environment.toString()), RESET));
}
prompt =
alert
? String.format("nom@%s%s%s > ", ALERT_COLOR, environment, RESET)
: String.format(
"nom@%s%s%s > ", NON_ALERT_COLOR, Ascii.toLowerCase(environment.toString()), RESET);
}
public ShellCommand buildCompletions(JCommander jcommander) {
if (consoleReader != null) {
@SuppressWarnings("unchecked")
ImmutableList<Completor> completors = ImmutableList.copyOf(consoleReader.getCompletors());
completors
.forEach(consoleReader::removeCompletor);
consoleReader.addCompletor(new JCommanderCompletor(jcommander));
}
((LineReaderImpl) lineReader).setCompleter(new JCommanderCompleter(jcommander));
return this;
}
private static class OutputEncapsulator implements CommandRunner {
private final CommandRunner runner;
private OutputEncapsulator(CommandRunner runner) {
this.runner = runner;
}
private record OutputEncapsulator(CommandRunner runner) implements CommandRunner {
/**
* Emit a success command separator.
@@ -233,26 +211,33 @@ public class ShellCommand implements Command {
// haven't been processed in the constructor.
CommandRunner runner =
encapsulateOutput ? new OutputEncapsulator(originalRunner) : originalRunner;
// On Production we want to be extra careful - to prevent accidental use.
// On Production, we want to be extra careful - to prevent accidental use.
boolean beExtraCareful = (RegistryToolEnvironment.get() == RegistryToolEnvironment.PRODUCTION);
setPrompt(RegistryToolEnvironment.get(), beExtraCareful);
String line;
DateTime lastTime = clock.nowUtc();
while ((line = getLine()) != null) {
while (true) {
try {
line = lineReader.readLine(prompt);
} catch (UserInterruptException | EndOfFileException e) {
break;
}
// Make sure we're not idle for too long. Only relevant when we're "extra careful"
if (!dontExitOnIdle
&& beExtraCareful
&& lastTime.plus(IDLE_THRESHOLD).isBefore(clock.nowUtc())) {
throw new RuntimeException(
"Been idle for too long, while in 'extra careful' mode. "
+ "The last command was saved in history. Please rerun the shell and try again.");
"""
Been idle for too long, while in 'extra careful' mode.
The last command was saved in history. Please rerun the shell and try again.""");
}
lastTime = clock.nowUtc();
String[] lineArgs = parseCommand(line);
if (lineArgs.length == 0) {
continue;
} else if (lineArgs.length == 1 && "exit".equals(lineArgs[0])) {
break;
}
try {
runner.run(lineArgs);
} catch (Exception e) {
@@ -265,14 +250,6 @@ public class ShellCommand implements Command {
}
}
private String getLine() {
try {
return lineReader.readLine();
} catch (IOException e) {
return null;
}
}
@VisibleForTesting
static String[] parseCommand(String line) {
ImmutableList.Builder<String> resultBuilder = new ImmutableList.Builder<>();
@@ -296,10 +273,10 @@ public class ShellCommand implements Command {
return resultBuilder.build().toArray(new String[0]);
}
static class JCommanderCompletor implements Completor {
static class JCommanderCompleter implements Completer {
private static final ParamDoc DEFAULT_PARAM_DOC =
ParamDoc.create("[No documentation available]", ImmutableList.of());
new ParamDoc("[No documentation available]", ImmutableList.of());
/**
* Documentation for all the known command + argument combinations.
@@ -320,7 +297,7 @@ public class ShellCommand implements Command {
*/
private final ImmutableTable<String, String, ParamDoc> commandFlagDocs;
private final FileNameCompletor filenameCompletor = new FileNameCompletor();
private final FileNameCompleter filenameCompleter = new FileNameCompleter();
/**
* Holds all the information about a parameter we need for completion.
@@ -332,15 +309,11 @@ public class ShellCommand implements Command {
*
* <p>For now - "all possible options" are only known for enum parameters.
*/
@AutoValue
abstract static class ParamDoc {
abstract String documentation();
abstract ImmutableList<String> options();
record ParamDoc(String documentation, ImmutableList<String> options) {
static ParamDoc create(@Nullable ParameterDescription parameter) {
if (parameter == null) {
return create("[None]", ImmutableList.of());
return new ParamDoc("[None]", ImmutableList.of());
}
String type = parameter.getParameterized().getGenericType().toString();
Class<?> clazz = parameter.getParameterized().getType();
@@ -350,31 +323,22 @@ public class ShellCommand implements Command {
Arrays.stream(clazz.getEnumConstants())
.map(Object::toString)
.collect(toImmutableList());
type = options.stream().collect(Collectors.joining(", "));
type = String.join(", ", options);
}
if (type.startsWith("class ")) {
type = type.substring(6);
}
return create(
String.format(
"%s\n (%s)",
parameter.getDescription(),
type),
options);
}
static ParamDoc create(String documentation, ImmutableList<String> options) {
return new AutoValue_ShellCommand_JCommanderCompletor_ParamDoc(documentation, options);
return new ParamDoc(String.format("%s\n (%s)", parameter.getDescription(), type), options);
}
}
/**
* Populates the completions and documentation based on the JCommander.
*
* The input data is copied, so changing the jcommander after creation of the
* JCommanderCompletor doesn't change the completions.
* <p>The input data is copied, so changing the jcommander after creation of the
* JCommanderCompleter doesn't change the completions.
*/
JCommanderCompletor(JCommander jcommander) {
JCommanderCompleter(JCommander jcommander) {
ImmutableTable.Builder<String, String, ParamDoc> builder = new ImmutableTable.Builder<>();
// Go over all the commands
@@ -383,7 +347,13 @@ public class ShellCommand implements Command {
JCommander subCommander = entry.getValue();
// Add the "main" parameters documentation
builder.put(command, "", ParamDoc.create(subCommander.getMainParameter()));
builder.put(
command,
"",
ParamDoc.create(
subCommander.getMainParameter() == null
? null
: subCommander.getMainParameterValue()));
// For each command - go over the parameters (arguments / flags)
for (ParameterDescription parameter : subCommander.getParameters()) {
@@ -399,53 +369,26 @@ public class ShellCommand implements Command {
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public int complete(String buffer, int location, List completions) {
// We just defer to the other function because of the warnings (the use of a naked List by
// jline)
return completeInternal(buffer, location, completions);
}
/**
* Given a string, finds all the possible completions to the end of that string.
*
* @param buffer the command line.
* @param location the location in the command line we want to complete
* @param completions a list to fill with the completion results
* @return the number of character back from the location that are part of the completions
*/
int completeInternal(String buffer, int location, List<String> completions) {
String truncatedBuffer = buffer.substring(0, location);
String[] parsedBuffer = parseCommand(truncatedBuffer);
int argumentIndex = parsedBuffer.length - 1;
if (argumentIndex < 0 || !truncatedBuffer.endsWith(parsedBuffer[argumentIndex])) {
argumentIndex += 1;
}
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
int argumentIndex = line.wordIndex();
// The argument we want to complete (only partially written, might even be empty)
String partialArgument =
argumentIndex < parsedBuffer.length ? parsedBuffer[argumentIndex] : "";
int argumentStart = location - partialArgument.length();
String partialArgument = line.word();
// The command name. Null if we're at the first argument
String command = argumentIndex == 0 ? null : parsedBuffer[0];
String command = argumentIndex == 0 ? null : line.words().getFirst();
// The previous argument before it - used for context. Null if we're at the first argument
String previousArgument = argumentIndex <= 1 ? null : parsedBuffer[argumentIndex - 1];
String previousArgument = argumentIndex <= 1 ? null : line.words().get(argumentIndex - 1);
// If it's obviously a file path (starts with something "file path like") - complete as a file
if (partialArgument.startsWith("./")
|| partialArgument.startsWith("~/")
|| partialArgument.startsWith("/")) {
int offset =
filenameCompletor.complete(partialArgument, partialArgument.length(), completions);
if (offset >= 0) {
return argumentStart + offset;
}
return -1;
filenameCompleter.complete(reader, line, candidates);
}
// Complete based on flag data
completions.addAll(getCompletions(command, previousArgument, partialArgument));
return argumentStart;
getCompletions(command, previousArgument, partialArgument).stream()
.map(Candidate::new)
.forEach(candidates::add);
}
/**
@@ -453,7 +396,7 @@ public class ShellCommand implements Command {
*
* @param command the name of the command we're running. Null if not yet known (it is in 'word')
* @param context the previous argument for context. Null if we're the first.
* @param word the (partial) word to complete. Can be the command, if "command" is null, or any
* @param word the (partial) word to complete. Can be the command if "command" is null, or any
* "regular" argument, if "command" isn't null.
* @return list of all possible completions to 'word'
*/
@@ -488,19 +431,14 @@ public class ShellCommand implements Command {
}
private List<String> getCommandCompletions(String word) {
return commandFlagDocs
.rowKeySet()
.stream()
return commandFlagDocs.rowKeySet().stream()
.filter(s -> s.startsWith(word))
.map(s -> s + " ")
.collect(toImmutableList());
}
private List<String> getFlagCompletions(String command, String word) {
return commandFlagDocs
.row(command)
.keySet()
.stream()
return commandFlagDocs.row(command).keySet().stream()
.filter(s -> s.startsWith(word))
.map(s -> s + " ")
.collect(toImmutableList());
@@ -513,19 +451,15 @@ public class ShellCommand implements Command {
//
// We want documentation for a flag if the previous argument was a flag, but the value of the
// flag wasn't set. So if the previous argument is "--flag" then we want documentation of that
// flag, but if it's "--flag=value" then that flag is set and we want documentation of the
// flag, but if it's "--flag=value" then that flag is set, and we want documentation of the
// main parameters.
boolean isFlagParameter =
context != null
&& context.startsWith("-")
&& context.indexOf('=') == -1;
context != null && context.startsWith("-") && context.indexOf('=') == -1;
ParamDoc paramDoc =
Optional.ofNullable(commandFlagDocs.get(command, isFlagParameter ? context : ""))
.orElse(DEFAULT_PARAM_DOC);
if (!word.isEmpty()) {
return paramDoc
.options()
.stream()
return paramDoc.options().stream()
.filter(s -> s.startsWith(word))
.map(s -> s + " ")
.collect(toImmutableList());
@@ -548,10 +482,6 @@ public class ShellCommand implements Command {
private final byte[] prefix;
private final ByteArrayOutputStream lastLine = new ByteArrayOutputStream();
// Flag to keep track of whether the last character written was a newline. We initialize this
// to "true" because we always want the first line of output to be escaped with a leading space.
boolean lastWasNewline = true;
EncapsulatingOutputStream(OutputStream out, String identifier) {
super(out);
this.prefix = identifier.getBytes(UTF_8);
@@ -581,7 +511,7 @@ public class ShellCommand implements Command {
// (System.out)
}
/** Dump the accumulated last line of output, if there was one. */
/** Dump the accumulated last line of output if there was one. */
public void dumpLastLine() throws IOException {
if (lastLine.size() > 0) {
out.write(prefix);

View File

@@ -35,9 +35,8 @@ public final class ParameterFactory implements IStringConverterFactory {
/** Returns JCommander converter for a given type, or {@code null} if none exists. */
@Nullable
@Override
@SuppressWarnings("unchecked")
public <T> Class<? extends IStringConverter<T>> getConverter(@Nullable Class<T> type) {
return (Class<? extends IStringConverter<T>>) CONVERTERS.get(type);
public Class<? extends IStringConverter<?>> getConverter(@Nullable Class<?> type) {
return CONVERTERS.get(type);
}
private static final ImmutableMap<Class<?>, Class<? extends IStringConverter<?>>> CONVERTERS =
@@ -53,4 +52,6 @@ public final class ParameterFactory implements IStringConverterFactory {
.put(Path.class, PathParameter.class)
.put(YearMonth.class, YearMonthParameter.class)
.build();
}

View File

@@ -49,6 +49,7 @@ public abstract class ConsoleApiAction implements Runnable {
}
}
protected void postHandler(User user) {
throw new UnsupportedOperationException("Console API POST handler not implemented");
}
@@ -57,6 +58,11 @@ public abstract class ConsoleApiAction implements Runnable {
throw new UnsupportedOperationException("Console API GET handler not implemented");
}
protected void setFailedResponse(String message, int code) {
consoleApiParams.response().setStatus(code);
consoleApiParams.response().setPayload(message);
}
private boolean verifyXSRF() {
Optional<Cookie> maybeCookie =
Arrays.stream(consoleApiParams.request().getCookies())

View File

@@ -0,0 +1,128 @@
// Copyright 2024 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.collect.ImmutableList.toImmutableList;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.GET;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableList;
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.User;
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.auth.Auth;
import google.registry.ui.server.registrar.ConsoleApiParams;
import google.registry.util.Clock;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.joda.time.DateTime;
@Action(
service = Action.Service.DEFAULT,
path = ConsoleDumDownloadAction.PATH,
method = {GET},
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
public class ConsoleDumDownloadAction extends ConsoleApiAction {
private static final String SQL_TEMPLATE =
"""
SELECT CONCAT(
d.domain_name,',',d.creation_time,',',d.registration_expiration_time,',',d.statuses
) AS result FROM "Domain" d
WHERE d.current_sponsor_registrar_id = :registrarId
AND d.deletion_time > ':now'
AND d.creation_time <= ':now';
""";
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
public static final String PATH = "/console-api/dum-download";
private Clock clock;
private final String registrarId;
private final String dumFileName;
@Inject
public ConsoleDumDownloadAction(
Clock clock,
ConsoleApiParams consoleApiParams,
@Parameter("registrarId") String registrarId,
@Config("dumFileName") String dumFileName) {
super(consoleApiParams);
this.registrarId = registrarId;
this.clock = clock;
this.dumFileName = dumFileName;
}
@Override
protected void getHandler(User user) {
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.DOWNLOAD_DOMAINS)) {
consoleApiParams.response().setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
consoleApiParams.response().setContentType(MediaType.CSV_UTF_8);
consoleApiParams
.response()
.setHeader(
"Content-Disposition", String.format("attachment; filename=%s.csv", dumFileName));
consoleApiParams
.response()
.setHeader("Cache-Control", "max-age=86400"); // 86400 seconds = 1 day
consoleApiParams
.response()
.setDateHeader("Expires", DateTime.now(UTC).withTimeAtStartOfDay().plusDays(1));
try (var writer = consoleApiParams.response().getWriter()) {
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT);
writeCsv(csvPrinter);
} catch (IOException e) {
logger.atWarning().withCause(e).log(
String.format("Failed to create DUM csv for %s", registrarId));
consoleApiParams.response().setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
consoleApiParams.response().setStatus(HttpServletResponse.SC_OK);
}
private void writeCsv(CSVPrinter printer) throws IOException {
String sql = SQL_TEMPLATE.replaceAll(":now", clock.nowUtc().toString());
// We deliberately don't want to use ImmutableList.copyOf because underlying list may contain
// large amount of records and that will degrade performance.
List<String> queryResult =
tm().transact(
() ->
tm().getEntityManager()
.createNativeQuery(sql)
.setParameter("registrarId", registrarId)
.setHint("org.hibernate.fetchSize", 1000)
.getResultList());
ImmutableList<String[]> formattedRecords =
queryResult.stream().map(r -> r.split(",")).collect(toImmutableList());
printer.printRecord(
ImmutableList.of("Domain Name", "Creation Time", "Expiration Time", "Domain Statuses"));
printer.printRecords(formattedRecords);
}
}

View File

@@ -0,0 +1,126 @@
// Copyright 2024 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 google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.POST;
import static google.registry.request.RequestParameters.extractRequiredParameter;
import com.google.api.client.http.HttpStatusCodes;
import com.google.common.base.Throwables;
import com.google.common.flogger.FluentLogger;
import google.registry.flows.EppException.AuthenticationErrorException;
import google.registry.flows.PasswordOnlyTransportCredentials;
import google.registry.groups.GmailClient;
import google.registry.model.console.User;
import google.registry.model.registrar.Registrar;
import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.auth.Auth;
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
import google.registry.ui.server.registrar.ConsoleApiParams;
import google.registry.util.EmailMessage;
import java.util.Optional;
import javax.inject.Inject;
import javax.mail.internet.InternetAddress;
@Action(
service = Action.Service.DEFAULT,
path = ConsoleEppPasswordAction.PATH,
method = {POST},
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
public class ConsoleEppPasswordAction extends ConsoleApiAction {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
protected static final String EMAIL_SUBJ = "EPP password update confirmation";
protected static final String EMAIL_BODY =
"Dear %s,\n" + "This is to confirm that your account password has been changed.";
public static final String PATH = "/console-api/eppPassword";
private final PasswordOnlyTransportCredentials credentials =
new PasswordOnlyTransportCredentials();
private final AuthenticatedRegistrarAccessor registrarAccessor;
private final GmailClient gmailClient;
@Inject
public ConsoleEppPasswordAction(
ConsoleApiParams consoleApiParams,
AuthenticatedRegistrarAccessor registrarAccessor,
GmailClient gmailClient) {
super(consoleApiParams);
this.registrarAccessor = registrarAccessor;
this.gmailClient = gmailClient;
}
@Override
protected void postHandler(User user) {
String registrarId;
String oldPassword;
String newPassword;
String newPasswordRepeat;
try {
registrarId = extractRequiredParameter(consoleApiParams.request(), "registrarId");
oldPassword = extractRequiredParameter(consoleApiParams.request(), "oldPassword");
newPassword = extractRequiredParameter(consoleApiParams.request(), "newPassword");
newPasswordRepeat = extractRequiredParameter(consoleApiParams.request(), "newPasswordRepeat");
} catch (BadRequestException e) {
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
return;
}
if (!newPassword.equals(newPasswordRepeat)) {
setFailedResponse("New password fields don't match", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
return;
}
Registrar registrar;
try {
registrar = registrarAccessor.getRegistrar(registrarId);
} catch (RegistrarAccessDeniedException e) {
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_NOT_FOUND);
return;
}
try {
credentials.validate(registrar, oldPassword);
} catch (AuthenticationErrorException e) {
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_FORBIDDEN);
return;
}
try {
tm().transact(
() -> {
tm().put(registrar.asBuilder().setPassword(newPassword).build());
this.gmailClient.sendEmail(
EmailMessage.create(
EMAIL_SUBJ,
String.format(EMAIL_BODY, registrar.getRegistrarName()),
new InternetAddress(registrar.getEmailAddress(), true)));
});
} catch (Throwable e) {
logger.atWarning().withCause(e).log("Failed to update password.");
String message =
Optional.ofNullable(Throwables.getRootCause(e).getMessage()).orElse("Unspecified error");
setFailedResponse(message, HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
}
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
}
}

View File

@@ -14,28 +14,22 @@
package google.registry.ui.server.registrar;
import com.google.auto.value.AutoValue;
import google.registry.request.Response;
import google.registry.request.auth.AuthResult;
import google.registry.security.XsrfTokenManager;
import jakarta.servlet.http.HttpServletRequest;
/** Groups necessary dependencies for Console API actions * */
@AutoValue
public abstract class ConsoleApiParams {
public record ConsoleApiParams(
HttpServletRequest request,
Response response,
AuthResult authResult,
XsrfTokenManager xsrfTokenManager) {
public static ConsoleApiParams create(
HttpServletRequest request,
Response response,
AuthResult authResult,
XsrfTokenManager xsrfTokenManager) {
return new AutoValue_ConsoleApiParams(request, response, authResult, xsrfTokenManager);
return new ConsoleApiParams(request, response, authResult, xsrfTokenManager);
}
public abstract HttpServletRequest request();
public abstract Response response();
public abstract AuthResult authResult();
public abstract XsrfTokenManager xsrfTokenManager();
}

View File

@@ -24,7 +24,6 @@ import static google.registry.security.JsonResponseHelper.Status.SUCCESS;
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
import static google.registry.util.RegistryEnvironment.PRODUCTION;
import com.google.auto.value.AutoValue;
import com.google.common.base.Ascii;
import com.google.common.base.Strings;
import com.google.common.collect.HashMultimap;
@@ -180,38 +179,29 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
}
}
@AutoValue
abstract static class RegistrarResult {
abstract String message();
abstract Registrar registrar();
record RegistrarResult(String message, Registrar registrar) {
Map<String, Object> toJsonResponse() {
return JsonResponseHelper.create(SUCCESS, message(), registrar().toJsonMap());
}
static RegistrarResult create(String message, Registrar registrar) {
return new AutoValue_RegistrarSettingsAction_RegistrarResult(message, registrar);
return new RegistrarResult(message, registrar);
}
}
@AutoValue
abstract static class EmailInfo {
abstract Registrar registrar();
abstract Registrar updatedRegistrar();
abstract ImmutableSet<RegistrarPoc> contacts();
abstract ImmutableSet<RegistrarPoc> updatedContacts();
record EmailInfo(
Registrar registrar,
Registrar updatedRegistrar,
ImmutableSet<RegistrarPoc> contacts,
ImmutableSet<RegistrarPoc> updatedContacts) {
static EmailInfo create(
Registrar registrar,
Registrar updatedRegistrar,
ImmutableSet<RegistrarPoc> contacts,
ImmutableSet<RegistrarPoc> updatedContacts) {
return new AutoValue_RegistrarSettingsAction_EmailInfo(
registrar, updatedRegistrar, contacts, updatedContacts);
return new EmailInfo(registrar, updatedRegistrar, contacts, updatedContacts);
}
}

View File

@@ -23,7 +23,6 @@ import static google.registry.model.tld.Tlds.getTlds;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Verify;
import com.google.common.net.InternetDomainName;
@@ -100,12 +99,8 @@ public class DomainLookupCommand implements WhoisCommand {
domain -> new DomainWhoisResponse(domain, fullOutput, whoisRedactedEmailText, now));
}
@AutoValue
abstract static class ResponseOrException {
abstract Optional<WhoisResponse> whoisResponse();
abstract Optional<WhoisException> exception();
record ResponseOrException(
Optional<WhoisResponse> whoisResponse, Optional<WhoisException> exception) {
WhoisResponse returnOrThrow() throws WhoisException {
Verify.verify(
@@ -115,13 +110,11 @@ public class DomainLookupCommand implements WhoisCommand {
}
static ResponseOrException of(WhoisResponse response) {
return new AutoValue_DomainLookupCommand_ResponseOrException(
Optional.of(response), Optional.empty());
return new ResponseOrException(Optional.of(response), Optional.empty());
}
static ResponseOrException of(WhoisException exception) {
return new AutoValue_DomainLookupCommand_ResponseOrException(
Optional.empty(), Optional.of(exception));
return new ResponseOrException(Optional.empty(), Optional.of(exception));
}
}
}

View File

@@ -17,7 +17,7 @@ package google.registry.whois;
import static com.google.common.base.Preconditions.checkState;
import static com.google.monitoring.metrics.EventMetric.DEFAULT_FITTER;
import com.google.auto.value.AutoValue;
import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableSet;
import com.google.monitoring.metrics.EventMetric;
import com.google.monitoring.metrics.IncrementableMetric;
@@ -73,18 +73,12 @@ public class WhoisMetrics {
}
/** A value class for recording attributes of a WHOIS metric. */
@AutoValue
public abstract static class WhoisMetric {
public abstract Optional<String> commandName();
public abstract int numResults();
public abstract int status();
public abstract DateTime startTimestamp();
public abstract DateTime endTimestamp();
public record WhoisMetric(
Optional<String> commandName,
int numResults,
int status,
DateTime startTimestamp,
DateTime endTimestamp) {
/**
* Create a {@link WhoisMetric.Builder} for a request context, with the start and end timestamps
@@ -98,11 +92,11 @@ public class WhoisMetrics {
/** Create a {@link WhoisMetric.Builder}. */
public static Builder builder() {
return new AutoValue_WhoisMetrics_WhoisMetric.Builder();
return new AutoBuilder_WhoisMetrics_WhoisMetric_Builder();
}
/** A builder to create instances of {@link WhoisMetric}. */
@AutoValue.Builder
@AutoBuilder
public abstract static class Builder {
boolean wasBuilt = false;

View File

@@ -14,7 +14,6 @@
package google.registry.whois;
import com.google.auto.value.AutoValue;
import org.joda.time.DateTime;
/** Representation of a WHOIS query response. */
@@ -36,13 +35,10 @@ public interface WhoisResponse {
DateTime getTimestamp();
/** A wrapper class for the plaintext response of a WHOIS command and its number of results. */
@AutoValue
abstract class WhoisResponseResults {
public abstract String plainTextOutput();
public abstract int numResults();
record WhoisResponseResults(String plainTextOutput, int numResults) {
static WhoisResponseResults create(String plainTextOutput, int numResults) {
return new AutoValue_WhoisResponse_WhoisResponseResults(plainTextOutput, numResults);
return new WhoisResponseResults(plainTextOutput, numResults);
}
}
}

View File

@@ -72,15 +72,15 @@ class BsaDiffCreatorTest {
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels())
.containsExactly(
BlockLabel.of("test1", LabelType.CREATE, ImmutableSet.of("JA")),
BlockLabel.of("test2", LabelType.CREATE, ImmutableSet.of("JA")),
BlockLabel.of("test3", LabelType.CREATE, ImmutableSet.of("JA")));
BlockLabel.create("test1", LabelType.CREATE, ImmutableSet.of("JA")),
BlockLabel.create("test2", LabelType.CREATE, ImmutableSet.of("JA")),
BlockLabel.create("test3", LabelType.CREATE, ImmutableSet.of("JA")));
assertThat(diff.getOrders())
.containsExactly(
BlockOrder.of(1, OrderType.CREATE),
BlockOrder.of(2, OrderType.CREATE),
BlockOrder.of(3, OrderType.CREATE),
BlockOrder.of(4, OrderType.CREATE));
BlockOrder.create(1, OrderType.CREATE),
BlockOrder.create(2, OrderType.CREATE),
BlockOrder.create(3, OrderType.CREATE),
BlockOrder.create(4, OrderType.CREATE));
}
@Test
@@ -96,16 +96,16 @@ class BsaDiffCreatorTest {
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels())
.containsExactly(
BlockLabel.of("test1", LabelType.CREATE, ImmutableSet.of("JA")),
BlockLabel.of("test2", LabelType.CREATE, ImmutableSet.of("JA")),
BlockLabel.of("test3", LabelType.CREATE, ImmutableSet.of("JA")));
BlockLabel.create("test1", LabelType.CREATE, ImmutableSet.of("JA")),
BlockLabel.create("test2", LabelType.CREATE, ImmutableSet.of("JA")),
BlockLabel.create("test3", LabelType.CREATE, ImmutableSet.of("JA")));
assertThat(diff.getOrders())
.containsExactly(
BlockOrder.of(1, OrderType.CREATE),
BlockOrder.of(2, OrderType.CREATE),
BlockOrder.of(3, OrderType.CREATE),
BlockOrder.of(4, OrderType.CREATE),
BlockOrder.of(5, OrderType.CREATE));
BlockOrder.create(1, OrderType.CREATE),
BlockOrder.create(2, OrderType.CREATE),
BlockOrder.create(3, OrderType.CREATE),
BlockOrder.create(4, OrderType.CREATE),
BlockOrder.create(5, OrderType.CREATE));
}
@Test
@@ -140,15 +140,15 @@ class BsaDiffCreatorTest {
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels())
.containsExactly(
BlockLabel.of("test1", LabelType.DELETE, ImmutableSet.of("JA")),
BlockLabel.of("test2", LabelType.DELETE, ImmutableSet.of("JA")),
BlockLabel.of("test3", LabelType.DELETE, ImmutableSet.of("JA")));
BlockLabel.create("test1", LabelType.DELETE, ImmutableSet.of("JA")),
BlockLabel.create("test2", LabelType.DELETE, ImmutableSet.of("JA")),
BlockLabel.create("test3", LabelType.DELETE, ImmutableSet.of("JA")));
assertThat(diff.getOrders())
.containsExactly(
BlockOrder.of(1, OrderType.DELETE),
BlockOrder.of(2, OrderType.DELETE),
BlockOrder.of(3, OrderType.DELETE),
BlockOrder.of(4, OrderType.DELETE));
BlockOrder.create(1, OrderType.DELETE),
BlockOrder.create(2, OrderType.DELETE),
BlockOrder.create(3, OrderType.DELETE),
BlockOrder.create(4, OrderType.DELETE));
}
@Test
@@ -167,8 +167,8 @@ class BsaDiffCreatorTest {
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels())
.containsExactly(
BlockLabel.of("test1", LabelType.NEW_ORDER_ASSOCIATION, ImmutableSet.of("JA")));
assertThat(diff.getOrders()).containsExactly(BlockOrder.of(5, OrderType.CREATE));
BlockLabel.create("test1", LabelType.NEW_ORDER_ASSOCIATION, ImmutableSet.of("JA")));
assertThat(diff.getOrders()).containsExactly(BlockOrder.create(5, OrderType.CREATE));
}
@Test
@@ -187,8 +187,8 @@ class BsaDiffCreatorTest {
when(schedule.latestCompleted()).thenReturn(Optional.of(completedJob));
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels())
.containsExactly(BlockLabel.of("test4", LabelType.CREATE, ImmutableSet.of("JA")));
assertThat(diff.getOrders()).containsExactly(BlockOrder.of(5, OrderType.CREATE));
.containsExactly(BlockLabel.create("test4", LabelType.CREATE, ImmutableSet.of("JA")));
assertThat(diff.getOrders()).containsExactly(BlockOrder.create(5, OrderType.CREATE));
}
@Test
@@ -205,7 +205,7 @@ class BsaDiffCreatorTest {
when(schedule.latestCompleted()).thenReturn(Optional.of(completedJob));
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels()).isEmpty();
assertThat(diff.getOrders()).containsExactly(BlockOrder.of(4, OrderType.DELETE));
assertThat(diff.getOrders()).containsExactly(BlockOrder.create(4, OrderType.DELETE));
}
@Test
@@ -222,7 +222,7 @@ class BsaDiffCreatorTest {
when(schedule.latestCompleted()).thenReturn(Optional.of(completedJob));
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels()).isEmpty();
assertThat(diff.getOrders()).containsExactly(BlockOrder.of(1, OrderType.DELETE));
assertThat(diff.getOrders()).containsExactly(BlockOrder.create(1, OrderType.DELETE));
}
@Test
@@ -240,8 +240,8 @@ class BsaDiffCreatorTest {
when(schedule.latestCompleted()).thenReturn(Optional.of(completedJob));
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels())
.containsExactly(BlockLabel.of("test2", LabelType.DELETE, ImmutableSet.of("JA")));
assertThat(diff.getOrders()).containsExactly(BlockOrder.of(3, OrderType.DELETE));
.containsExactly(BlockLabel.create("test2", LabelType.DELETE, ImmutableSet.of("JA")));
assertThat(diff.getOrders()).containsExactly(BlockOrder.create(3, OrderType.DELETE));
}
@Test
@@ -260,13 +260,13 @@ class BsaDiffCreatorTest {
BsaDiff diff = diffCreator.createDiff(schedule, idnChecker);
assertThat(diff.getLabels())
.containsExactly(
BlockLabel.of("test1", LabelType.DELETE, ImmutableSet.of("JA")),
BlockLabel.of("test3", LabelType.DELETE, ImmutableSet.of("JA")));
BlockLabel.create("test1", LabelType.DELETE, ImmutableSet.of("JA")),
BlockLabel.create("test3", LabelType.DELETE, ImmutableSet.of("JA")));
assertThat(diff.getOrders())
.containsExactly(
BlockOrder.of(1, OrderType.DELETE),
BlockOrder.of(2, OrderType.DELETE),
BlockOrder.of(4, OrderType.DELETE));
BlockOrder.create(1, OrderType.DELETE),
BlockOrder.create(2, OrderType.DELETE),
BlockOrder.create(4, OrderType.DELETE));
}
@Test

View File

@@ -144,7 +144,7 @@ class BsaRefreshFunctionalTest {
UnblockableDomain newUnblockable = new UnblockableDomain("blocked1.app", Reason.RESERVED);
assertThat(queryUnblockableDomains()).containsExactly(newUnblockable);
assertThat(gcsClient.readRefreshChanges(jobName))
.containsExactly(UnblockableDomainChange.ofNew(newUnblockable));
.containsExactly(UnblockableDomainChange.createNew(newUnblockable));
verify(bsaReportSender, never()).removeUnblockableDomainsUpdates(anyString());
verify(bsaReportSender, times(1))
.addUnblockableDomainsUpdates("{\n \"reserved\": [\n \"blocked1.app\"\n ]\n}");
@@ -161,7 +161,7 @@ class BsaRefreshFunctionalTest {
UnblockableDomain newUnblockable = new UnblockableDomain("blocked1.dev", Reason.REGISTERED);
assertThat(queryUnblockableDomains()).containsExactly(newUnblockable);
assertThat(gcsClient.readRefreshChanges(jobName))
.containsExactly(UnblockableDomainChange.ofNew(newUnblockable));
.containsExactly(UnblockableDomainChange.createNew(newUnblockable));
verify(bsaReportSender, never()).removeUnblockableDomainsUpdates(anyString());
verify(bsaReportSender, times(1))
@@ -184,7 +184,7 @@ class BsaRefreshFunctionalTest {
assertThat(queryUnblockableDomains()).isEmpty();
assertThat(gcsClient.readRefreshChanges(jobName))
.containsExactly(
UnblockableDomainChange.ofDeleted(
UnblockableDomainChange.createDeleted(
new UnblockableDomain("blocked1.dev", Reason.REGISTERED)));
verify(bsaReportSender, never()).addUnblockableDomainsUpdates(anyString());
@@ -207,7 +207,7 @@ class BsaRefreshFunctionalTest {
assertThat(queryUnblockableDomains()).isEmpty();
assertThat(gcsClient.readRefreshChanges(jobName))
.containsExactly(
UnblockableDomainChange.ofDeleted(
UnblockableDomainChange.createDeleted(
new UnblockableDomain("blocked1.app", Reason.RESERVED)));
verify(bsaReportSender, never()).addUnblockableDomainsUpdates(anyString());
@@ -233,7 +233,7 @@ class BsaRefreshFunctionalTest {
.containsExactly(new UnblockableDomain("blocked1.app", Reason.RESERVED));
assertThat(gcsClient.readRefreshChanges(jobName))
.containsExactly(
UnblockableDomainChange.ofChanged(
UnblockableDomainChange.createChanged(
new UnblockableDomain("blocked1.app", Reason.REGISTERED), Reason.RESERVED));
InOrder inOrder = Mockito.inOrder(bsaReportSender);
inOrder.verify(bsaReportSender).removeUnblockableDomainsUpdates("[\n \"blocked1.app\"\n]");
@@ -260,7 +260,7 @@ class BsaRefreshFunctionalTest {
assertThat(queryUnblockableDomains()).containsExactly(changed);
assertThat(gcsClient.readRefreshChanges(jobName))
.containsExactly(
UnblockableDomainChange.ofChanged(
UnblockableDomainChange.createChanged(
new UnblockableDomain("blocked1.app", Reason.RESERVED), Reason.REGISTERED));
InOrder inOrder = Mockito.inOrder(bsaReportSender);
inOrder.verify(bsaReportSender).removeUnblockableDomainsUpdates("[\n \"blocked1.app\"\n]");
@@ -279,7 +279,7 @@ class BsaRefreshFunctionalTest {
UnblockableDomain newUnblockable = new UnblockableDomain("blocked1.app", Reason.REGISTERED);
assertThat(queryUnblockableDomains()).containsExactly(newUnblockable);
assertThat(gcsClient.readRefreshChanges(jobName))
.containsExactly(UnblockableDomainChange.ofNew(newUnblockable));
.containsExactly(UnblockableDomainChange.createNew(newUnblockable));
}
@Test

View File

@@ -31,6 +31,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.startsWith;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -56,7 +57,6 @@ import google.registry.testing.FakeClock;
import google.registry.tldconfig.idn.IdnTableEnum;
import google.registry.util.EmailMessage;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.stream.Stream;
import javax.mail.internet.InternetAddress;
import org.joda.time.DateTime;
@@ -90,8 +90,6 @@ public class BsaValidateActionTest {
@Mock Response response;
@Mock private BsaLock bsaLock;
@Mock private InternetAddress emailRecipient;
@Captor ArgumentCaptor<EmailMessage> emailCaptor = ArgumentCaptor.forClass(EmailMessage.class);
@@ -112,7 +110,6 @@ public class BsaValidateActionTest {
/* transactionBatchSize= */ 500,
MAX_STALENESS,
fakeClock,
bsaLock,
response);
createTld("app");
}
@@ -340,6 +337,21 @@ public class BsaValidateActionTest {
.containsExactly("Missing unblockable domain: reserved-missing-in-app.app is reserved.");
}
@Test
void checkForMissingReservedUnblockables_unblockedReservedNotReported() {
persistResource(
createTld("app").asBuilder().setBsaEnrollStartTime(Optional.of(START_OF_TIME)).build());
createReservedList(
"rl",
Stream.of("reserved-only")
.collect(toImmutableMap(x -> x, x -> ReservationType.RESERVED_FOR_SPECIFIC_USE)));
addReservedListsToTld("app", ImmutableList.of("rl"));
ImmutableList<String> errors = action.checkForMissingReservedUnblockables(fakeClock.nowUtc());
assertThat(errors).isEmpty();
}
@Test
void checkForMissingRegisteredUnblockables_success() {
persistResource(
@@ -357,22 +369,11 @@ public class BsaValidateActionTest {
"Registered domain registered-missing.app missing or not recorded as REGISTERED");
}
@Test
void notificationSent_cannotAcquireLock() {
when(bsaLock.executeWithLock(any())).thenReturn(false);
action.run();
verify(gmailClient, times(1))
.sendEmail(
EmailMessage.create(
"BSA validation did not run: another BSA related task is running",
"",
emailRecipient));
}
@Test
void notificationSent_abortedByException() {
action = spy(action);
RuntimeException throwable = new RuntimeException("Error");
when(bsaLock.executeWithLock(any())).thenThrow(throwable);
doThrow(throwable).when(action).validate();
action.run();
verify(gmailClient, times(1))
.sendEmail(
@@ -382,12 +383,6 @@ public class BsaValidateActionTest {
@Test
void notificationSent_noDownloads() {
when(bsaLock.executeWithLock(any()))
.thenAnswer(
args -> {
args.getArgument(0, Callable.class).call();
return true;
});
action.run();
verify(gmailClient, times(1))
.sendEmail(
@@ -397,12 +392,6 @@ public class BsaValidateActionTest {
@Test
void notificationSent_withValidationError() {
when(bsaLock.executeWithLock(any()))
.thenAnswer(
args -> {
args.getArgument(0, Callable.class).call();
return true;
});
persistDownloadSchedule(DownloadStage.DONE);
action = spy(action);
doReturn(ImmutableList.of("Error line 1.", "Error line 2"))
@@ -420,12 +409,6 @@ public class BsaValidateActionTest {
@Test
void notification_notSent_WhenNoError() {
when(bsaLock.executeWithLock(any()))
.thenAnswer(
args -> {
args.getArgument(0, Callable.class).call();
return true;
});
persistDownloadSchedule(DownloadStage.DONE);
action = spy(action);
doReturn(ImmutableList.of()).when(action).checkBsaLabels(anyString());

View File

@@ -79,7 +79,8 @@ class GcsClientTest {
@Test
void readWriteOrderDiffs_success() throws Exception {
ImmutableList<BlockOrder> orders =
ImmutableList.of(BlockOrder.of(1, OrderType.CREATE), BlockOrder.of(2, OrderType.DELETE));
ImmutableList.of(
BlockOrder.create(1, OrderType.CREATE), BlockOrder.create(2, OrderType.DELETE));
gcsClient.writeOrderDiffs("job", orders.stream());
assertThat(gcsClient.readOrderDiffs("job")).containsExactlyElementsIn(orders);
}
@@ -88,9 +89,9 @@ class GcsClientTest {
void readWriteLabelDiffs_success() throws Exception {
ImmutableList<BlockLabel> labels =
ImmutableList.of(
BlockLabel.of("1", LabelType.CREATE.CREATE, ImmutableSet.of()),
BlockLabel.of("2", LabelType.NEW_ORDER_ASSOCIATION, ImmutableSet.of("JA")),
BlockLabel.of("3", LabelType.DELETE, ImmutableSet.of("JA", "EXTENDED_LATIN")));
BlockLabel.create("1", LabelType.CREATE.CREATE, ImmutableSet.of()),
BlockLabel.create("2", LabelType.NEW_ORDER_ASSOCIATION, ImmutableSet.of("JA")),
BlockLabel.create("3", LabelType.DELETE, ImmutableSet.of("JA", "EXTENDED_LATIN")));
gcsClient.writeLabelDiffs("job", labels.stream());
assertThat(gcsClient.readLabelDiffs("job")).containsExactlyElementsIn(labels);
}

View File

@@ -28,7 +28,7 @@ class BlockLabelTest {
@BeforeEach
void setup() {
label = BlockLabel.of("buy", LabelType.CREATE, ImmutableSet.of("JA", "EXTENDED_LATIN"));
label = BlockLabel.create("buy", LabelType.CREATE, ImmutableSet.of("JA", "EXTENDED_LATIN"));
}
@Test
@@ -43,7 +43,7 @@ class BlockLabelTest {
@Test
void emptyIdns() {
label = BlockLabel.of("buy", LabelType.CREATE, ImmutableSet.of());
label = BlockLabel.create("buy", LabelType.CREATE, ImmutableSet.of());
assertThat(label.serialize()).isEqualTo("buy,CREATE");
assertThat(BlockLabel.deserialize("buy,CREATE")).isEqualTo(label);
}

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