Skip to content

Commit 9c16b3d

Browse files
ptkachqrtp
authored andcommitted
Add java code for RegitrarPoc id (google#2770)
1 parent 432e429 commit 9c16b3d

File tree

13 files changed

+213
-196
lines changed

13 files changed

+213
-196
lines changed

console-webapp/src/app/settings/contact/contact.service.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type contactType =
2424
| 'LEGAL'
2525
| 'MARKETING'
2626
| 'TECH'
27-
| 'RDAP';
27+
| 'WHOIS';
2828

2929
type contactTypesToUserFriendlyTypes = { [type in contactType]: string };
3030

@@ -35,7 +35,7 @@ export const contactTypeToTextMap: contactTypesToUserFriendlyTypes = {
3535
LEGAL: 'Legal contact',
3636
MARKETING: 'Marketing contact',
3737
TECH: 'Technical contact',
38-
RDAP: 'RDAP-Inquiry contact',
38+
WHOIS: 'RDAP-Inquiry contact',
3939
};
4040

4141
type UserFriendlyType = (typeof contactTypeToTextMap)[contactType];
@@ -59,7 +59,10 @@ export interface ViewReadyContact extends Contact {
5959
export function contactTypeToViewReadyContact(c: Contact): ViewReadyContact {
6060
return {
6161
...c,
62-
userFriendlyTypes: c.types?.map((cType) => contactTypeToTextMap[cType]),
62+
userFriendlyTypes: (c.types || []).map(
63+
(cType) => contactTypeToTextMap[cType]
64+
),
65+
types: c.types || [],
6366
};
6467
}
6568

@@ -98,19 +101,21 @@ export class ContactService {
98101
);
99102
}
100103

101-
saveContacts(contacts: ViewReadyContact[]): Observable<Contact[]> {
104+
updateContact(contact: ViewReadyContact) {
102105
return this.backend
103-
.postContacts(this.registrarService.registrarId(), contacts)
106+
.updateContact(this.registrarService.registrarId(), contact)
104107
.pipe(switchMap((_) => this.fetchContacts()));
105108
}
106109

107110
addContact(contact: ViewReadyContact) {
108-
const newContacts = this.contacts().concat([contact]);
109-
return this.saveContacts(newContacts);
111+
return this.backend
112+
.createContact(this.registrarService.registrarId(), contact)
113+
.pipe(switchMap((_) => this.fetchContacts()));
110114
}
111115

112116
deleteContact(contact: ViewReadyContact) {
113-
const newContacts = this.contacts().filter((c) => c !== contact);
114-
return this.saveContacts(newContacts);
117+
return this.backend
118+
.deleteContact(this.registrarService.registrarId(), contact)
119+
.pipe(switchMap((_) => this.fetchContacts()));
115120
}
116121
}

console-webapp/src/app/settings/contact/contactDetails.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,13 @@ export class ContactDetailsComponent {
6969

7070
save(e: SubmitEvent) {
7171
e.preventDefault();
72+
if ((this.contactService.contactInEdit.types || []).length === 0) {
73+
this._snackBar.open('Required to select contact type');
74+
return;
75+
}
7276
const request = this.contactService.isContactNewView
7377
? this.contactService.addContact(this.contactService.contactInEdit)
74-
: this.contactService.saveContacts(this.contactService.contacts());
78+
: this.contactService.updateContact(this.contactService.contactInEdit);
7579
request.subscribe({
7680
complete: () => {
7781
this.goBack();

console-webapp/src/app/shared/services/backend.service.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,26 @@ export class BackendService {
7070
.pipe(catchError((err) => this.errorCatcher<Contact[]>(err)));
7171
}
7272

73-
postContacts(
74-
registrarId: string,
75-
contacts: Contact[]
76-
): Observable<Contact[]> {
77-
return this.http.post<Contact[]>(
73+
updateContact(registrarId: string, contact: Contact): Observable<Contact> {
74+
return this.http.put<Contact>(
75+
`/console-api/settings/contacts?registrarId=${registrarId}`,
76+
contact
77+
);
78+
}
79+
80+
createContact(registrarId: string, contact: Contact): Observable<Contact> {
81+
return this.http.post<Contact>(
7882
`/console-api/settings/contacts?registrarId=${registrarId}`,
79-
contacts
83+
contact
84+
);
85+
}
86+
87+
deleteContact(registrarId: string, contact: Contact): Observable<Contact> {
88+
return this.http.delete<Contact>(
89+
`/console-api/settings/contacts?registrarId=${registrarId}`,
90+
{
91+
body: JSON.stringify(contact),
92+
}
8093
);
8194
}
8295

core/src/main/java/google/registry/model/registrar/RegistrarPoc.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ public boolean isRequired() {
9393
}
9494
}
9595

96+
@Expose
97+
@Column(insertable = false, updatable = false)
98+
protected Long id;
99+
96100
/** The name of the contact. */
97101
@Expose String name;
98102

@@ -179,6 +183,10 @@ public static void updateContacts(
179183
tm().putAll(contacts);
180184
}
181185

186+
public Long getId() {
187+
return id;
188+
}
189+
182190
public String getName() {
183191
return name;
184192
}
@@ -295,6 +303,7 @@ public Map<String, Object> toJsonMap() {
295303
.put("visibleInDomainWhoisAsAbuse", visibleInDomainWhoisAsAbuse)
296304
.put("allowedToSetRegistryLockPassword", allowedToSetRegistryLockPassword)
297305
.put("registryLockAllowed", isRegistryLockAllowed())
306+
.put("id", getId())
298307
.build();
299308
}
300309

core/src/main/java/google/registry/ui/server/console/ConsoleModule.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import static google.registry.request.RequestParameters.extractOptionalParameter;
2020
import static google.registry.request.RequestParameters.extractRequiredParameter;
2121

22-
import com.google.common.collect.ImmutableSet;
2322
import com.google.gson.Gson;
2423
import com.google.gson.JsonElement;
2524
import dagger.Module;
@@ -192,10 +191,10 @@ static String provideDomain(HttpServletRequest req) {
192191
}
193192

194193
@Provides
195-
@Parameter("contacts")
196-
public static Optional<ImmutableSet<RegistrarPoc>> provideContacts(
194+
@Parameter("contact")
195+
public static Optional<RegistrarPoc> provideContacts(
197196
Gson gson, @OptionalJsonPayload Optional<JsonElement> payload) {
198-
return payload.map(s -> ImmutableSet.copyOf(gson.fromJson(s, RegistrarPoc[].class)));
197+
return payload.map(s -> gson.fromJson(s, RegistrarPoc.class));
199198
}
200199

201200
@Provides

core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java

Lines changed: 81 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
import static com.google.common.collect.ImmutableSet.toImmutableSet;
2020
import static com.google.common.collect.Sets.difference;
2121
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
22+
import static google.registry.request.Action.Method.DELETE;
2223
import static google.registry.request.Action.Method.GET;
2324
import static google.registry.request.Action.Method.POST;
25+
import static google.registry.request.Action.Method.PUT;
2426
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
2527

2628
import com.google.common.collect.HashMultimap;
@@ -40,59 +42,123 @@
4042
import google.registry.request.Parameter;
4143
import google.registry.request.auth.Auth;
4244
import google.registry.ui.forms.FormException;
43-
import google.registry.ui.server.RegistrarFormFields;
4445
import google.registry.ui.server.console.ConsoleApiAction;
4546
import google.registry.ui.server.console.ConsoleApiParams;
4647
import jakarta.inject.Inject;
47-
import java.util.Collections;
4848
import java.util.HashSet;
4949
import java.util.Objects;
5050
import java.util.Optional;
5151
import java.util.Set;
52+
import java.util.function.BiFunction;
5253

5354
@Action(
5455
service = GaeService.DEFAULT,
5556
gkeService = GkeService.CONSOLE,
5657
path = ContactAction.PATH,
57-
method = {GET, POST},
58+
method = {GET, POST, DELETE, PUT},
5859
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
5960
public class ContactAction extends ConsoleApiAction {
6061
static final String PATH = "/console-api/settings/contacts";
6162
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
62-
private final Optional<ImmutableSet<RegistrarPoc>> contacts;
63+
private final Optional<RegistrarPoc> contact;
6364
private final String registrarId;
6465

6566
@Inject
6667
public ContactAction(
6768
ConsoleApiParams consoleApiParams,
6869
@Parameter("registrarId") String registrarId,
69-
@Parameter("contacts") Optional<ImmutableSet<RegistrarPoc>> contacts) {
70+
@Parameter("contact") Optional<RegistrarPoc> contact) {
7071
super(consoleApiParams);
7172
this.registrarId = registrarId;
72-
this.contacts = contacts;
73+
this.contact = contact;
7374
}
7475

7576
@Override
7677
protected void getHandler(User user) {
7778
checkPermission(user, registrarId, ConsolePermission.VIEW_REGISTRAR_DETAILS);
78-
ImmutableList<RegistrarPoc> am =
79+
ImmutableList<RegistrarPoc> contacts =
7980
tm().transact(
8081
() ->
8182
tm()
8283
.createQueryComposer(RegistrarPoc.class)
8384
.where("registrarId", Comparator.EQ, registrarId)
8485
.stream()
85-
.filter(r -> !r.getTypes().isEmpty())
8686
.collect(toImmutableList()));
8787

8888
consoleApiParams.response().setStatus(SC_OK);
89-
consoleApiParams.response().setPayload(consoleApiParams.gson().toJson(am));
89+
consoleApiParams.response().setPayload(consoleApiParams.gson().toJson(contacts));
90+
}
91+
92+
@Override
93+
protected void deleteHandler(User user) {
94+
updateContacts(
95+
user,
96+
(registrar, oldContacts) ->
97+
oldContacts.stream()
98+
.filter(
99+
oldContact ->
100+
!oldContact.getEmailAddress().equals(contact.get().getEmailAddress()))
101+
.collect(toImmutableSet()));
90102
}
91103

92104
@Override
93105
protected void postHandler(User user) {
106+
updateContacts(
107+
user,
108+
(registrar, oldContacts) -> {
109+
RegistrarPoc newContact = contact.get();
110+
return ImmutableSet.<RegistrarPoc>builder()
111+
.addAll(oldContacts)
112+
.add(
113+
new RegistrarPoc()
114+
.asBuilder()
115+
.setTypes(newContact.getTypes())
116+
.setVisibleInWhoisAsTech(newContact.getVisibleInWhoisAsTech())
117+
.setVisibleInWhoisAsAdmin(newContact.getVisibleInWhoisAsAdmin())
118+
.setVisibleInDomainWhoisAsAbuse(newContact.getVisibleInDomainWhoisAsAbuse())
119+
.setFaxNumber(newContact.getFaxNumber())
120+
.setName(newContact.getName())
121+
.setEmailAddress(newContact.getEmailAddress())
122+
.setPhoneNumber(newContact.getPhoneNumber())
123+
.setRegistrar(registrar)
124+
.build())
125+
.build();
126+
});
127+
}
128+
129+
@Override
130+
protected void putHandler(User user) {
131+
updateContacts(
132+
user,
133+
(registrar, oldContacts) -> {
134+
RegistrarPoc updatedContact = contact.get();
135+
return oldContacts.stream()
136+
.map(
137+
oldContact ->
138+
oldContact.getId().equals(updatedContact.getId())
139+
? oldContact
140+
.asBuilder()
141+
.setTypes(updatedContact.getTypes())
142+
.setVisibleInWhoisAsTech(updatedContact.getVisibleInWhoisAsTech())
143+
.setVisibleInWhoisAsAdmin(updatedContact.getVisibleInWhoisAsAdmin())
144+
.setVisibleInDomainWhoisAsAbuse(
145+
updatedContact.getVisibleInDomainWhoisAsAbuse())
146+
.setFaxNumber(updatedContact.getFaxNumber())
147+
.setName(updatedContact.getName())
148+
.setEmailAddress(updatedContact.getEmailAddress())
149+
.setPhoneNumber(updatedContact.getPhoneNumber())
150+
.build()
151+
: oldContact)
152+
.collect(toImmutableSet());
153+
});
154+
}
155+
156+
private void updateContacts(
157+
User user,
158+
BiFunction<Registrar, ImmutableSet<RegistrarPoc>, ImmutableSet<RegistrarPoc>>
159+
contactsUpdater) {
94160
checkPermission(user, registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS);
95-
checkArgument(contacts.isPresent(), "Contacts parameter is not present");
161+
checkArgument(contact.isPresent(), "Contact parameter is not present");
96162
Registrar registrar =
97163
Registrar.loadByRegistrarId(registrarId)
98164
.orElseThrow(
@@ -101,20 +167,10 @@ protected void postHandler(User user) {
101167
String.format("Unknown registrar %s", registrarId)));
102168

103169
ImmutableSet<RegistrarPoc> oldContacts = registrar.getContacts();
104-
ImmutableSet<RegistrarPoc> updatedContacts =
105-
RegistrarFormFields.getRegistrarContactBuilders(
106-
oldContacts,
107-
Collections.singletonMap(
108-
"contacts",
109-
contacts.get().stream()
110-
.map(RegistrarPoc::toJsonMap)
111-
.collect(toImmutableList())))
112-
.stream()
113-
.map(builder -> builder.setRegistrar(registrar).build())
114-
.collect(toImmutableSet());
170+
ImmutableSet<RegistrarPoc> newContacts = contactsUpdater.apply(registrar, oldContacts);
115171

116172
try {
117-
checkContactRequirements(oldContacts, updatedContacts);
173+
checkContactRequirements(oldContacts, newContacts);
118174
} catch (FormException e) {
119175
logger.atWarning().withCause(e).log(
120176
"Error processing contacts post request for registrar: %s", registrarId);
@@ -123,14 +179,13 @@ protected void postHandler(User user) {
123179

124180
tm().transact(
125181
() -> {
126-
RegistrarPoc.updateContacts(registrar, updatedContacts);
182+
RegistrarPoc.updateContacts(registrar, newContacts);
127183
Registrar updatedRegistrar =
128184
registrar.asBuilder().setContactsRequireSyncing(true).build();
129185
tm().put(updatedRegistrar);
130186
sendExternalUpdatesIfNecessary(
131-
EmailInfo.create(registrar, updatedRegistrar, oldContacts, updatedContacts));
187+
EmailInfo.create(registrar, updatedRegistrar, oldContacts, newContacts));
132188
});
133-
134189
consoleApiParams.response().setStatus(SC_OK);
135190
}
136191

@@ -169,6 +224,7 @@ private static void checkContactRequirements(
169224
throw new ContactRequirementException(t);
170225
}
171226
}
227+
172228
enforcePrimaryContactRestrictions(oldContactsByType, newContactsByType);
173229
ensurePhoneNumberNotRemovedForContactTypes(oldContactsByType, newContactsByType, Type.TECH);
174230
Optional<RegistrarPoc> domainWhoisAbuseContact =

core/src/test/java/google/registry/model/registrar/RegistrarTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import google.registry.model.tld.Tld;
4545
import google.registry.model.tld.Tld.TldType;
4646
import google.registry.model.tld.Tlds;
47+
import google.registry.testing.DatabaseHelper;
4748
import google.registry.util.CidrAddressBlock;
4849
import google.registry.util.SerializeUtils;
4950
import java.math.BigDecimal;
@@ -340,6 +341,7 @@ void testSuccess_getContactsByType() {
340341
.setFaxNumber("+1.2125551213")
341342
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH, RegistrarPoc.Type.ABUSE))
342343
.build());
344+
abuseAdminContact = DatabaseHelper.loadByKey(abuseAdminContact.createVKey());
343345
ImmutableSortedSet<RegistrarPoc> techContacts =
344346
registrar.getContactsOfType(RegistrarPoc.Type.TECH);
345347
assertThat(techContacts).containsExactly(newTechContact, newTechAbuseContact).inOrder();

core/src/test/java/google/registry/schema/registrar/RegistrarPocTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
package google.registry.schema.registrar;
1616

1717
import static com.google.common.truth.Truth.assertThat;
18+
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
1819
import static google.registry.model.registrar.RegistrarPoc.Type.WHOIS;
1920
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
2021
import static google.registry.testing.DatabaseHelper.insertInDb;
21-
import static google.registry.testing.DatabaseHelper.loadByEntity;
2222
import static google.registry.testing.SqlHelper.saveRegistrar;
2323

2424
import com.google.common.collect.ImmutableSet;
@@ -63,7 +63,9 @@ public void beforeEach() {
6363
@Test
6464
void testPersistence_succeeds() {
6565
insertInDb(testRegistrarPoc);
66-
assertThat(loadByEntity(testRegistrarPoc)).isEqualTo(testRegistrarPoc);
66+
assertAboutImmutableObjects()
67+
.that(testRegistrarPoc)
68+
.isEqualExceptFields(testRegistrarPoc, "id");
6769
}
6870

6971
@Test

0 commit comments

Comments
 (0)