mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 07:57:13 +02:00
HistoryEntry for extra logic; update fee check
While working on an implementation of TLD-specific logic, it was realized that the extra logic methods would need access to the flow's HistoryEntry, so that things like poll messages could be parented properly. Also, the update flow had not been fixed to perform the fee check. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=132561527
This commit is contained in:
parent
95cc7ab3d8
commit
a63921350b
13 changed files with 129 additions and 21 deletions
|
@ -26,6 +26,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateNoDuplicateCo
|
|||
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrantAllowedOnTld;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateRequiredContactsPresent;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyNotInPendingDelete;
|
||||
import static google.registry.model.domain.fee.Fee.FEE_UPDATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -37,11 +38,13 @@ import google.registry.flows.ResourceUpdateFlow;
|
|||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainBase.Builder;
|
||||
import google.registry.model.domain.DomainCommand.Update;
|
||||
import google.registry.model.domain.fee.FeeTransformCommandExtension;
|
||||
import google.registry.model.domain.secdns.DelegationSignerData;
|
||||
import google.registry.model.domain.secdns.SecDnsUpdateExtension;
|
||||
import google.registry.model.domain.secdns.SecDnsUpdateExtension.Add;
|
||||
import google.registry.model.domain.secdns.SecDnsUpdateExtension.Remove;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An EPP flow that updates a domain application or resource.
|
||||
|
@ -52,10 +55,16 @@ import java.util.Set;
|
|||
public abstract class BaseDomainUpdateFlow<R extends DomainBase, B extends Builder<R, B>>
|
||||
extends ResourceUpdateFlow<R, B, Update> {
|
||||
|
||||
@Nullable
|
||||
protected FeeTransformCommandExtension feeUpdate;
|
||||
|
||||
protected Optional<RegistryExtraFlowLogic> extraFlowLogic;
|
||||
|
||||
@Override
|
||||
public final void initResourceCreateOrMutateFlow() throws EppException {
|
||||
registerExtensions(FEE_UPDATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
feeUpdate =
|
||||
eppInput.getFirstExtensionOfClasses(FEE_UPDATE_COMMAND_EXTENSIONS_IN_PREFERENCE_ORDER);
|
||||
command = cloneAndLinkReferences(command, now);
|
||||
initDomainUpdateFlow();
|
||||
extraFlowLogic = RegistryExtraFlowLogicProxy.newInstanceForDomain(existingResource);
|
||||
|
|
|
@ -195,7 +195,8 @@ public class DomainCreateFlow extends DomainCreateOrAllocateFlow {
|
|||
getClientId(),
|
||||
now,
|
||||
command.getPeriod().getValue(),
|
||||
eppInput);
|
||||
eppInput,
|
||||
historyEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ public class DomainDeleteFlow extends ResourceSyncDeleteFlow<DomainResource, Bui
|
|||
// Handle extra flow logic, if any.
|
||||
if (extraFlowLogic.isPresent()) {
|
||||
extraFlowLogic.get().performAdditionalDomainDeleteLogic(
|
||||
existingResource, getClientId(), now, eppInput);
|
||||
existingResource, getClientId(), now, eppInput, historyEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -971,6 +971,13 @@ public class DomainFlowUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/** Fees must be explicitly acknowledged when performing an update which is not free. */
|
||||
static class FeesRequiredForNonFreeUpdateException extends RequiredParameterMissingException {
|
||||
FeesRequiredForNonFreeUpdateException() {
|
||||
super("Fees must be explicitly acknowledged when performing an update which is not free.");
|
||||
}
|
||||
}
|
||||
|
||||
/** The 'grace-period', 'applied' and 'refundable' fields are disallowed by server policy. */
|
||||
static class UnsupportedFeeAttributeException extends UnimplementedOptionException {
|
||||
UnsupportedFeeAttributeException() {
|
||||
|
@ -1048,4 +1055,3 @@ public class DomainFlowUtils {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,12 @@ public class DomainRenewFlow extends OwnedResourceMutateFlow<DomainResource, Ren
|
|||
// Handle extra flow logic, if any.
|
||||
if (extraFlowLogic.isPresent()) {
|
||||
extraFlowLogic.get().performAdditionalDomainRenewLogic(
|
||||
existingResource, getClientId(), now, command.getPeriod().getValue(), eppInput);
|
||||
existingResource,
|
||||
getClientId(),
|
||||
now,
|
||||
command.getPeriod().getValue(),
|
||||
eppInput,
|
||||
historyEntry);
|
||||
}
|
||||
|
||||
ofy().save().<Object>entities(explicitRenewEvent, newAutorenewEvent, newAutorenewPollMessage);
|
||||
|
|
|
@ -162,7 +162,7 @@ public class DomainRestoreRequestFlow extends OwnedResourceMutateFlow<DomainReso
|
|||
// Handle extra flow logic, if any.
|
||||
if (extraFlowLogic.isPresent()) {
|
||||
extraFlowLogic.get().performAdditionalDomainRestoreLogic(
|
||||
existingResource, getClientId(), now, eppInput);
|
||||
existingResource, getClientId(), now, eppInput, historyEntry);
|
||||
}
|
||||
|
||||
return existingResource.asBuilder()
|
||||
|
|
|
@ -191,7 +191,12 @@ public class DomainTransferRequestFlow
|
|||
// Handle extra flow logic, if any.
|
||||
if (extraFlowLogic.isPresent()) {
|
||||
extraFlowLogic.get().performAdditionalDomainTransferLogic(
|
||||
existingResource, getClientId(), now, command.getPeriod().getValue(), eppInput);
|
||||
existingResource,
|
||||
getClientId(),
|
||||
now,
|
||||
command.getPeriod().getValue(),
|
||||
eppInput,
|
||||
historyEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package google.registry.flows.domain;
|
||||
|
||||
import static com.google.common.collect.Sets.symmetricDifference;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.util.DateTimeUtils.earliestOf;
|
||||
|
||||
|
@ -23,6 +24,8 @@ import com.google.common.base.Predicate;
|
|||
import com.google.common.collect.Iterables;
|
||||
import google.registry.dns.DnsQueue;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForNonFreeUpdateException;
|
||||
import google.registry.flows.domain.TldSpecificLogicProxy.EppCommandOperations;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Reason;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
|
@ -55,6 +58,8 @@ import org.joda.time.DateTime;
|
|||
* @error {@link BaseDomainUpdateFlow.SecDnsAllUsageException}
|
||||
* @error {@link BaseDomainUpdateFlow.UrgentAttributeNotSupportedException}
|
||||
* @error {@link DomainFlowUtils.DuplicateContactForRoleException}
|
||||
* @error {@link DomainFlowUtils.FeesMismatchException}
|
||||
* @error {@link DomainFlowUtils.FeesRequiredForNonFreeUpdateException}
|
||||
* @error {@link DomainFlowUtils.LinkedResourcesDoNotExistException}
|
||||
* @error {@link DomainFlowUtils.LinkedResourceInPendingDeleteProhibitsOperationException}
|
||||
* @error {@link DomainFlowUtils.MissingAdminContactException}
|
||||
|
@ -132,11 +137,27 @@ public class DomainUpdateFlow extends BaseDomainUpdateFlow<DomainResource, Build
|
|||
// Handle extra flow logic, if any.
|
||||
if (extraFlowLogic.isPresent()) {
|
||||
extraFlowLogic.get().performAdditionalDomainUpdateLogic(
|
||||
existingResource, getClientId(), now, eppInput);
|
||||
existingResource, getClientId(), now, eppInput, historyEntry);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void verifyDomainUpdateIsAllowed() throws EppException {
|
||||
EppCommandOperations commandOperations = TldSpecificLogicProxy.getUpdatePrice(
|
||||
Registry.get(existingResource.getTld()),
|
||||
existingResource.getFullyQualifiedDomainName(),
|
||||
getClientId(),
|
||||
now,
|
||||
eppInput);
|
||||
// The fee extension must be present if the update is not free.
|
||||
if ((feeUpdate == null) && !commandOperations.getTotalCost().isZero()) {
|
||||
throw new FeesRequiredForNonFreeUpdateException();
|
||||
}
|
||||
validateFeeChallenge(
|
||||
targetId, existingResource.getTld(), now, feeUpdate, commandOperations.getTotalCost());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void modifyUpdateRelatedResources() {
|
||||
// Determine the status changes, and filter to server statuses.
|
||||
|
|
|
@ -18,6 +18,7 @@ import google.registry.flows.EppException;
|
|||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.fee.BaseFee;
|
||||
import google.registry.model.eppinput.EppInput;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import java.util.List;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
|
@ -48,7 +49,8 @@ public interface RegistryExtraFlowLogic {
|
|||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
int years,
|
||||
EppInput eppInput) throws EppException;
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException;
|
||||
|
||||
/**
|
||||
* Performs additional tasks required for a delete command. Any changes should not be persisted to
|
||||
|
@ -58,7 +60,8 @@ public interface RegistryExtraFlowLogic {
|
|||
DomainResource domain,
|
||||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
EppInput eppInput) throws EppException;
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException;
|
||||
|
||||
/** Computes the expected renewal fee, for use in fee challenges and the like. */
|
||||
public BaseFee getRenewFeeOrCredit(
|
||||
|
@ -77,7 +80,8 @@ public interface RegistryExtraFlowLogic {
|
|||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
int years,
|
||||
EppInput eppInput) throws EppException;
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException;
|
||||
|
||||
/**
|
||||
* Performs additional tasks required for a restore command. Any changes should not be persisted
|
||||
|
@ -87,7 +91,8 @@ public interface RegistryExtraFlowLogic {
|
|||
DomainResource domain,
|
||||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
EppInput eppInput) throws EppException;
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException;
|
||||
|
||||
/**
|
||||
* Performs additional tasks required for a transfer command. Any changes should not be persisted
|
||||
|
@ -98,7 +103,8 @@ public interface RegistryExtraFlowLogic {
|
|||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
int years,
|
||||
EppInput eppInput) throws EppException;
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException;
|
||||
|
||||
/** Computes the expected update fee, for use in fee challenges and the like. */
|
||||
public BaseFee getUpdateFeeOrCredit(
|
||||
|
@ -115,7 +121,8 @@ public interface RegistryExtraFlowLogic {
|
|||
DomainResource domain,
|
||||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
EppInput eppInput) throws EppException;
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException;
|
||||
|
||||
/** Commits any changes made as a result of a call to one of the performXXX methods. */
|
||||
public void commitAdditionalLogicChanges();
|
||||
|
|
|
@ -55,6 +55,8 @@ import google.registry.flows.domain.BaseDomainUpdateFlow.MaxSigLifeChangeNotSupp
|
|||
import google.registry.flows.domain.BaseDomainUpdateFlow.SecDnsAllUsageException;
|
||||
import google.registry.flows.domain.BaseDomainUpdateFlow.UrgentAttributeNotSupportedException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.DuplicateContactForRoleException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForNonFreeUpdateException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.LinkedResourceInPendingDeleteProhibitsOperationException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.LinkedResourcesDoNotExistException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.MissingAdminContactException;
|
||||
|
@ -1181,10 +1183,28 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testAddAndRemoveFlags() throws Exception {
|
||||
public void testAddAndRemoveFlags_noFee() throws Exception {
|
||||
setEppInput("domain_update_addremove_flags.xml");
|
||||
persistReferencedEntities();
|
||||
persistDomain();
|
||||
thrown.expect(FeesRequiredForNonFreeUpdateException.class);
|
||||
runFlow();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAndRemoveFlags_wrongFee() throws Exception {
|
||||
setEppInput("domain_update_addremove_flags_fee.xml", ImmutableMap.of("FEE", "11.00"));
|
||||
persistReferencedEntities();
|
||||
persistDomain();
|
||||
thrown.expect(FeesMismatchException.class);
|
||||
runFlow();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAndRemoveFlags_correctFee() throws Exception {
|
||||
setEppInput("domain_update_addremove_flags_fee.xml", ImmutableMap.of("FEE", "13.00"));
|
||||
persistReferencedEntities();
|
||||
persistDomain();
|
||||
thrown.expect(IllegalArgumentException.class, "add:flag1,flag2;remove:flag3,flag4");
|
||||
runFlow();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<update>
|
||||
<domain:update
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example.flags</domain:name>
|
||||
<domain:name>update-13.flags</domain:name>
|
||||
</domain:update>
|
||||
</update>
|
||||
<extension>
|
||||
|
|
27
javatests/google/registry/flows/domain/testdata/domain_update_addremove_flags_fee.xml
vendored
Normal file
27
javatests/google/registry/flows/domain/testdata/domain_update_addremove_flags_fee.xml
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<update>
|
||||
<domain:update
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>update-13.flags</domain:name>
|
||||
</domain:update>
|
||||
</update>
|
||||
<extension>
|
||||
<flags:update xmlns:flags="urn:google:params:xml:ns:flags-0.1">
|
||||
<flags:add>
|
||||
<flags:flag>flag1</flags:flag>
|
||||
<flags:flag>flag2</flags:flag>
|
||||
</flags:add>
|
||||
<flags:rem>
|
||||
<flags:flag>flag3</flags:flag>
|
||||
<flags:flag>flag4</flags:flag>
|
||||
</flags:rem>
|
||||
</flags:update>
|
||||
<fee:update xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee>%FEE%</fee:fee>
|
||||
</fee:update>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
|
@ -31,6 +31,7 @@ import google.registry.model.domain.flags.FlagsCreateCommandExtension;
|
|||
import google.registry.model.domain.flags.FlagsTransferCommandExtension;
|
||||
import google.registry.model.domain.flags.FlagsUpdateCommandExtension;
|
||||
import google.registry.model.eppinput.EppInput;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import org.joda.time.DateTime;
|
||||
|
@ -95,7 +96,8 @@ public class TestExtraLogicManager implements RegistryExtraFlowLogic {
|
|||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
int years,
|
||||
EppInput eppInput) throws EppException {
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException {
|
||||
FlagsCreateCommandExtension flags =
|
||||
eppInput.getSingleExtension(FlagsCreateCommandExtension.class);
|
||||
if (flags == null) {
|
||||
|
@ -113,7 +115,8 @@ public class TestExtraLogicManager implements RegistryExtraFlowLogic {
|
|||
DomainResource domainResource,
|
||||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
EppInput eppInput) throws EppException {
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException {
|
||||
messageToThrow = "deleted";
|
||||
}
|
||||
|
||||
|
@ -138,7 +141,8 @@ public class TestExtraLogicManager implements RegistryExtraFlowLogic {
|
|||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
int years,
|
||||
EppInput eppInput) throws EppException {
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException {
|
||||
messageToThrow = "renewed";
|
||||
}
|
||||
|
||||
|
@ -151,7 +155,8 @@ public class TestExtraLogicManager implements RegistryExtraFlowLogic {
|
|||
DomainResource domainResource,
|
||||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
EppInput eppInput) throws EppException {
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException {
|
||||
messageToThrow = "restored";
|
||||
}
|
||||
|
||||
|
@ -165,7 +170,8 @@ public class TestExtraLogicManager implements RegistryExtraFlowLogic {
|
|||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
int years,
|
||||
EppInput eppInput) throws EppException {
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException {
|
||||
FlagsTransferCommandExtension flags =
|
||||
eppInput.getSingleExtension(FlagsTransferCommandExtension.class);
|
||||
if (flags == null) {
|
||||
|
@ -197,7 +203,8 @@ public class TestExtraLogicManager implements RegistryExtraFlowLogic {
|
|||
DomainResource domainResource,
|
||||
String clientIdentifier,
|
||||
DateTime asOfDate,
|
||||
EppInput eppInput) throws EppException {
|
||||
EppInput eppInput,
|
||||
HistoryEntry historyEntry) throws EppException {
|
||||
FlagsUpdateCommandExtension flags =
|
||||
eppInput.getSingleExtension(FlagsUpdateCommandExtension.class);
|
||||
if (flags == null) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue