mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 16:07:15 +02:00
Dagger, meet Flows. Flows, meet Dagger.
Daggerizes all of the EPP flows. This does not change anything yet about the flows themselves, just how they are invoked, but after this CL it's safe to @Inject things into flow classes. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=125382478
This commit is contained in:
parent
116bf1f4d6
commit
c9a16f7f11
69 changed files with 973 additions and 292 deletions
|
@ -15,12 +15,11 @@
|
||||||
package google.registry.flows;
|
package google.registry.flows;
|
||||||
|
|
||||||
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
import static google.registry.flows.EppXmlTransformer.unmarshal;
|
||||||
import static google.registry.flows.picker.FlowPicker.getFlowClass;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
|
|
||||||
|
import google.registry.flows.FlowModule.EppExceptionInProviderException;
|
||||||
import google.registry.model.eppcommon.Trid;
|
import google.registry.model.eppcommon.Trid;
|
||||||
import google.registry.model.eppinput.EppInput;
|
import google.registry.model.eppinput.EppInput;
|
||||||
import google.registry.model.eppoutput.EppOutput;
|
import google.registry.model.eppoutput.EppOutput;
|
||||||
|
@ -43,6 +42,7 @@ public final class EppController {
|
||||||
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
|
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
|
||||||
|
|
||||||
@Inject Clock clock;
|
@Inject Clock clock;
|
||||||
|
@Inject FlowComponent.Builder flowComponentBuilder;
|
||||||
@Inject EppMetrics metrics;
|
@Inject EppMetrics metrics;
|
||||||
@Inject EppController() {}
|
@Inject EppController() {}
|
||||||
|
|
||||||
|
@ -54,57 +54,62 @@ public final class EppController {
|
||||||
boolean isDryRun,
|
boolean isDryRun,
|
||||||
boolean isSuperuser,
|
boolean isSuperuser,
|
||||||
byte[] inputXmlBytes) {
|
byte[] inputXmlBytes) {
|
||||||
Trid trid = null;
|
|
||||||
try {
|
|
||||||
EppInput eppInput = unmarshal(EppInput.class, inputXmlBytes);
|
|
||||||
trid = Trid.create(eppInput.getCommandWrapper().getClTrid());
|
|
||||||
ImmutableList<String> targetIds = eppInput.getTargetIds();
|
|
||||||
metrics.setCommandName(eppInput.getCommandName());
|
|
||||||
metrics.setClientId(sessionMetadata.getClientId());
|
metrics.setClientId(sessionMetadata.getClientId());
|
||||||
metrics.setPrivilegeLevel(isSuperuser ? "SUPERUSER" : "NORMAL");
|
metrics.setPrivilegeLevel(isSuperuser ? "SUPERUSER" : "NORMAL");
|
||||||
if (!targetIds.isEmpty()) {
|
try {
|
||||||
metrics.setEppTarget(Joiner.on(",").join(targetIds));
|
EppInput eppInput;
|
||||||
}
|
try {
|
||||||
FlowRunner flowRunner = new FlowRunner(
|
eppInput = unmarshal(EppInput.class, inputXmlBytes);
|
||||||
getFlowClass(eppInput),
|
|
||||||
eppInput,
|
|
||||||
trid,
|
|
||||||
sessionMetadata,
|
|
||||||
credentials,
|
|
||||||
eppRequestSource,
|
|
||||||
isDryRun,
|
|
||||||
isSuperuser,
|
|
||||||
inputXmlBytes,
|
|
||||||
metrics,
|
|
||||||
clock);
|
|
||||||
EppOutput eppOutput = flowRunner.run();
|
|
||||||
if (eppOutput.isResponse()) {
|
|
||||||
metrics.setEppStatus(eppOutput.getResponse().getResult().getCode());
|
|
||||||
}
|
|
||||||
return eppOutput;
|
|
||||||
} catch (EppException e) {
|
} catch (EppException e) {
|
||||||
// The command failed. Send the client an error message.
|
// Send the client an error message, with no clTRID since we couldn't unmarshal it.
|
||||||
metrics.setEppStatus(e.getResult().getCode());
|
metrics.setEppStatus(e.getResult().getCode());
|
||||||
return getErrorResponse(clock, e.getResult(), trid);
|
return getErrorResponse(clock, e.getResult(), Trid.create(null));
|
||||||
} catch (Throwable e) {
|
}
|
||||||
// Something bad and unexpected happened. Send the client a generic error, and log it.
|
metrics.setCommandName(eppInput.getCommandName());
|
||||||
logger.severe(e, "Unexpected failure");
|
if (!eppInput.getTargetIds().isEmpty()) {
|
||||||
metrics.setEppStatus(Code.CommandFailed);
|
metrics.setEppTarget(Joiner.on(',').join(eppInput.getTargetIds()));
|
||||||
return getErrorResponse(clock, Result.create(Code.CommandFailed), trid);
|
}
|
||||||
|
EppOutput output = runFlowConvertEppErrors(flowComponentBuilder
|
||||||
|
.flowModule(new FlowModule.Builder()
|
||||||
|
.setSessionMetadata(sessionMetadata)
|
||||||
|
.setCredentials(credentials)
|
||||||
|
.setEppRequestSource(eppRequestSource)
|
||||||
|
.setIsDryRun(isDryRun)
|
||||||
|
.setIsSuperuser(isSuperuser)
|
||||||
|
.setInputXmlBytes(inputXmlBytes)
|
||||||
|
.setEppInput(eppInput)
|
||||||
|
.build())
|
||||||
|
.build());
|
||||||
|
if (output.isResponse()) {
|
||||||
|
metrics.setEppStatus(output.getResponse().getResult().getCode());
|
||||||
|
}
|
||||||
|
return output;
|
||||||
} finally {
|
} finally {
|
||||||
metrics.export();
|
metrics.export();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a response indicating an Epp failure. */
|
/** Run an EPP flow and convert known exceptions into EPP error responses. */
|
||||||
|
private EppOutput runFlowConvertEppErrors(FlowComponent flowComponent) {
|
||||||
|
try {
|
||||||
|
return flowComponent.flowRunner().run();
|
||||||
|
} catch (EppException | EppExceptionInProviderException e) {
|
||||||
|
// The command failed. Send the client an error message.
|
||||||
|
EppException eppEx = (EppException) (e instanceof EppException ? e : e.getCause());
|
||||||
|
return getErrorResponse(clock, eppEx.getResult(), flowComponent.trid());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
// Something bad and unexpected happened. Send the client a generic error, and log it.
|
||||||
|
logger.severe(e, "Unexpected failure");
|
||||||
|
return getErrorResponse(clock, Result.create(Code.CommandFailed), flowComponent.trid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a response indicating an EPP failure. */
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static EppOutput getErrorResponse(Clock clock, Result result, Trid trid) {
|
static EppOutput getErrorResponse(Clock clock, Result result, Trid trid) {
|
||||||
// Create TRID (without a clTRID) if one hasn't been created yet, as it's necessary to construct
|
|
||||||
// a valid response. This can happen if the error occurred before we could even parse out the
|
|
||||||
// clTRID (e.g. if a syntax error occurred parsing the supplied XML).
|
|
||||||
return EppOutput.create(new EppResponse.Builder()
|
return EppOutput.create(new EppResponse.Builder()
|
||||||
.setTrid(trid == null ? Trid.create(null) : trid)
|
|
||||||
.setResult(result)
|
.setResult(result)
|
||||||
|
.setTrid(trid)
|
||||||
.setExecutionTime(clock.nowUtc())
|
.setExecutionTime(clock.nowUtc())
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
35
java/google/registry/flows/FlowComponent.java
Normal file
35
java/google/registry/flows/FlowComponent.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2016 The Domain Registry 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.flows;
|
||||||
|
|
||||||
|
import dagger.Subcomponent;
|
||||||
|
|
||||||
|
import google.registry.model.eppcommon.Trid;
|
||||||
|
|
||||||
|
/** Dagger component for flow classes. */
|
||||||
|
@FlowScope
|
||||||
|
@Subcomponent(modules = FlowModule.class)
|
||||||
|
public interface FlowComponent {
|
||||||
|
|
||||||
|
Trid trid();
|
||||||
|
FlowRunner flowRunner();
|
||||||
|
|
||||||
|
/** Dagger-implemented builder for this subcomponent. */
|
||||||
|
@Subcomponent.Builder
|
||||||
|
interface Builder {
|
||||||
|
Builder flowModule(FlowModule flowModule);
|
||||||
|
FlowComponent build();
|
||||||
|
}
|
||||||
|
}
|
335
java/google/registry/flows/FlowModule.java
Normal file
335
java/google/registry/flows/FlowModule.java
Normal file
|
@ -0,0 +1,335 @@
|
||||||
|
// Copyright 2016 The Domain Registry 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.flows;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
|
||||||
|
import google.registry.flows.contact.ContactCheckFlow;
|
||||||
|
import google.registry.flows.contact.ContactCreateFlow;
|
||||||
|
import google.registry.flows.contact.ContactDeleteFlow;
|
||||||
|
import google.registry.flows.contact.ContactInfoFlow;
|
||||||
|
import google.registry.flows.contact.ContactTransferApproveFlow;
|
||||||
|
import google.registry.flows.contact.ContactTransferCancelFlow;
|
||||||
|
import google.registry.flows.contact.ContactTransferQueryFlow;
|
||||||
|
import google.registry.flows.contact.ContactTransferRejectFlow;
|
||||||
|
import google.registry.flows.contact.ContactTransferRequestFlow;
|
||||||
|
import google.registry.flows.contact.ContactUpdateFlow;
|
||||||
|
import google.registry.flows.domain.ClaimsCheckFlow;
|
||||||
|
import google.registry.flows.domain.DomainAllocateFlow;
|
||||||
|
import google.registry.flows.domain.DomainApplicationCreateFlow;
|
||||||
|
import google.registry.flows.domain.DomainApplicationDeleteFlow;
|
||||||
|
import google.registry.flows.domain.DomainApplicationInfoFlow;
|
||||||
|
import google.registry.flows.domain.DomainApplicationUpdateFlow;
|
||||||
|
import google.registry.flows.domain.DomainCheckFlow;
|
||||||
|
import google.registry.flows.domain.DomainCreateFlow;
|
||||||
|
import google.registry.flows.domain.DomainDeleteFlow;
|
||||||
|
import google.registry.flows.domain.DomainInfoFlow;
|
||||||
|
import google.registry.flows.domain.DomainRenewFlow;
|
||||||
|
import google.registry.flows.domain.DomainRestoreRequestFlow;
|
||||||
|
import google.registry.flows.domain.DomainTransferApproveFlow;
|
||||||
|
import google.registry.flows.domain.DomainTransferCancelFlow;
|
||||||
|
import google.registry.flows.domain.DomainTransferQueryFlow;
|
||||||
|
import google.registry.flows.domain.DomainTransferRejectFlow;
|
||||||
|
import google.registry.flows.domain.DomainTransferRequestFlow;
|
||||||
|
import google.registry.flows.domain.DomainUpdateFlow;
|
||||||
|
import google.registry.flows.host.HostCheckFlow;
|
||||||
|
import google.registry.flows.host.HostCreateFlow;
|
||||||
|
import google.registry.flows.host.HostDeleteFlow;
|
||||||
|
import google.registry.flows.host.HostInfoFlow;
|
||||||
|
import google.registry.flows.host.HostUpdateFlow;
|
||||||
|
import google.registry.flows.picker.FlowPicker;
|
||||||
|
import google.registry.flows.poll.PollAckFlow;
|
||||||
|
import google.registry.flows.poll.PollRequestFlow;
|
||||||
|
import google.registry.flows.session.HelloFlow;
|
||||||
|
import google.registry.flows.session.LoginFlow;
|
||||||
|
import google.registry.flows.session.LogoutFlow;
|
||||||
|
import google.registry.model.eppcommon.Trid;
|
||||||
|
import google.registry.model.eppinput.EppInput;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
/** Module to choose and instantiate an EPP flow. */
|
||||||
|
@Module
|
||||||
|
public class FlowModule {
|
||||||
|
|
||||||
|
private EppInput eppInput;
|
||||||
|
private byte[] inputXmlBytes;
|
||||||
|
private SessionMetadata sessionMetadata;
|
||||||
|
private TransportCredentials credentials;
|
||||||
|
private boolean isDryRun;
|
||||||
|
private EppRequestSource eppRequestSource;
|
||||||
|
private boolean isSuperuser;
|
||||||
|
|
||||||
|
private FlowModule() {}
|
||||||
|
|
||||||
|
/** Builder for {@link FlowModule}. */
|
||||||
|
static class Builder {
|
||||||
|
FlowModule module = new FlowModule();
|
||||||
|
|
||||||
|
Builder setEppInput(EppInput eppInput) {
|
||||||
|
module.eppInput = eppInput;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setInputXmlBytes(byte[] inputXmlBytes) {
|
||||||
|
module.inputXmlBytes = inputXmlBytes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setSessionMetadata(SessionMetadata sessionMetadata) {
|
||||||
|
module.sessionMetadata = sessionMetadata;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setIsDryRun(boolean isDryRun) {
|
||||||
|
module.isDryRun = isDryRun;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setIsSuperuser(boolean isSuperuser) {
|
||||||
|
module.isSuperuser = isSuperuser;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setEppRequestSource(EppRequestSource eppRequestSource) {
|
||||||
|
module.eppRequestSource = eppRequestSource;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setCredentials(TransportCredentials credentials) {
|
||||||
|
module.credentials = credentials;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlowModule build() {
|
||||||
|
try {
|
||||||
|
checkState(module != null, "Already built");
|
||||||
|
return module;
|
||||||
|
} finally {
|
||||||
|
module = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
@InputXml
|
||||||
|
byte[] provideInputXml() {
|
||||||
|
return inputXmlBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
EppInput provideEppInput() {
|
||||||
|
return eppInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
SessionMetadata provideSessionMetadata() {
|
||||||
|
return sessionMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
@DryRun
|
||||||
|
boolean provideIsDryRun() {
|
||||||
|
return isDryRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
@Transactional
|
||||||
|
boolean provideIsTransactional(Class<? extends Flow> flowClass) {
|
||||||
|
return TransactionalFlow.class.isAssignableFrom(flowClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
@Superuser
|
||||||
|
boolean provideIsSuperuser() {
|
||||||
|
return isSuperuser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
EppRequestSource provideEppRequestSource() {
|
||||||
|
return eppRequestSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
TransportCredentials provideTransportCredentials() {
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
@Nullable
|
||||||
|
@ClientId
|
||||||
|
static String provideClientId(SessionMetadata sessionMetadata) {
|
||||||
|
return sessionMetadata.getClientId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
static Trid provideTrid(EppInput eppInput) {
|
||||||
|
return Trid.create(eppInput.getCommandWrapper().getClTrid());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Provides a mapping between flow classes and injected providers. */
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
static Map<Class<? extends Flow>, Provider<? extends Flow>> provideFlowClassMap(
|
||||||
|
Provider<ContactCheckFlow> contactCheckFlowProvider,
|
||||||
|
Provider<ContactCreateFlow> contactCreateFlowProvider,
|
||||||
|
Provider<ContactDeleteFlow> contactDeleteFlowProvider,
|
||||||
|
Provider<ContactInfoFlow> contactInfoFlowProvider,
|
||||||
|
Provider<ContactTransferApproveFlow> contactTransferApproveFlowProvider,
|
||||||
|
Provider<ContactTransferCancelFlow> contactTransferCancelFlowProvider,
|
||||||
|
Provider<ContactTransferQueryFlow> contactTransferQueryFlowProvider,
|
||||||
|
Provider<ContactTransferRejectFlow> contactTransferRejectFlowProvider,
|
||||||
|
Provider<ContactTransferRequestFlow> contactTransferRequestFlowProvider,
|
||||||
|
Provider<ContactUpdateFlow> contactUpdateFlowProvider,
|
||||||
|
Provider<ClaimsCheckFlow> claimsCheckFlowProvider,
|
||||||
|
Provider<DomainAllocateFlow> domainAllocateFlowProvider,
|
||||||
|
Provider<DomainApplicationCreateFlow> domainApplicationCreateFlowProvider,
|
||||||
|
Provider<DomainApplicationDeleteFlow> domainApplicationDeleteFlowProvider,
|
||||||
|
Provider<DomainApplicationInfoFlow> domainApplicationInfoFlowProvider,
|
||||||
|
Provider<DomainApplicationUpdateFlow> domainApplicationUpdateFlowProvider,
|
||||||
|
Provider<DomainCheckFlow> domainCheckFlowProvider,
|
||||||
|
Provider<DomainCreateFlow> domainCreateFlowProvider,
|
||||||
|
Provider<DomainDeleteFlow> domainDeleteFlowProvider,
|
||||||
|
Provider<DomainInfoFlow> domainInfoFlowProvider,
|
||||||
|
Provider<DomainRenewFlow> domainRenewFlowProvider,
|
||||||
|
Provider<DomainRestoreRequestFlow> domainRestoreRequestFlowProvider,
|
||||||
|
Provider<DomainTransferApproveFlow> domainTransferApproveFlowProvider,
|
||||||
|
Provider<DomainTransferCancelFlow> domainTransferCancelFlowProvider,
|
||||||
|
Provider<DomainTransferQueryFlow> domainTransferQueryFlowProvider,
|
||||||
|
Provider<DomainTransferRejectFlow> domainTransferRejectFlowProvider,
|
||||||
|
Provider<DomainTransferRequestFlow> domainTransferRequestFlowProvider,
|
||||||
|
Provider<DomainUpdateFlow> domainUpdateFlowProvider,
|
||||||
|
Provider<HostCheckFlow> hostCheckFlowProvider,
|
||||||
|
Provider<HostCreateFlow> hostCreateFlowProvider,
|
||||||
|
Provider<HostDeleteFlow> hostDeleteFlowProvider,
|
||||||
|
Provider<HostInfoFlow> hostInfoFlowProvider,
|
||||||
|
Provider<HostUpdateFlow> hostUpdateFlowProvider,
|
||||||
|
Provider<PollAckFlow> pollAckFlowProvider,
|
||||||
|
Provider<PollRequestFlow> pollRequestFlowProvider,
|
||||||
|
Provider<HelloFlow> helloFlowProvider,
|
||||||
|
Provider<LoginFlow> loginFlowProvider,
|
||||||
|
Provider<LogoutFlow> logoutFlowProvider) {
|
||||||
|
return new ImmutableMap.Builder<Class<? extends Flow>, Provider<? extends Flow>>()
|
||||||
|
.put(ContactCheckFlow.class, contactCheckFlowProvider)
|
||||||
|
.put(ContactCreateFlow.class, contactCreateFlowProvider)
|
||||||
|
.put(ContactDeleteFlow.class, contactDeleteFlowProvider)
|
||||||
|
.put(ContactInfoFlow.class, contactInfoFlowProvider)
|
||||||
|
.put(ContactTransferApproveFlow.class, contactTransferApproveFlowProvider)
|
||||||
|
.put(ContactTransferCancelFlow.class, contactTransferCancelFlowProvider)
|
||||||
|
.put(ContactTransferQueryFlow.class, contactTransferQueryFlowProvider)
|
||||||
|
.put(ContactTransferRejectFlow.class, contactTransferRejectFlowProvider)
|
||||||
|
.put(ContactTransferRequestFlow.class, contactTransferRequestFlowProvider)
|
||||||
|
.put(ContactUpdateFlow.class, contactUpdateFlowProvider)
|
||||||
|
.put(ClaimsCheckFlow.class, claimsCheckFlowProvider)
|
||||||
|
.put(DomainAllocateFlow.class, domainAllocateFlowProvider)
|
||||||
|
.put(DomainApplicationCreateFlow.class, domainApplicationCreateFlowProvider)
|
||||||
|
.put(DomainApplicationDeleteFlow.class, domainApplicationDeleteFlowProvider)
|
||||||
|
.put(DomainApplicationInfoFlow.class, domainApplicationInfoFlowProvider)
|
||||||
|
.put(DomainApplicationUpdateFlow.class, domainApplicationUpdateFlowProvider)
|
||||||
|
.put(DomainCheckFlow.class, domainCheckFlowProvider)
|
||||||
|
.put(DomainCreateFlow.class, domainCreateFlowProvider)
|
||||||
|
.put(DomainDeleteFlow.class, domainDeleteFlowProvider)
|
||||||
|
.put(DomainInfoFlow.class, domainInfoFlowProvider)
|
||||||
|
.put(DomainRenewFlow.class, domainRenewFlowProvider)
|
||||||
|
.put(DomainRestoreRequestFlow.class, domainRestoreRequestFlowProvider)
|
||||||
|
.put(DomainTransferApproveFlow.class, domainTransferApproveFlowProvider)
|
||||||
|
.put(DomainTransferCancelFlow.class, domainTransferCancelFlowProvider)
|
||||||
|
.put(DomainTransferQueryFlow.class, domainTransferQueryFlowProvider)
|
||||||
|
.put(DomainTransferRejectFlow.class, domainTransferRejectFlowProvider)
|
||||||
|
.put(DomainTransferRequestFlow.class, domainTransferRequestFlowProvider)
|
||||||
|
.put(DomainUpdateFlow.class, domainUpdateFlowProvider)
|
||||||
|
.put(HostCheckFlow.class, hostCheckFlowProvider)
|
||||||
|
.put(HostCreateFlow.class, hostCreateFlowProvider)
|
||||||
|
.put(HostDeleteFlow.class, hostDeleteFlowProvider)
|
||||||
|
.put(HostInfoFlow.class, hostInfoFlowProvider)
|
||||||
|
.put(HostUpdateFlow.class, hostUpdateFlowProvider)
|
||||||
|
.put(PollAckFlow.class, pollAckFlowProvider)
|
||||||
|
.put(PollRequestFlow.class, pollRequestFlowProvider)
|
||||||
|
.put(HelloFlow.class, helloFlowProvider)
|
||||||
|
.put(LoginFlow.class, loginFlowProvider)
|
||||||
|
.put(LogoutFlow.class, logoutFlowProvider)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
static Class<? extends Flow> provideFlowClass(EppInput eppInput) {
|
||||||
|
try {
|
||||||
|
return FlowPicker.getFlowClass(eppInput);
|
||||||
|
} catch (EppException e) {
|
||||||
|
throw new EppExceptionInProviderException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FlowScope
|
||||||
|
static Flow provideFlow(
|
||||||
|
Map<Class<? extends Flow>, Provider<? extends Flow>> flowProviders,
|
||||||
|
Class<? extends Flow> flowClass) {
|
||||||
|
return flowProviders.get(flowClass).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Wrapper class to carry an {@link EppException} to the calling code. */
|
||||||
|
static class EppExceptionInProviderException extends RuntimeException {
|
||||||
|
EppExceptionInProviderException(EppException exception) {
|
||||||
|
super(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dagger qualifier for inputXml. */
|
||||||
|
@Qualifier
|
||||||
|
@Documented
|
||||||
|
public @interface InputXml {}
|
||||||
|
|
||||||
|
/** Dagger qualifier for registrar client id. */
|
||||||
|
@Qualifier
|
||||||
|
@Documented
|
||||||
|
public @interface ClientId {}
|
||||||
|
|
||||||
|
/** Dagger qualifier for whether a flow is in dry run mode. */
|
||||||
|
@Qualifier
|
||||||
|
@Documented
|
||||||
|
public @interface DryRun {}
|
||||||
|
|
||||||
|
/** Dagger qualifier for whether a flow is in superuser mode. */
|
||||||
|
@Qualifier
|
||||||
|
@Documented
|
||||||
|
public @interface Superuser {}
|
||||||
|
|
||||||
|
/** Dagger qualifier for whether a flow is transactional. */
|
||||||
|
@Qualifier
|
||||||
|
@Documented
|
||||||
|
public @interface Transactional {}
|
||||||
|
}
|
|
@ -23,16 +23,24 @@ import com.google.common.base.Strings;
|
||||||
|
|
||||||
import com.googlecode.objectify.Work;
|
import com.googlecode.objectify.Work;
|
||||||
|
|
||||||
|
import google.registry.flows.FlowModule.ClientId;
|
||||||
|
import google.registry.flows.FlowModule.DryRun;
|
||||||
|
import google.registry.flows.FlowModule.InputXml;
|
||||||
|
import google.registry.flows.FlowModule.Superuser;
|
||||||
|
import google.registry.flows.FlowModule.Transactional;
|
||||||
import google.registry.model.eppcommon.Trid;
|
import google.registry.model.eppcommon.Trid;
|
||||||
import google.registry.model.eppinput.EppInput;
|
import google.registry.model.eppinput.EppInput;
|
||||||
import google.registry.model.eppoutput.EppOutput;
|
import google.registry.model.eppoutput.EppOutput;
|
||||||
import google.registry.monitoring.whitebox.EppMetrics;
|
import google.registry.monitoring.whitebox.EppMetrics;
|
||||||
import google.registry.util.Clock;
|
import google.registry.util.Clock;
|
||||||
import google.registry.util.FormattingLogger;
|
import google.registry.util.FormattingLogger;
|
||||||
import google.registry.util.TypeUtils;
|
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
|
||||||
/** Run a flow, either transactionally or not, with logging and retrying as needed. */
|
/** Run a flow, either transactionally or not, with logging and retrying as needed. */
|
||||||
public class FlowRunner {
|
public class FlowRunner {
|
||||||
|
|
||||||
|
@ -40,43 +48,20 @@ public class FlowRunner {
|
||||||
|
|
||||||
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
|
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
|
||||||
|
|
||||||
private final Class<? extends Flow> flowClass;
|
@Inject @Nullable @ClientId String clientId;
|
||||||
private final EppInput eppInput;
|
@Inject Clock clock;
|
||||||
private final Trid trid;
|
@Inject TransportCredentials credentials;
|
||||||
private final SessionMetadata sessionMetadata;
|
@Inject EppInput eppInput;
|
||||||
private final TransportCredentials credentials;
|
@Inject EppRequestSource eppRequestSource;
|
||||||
private final EppRequestSource eppRequestSource;
|
@Inject Provider<Flow> flowProvider;
|
||||||
private final boolean isDryRun;
|
@Inject @InputXml byte[] inputXmlBytes;
|
||||||
private final boolean isSuperuser;
|
@Inject @DryRun boolean isDryRun;
|
||||||
private final byte[] inputXmlBytes;
|
@Inject @Superuser boolean isSuperuser;
|
||||||
private final EppMetrics metrics;
|
@Inject @Transactional boolean isTransactional;
|
||||||
private final Clock clock;
|
@Inject EppMetrics metrics;
|
||||||
|
@Inject SessionMetadata sessionMetadata;
|
||||||
|
@Inject Trid trid;
|
||||||
public FlowRunner(
|
@Inject FlowRunner() {}
|
||||||
Class<? extends Flow> flowClass,
|
|
||||||
EppInput eppInput,
|
|
||||||
Trid trid,
|
|
||||||
SessionMetadata sessionMetadata,
|
|
||||||
TransportCredentials credentials,
|
|
||||||
EppRequestSource eppRequestSource,
|
|
||||||
boolean isDryRun,
|
|
||||||
boolean isSuperuser,
|
|
||||||
byte[] inputXmlBytes,
|
|
||||||
final EppMetrics metrics,
|
|
||||||
Clock clock) {
|
|
||||||
this.flowClass = flowClass;
|
|
||||||
this.eppInput = eppInput;
|
|
||||||
this.trid = trid;
|
|
||||||
this.sessionMetadata = sessionMetadata;
|
|
||||||
this.credentials = credentials;
|
|
||||||
this.eppRequestSource = eppRequestSource;
|
|
||||||
this.isDryRun = isDryRun;
|
|
||||||
this.isSuperuser = isSuperuser;
|
|
||||||
this.inputXmlBytes = inputXmlBytes;
|
|
||||||
this.metrics = metrics;
|
|
||||||
this.clock = clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EppOutput run() throws EppException {
|
public EppOutput run() throws EppException {
|
||||||
String clientId = sessionMetadata.getClientId();
|
String clientId = sessionMetadata.getClientId();
|
||||||
|
@ -90,10 +75,8 @@ public class FlowRunner {
|
||||||
eppRequestSource,
|
eppRequestSource,
|
||||||
isDryRun ? "DRY_RUN" : "LIVE",
|
isDryRun ? "DRY_RUN" : "LIVE",
|
||||||
isSuperuser ? "SUPERUSER" : "NORMAL");
|
isSuperuser ? "SUPERUSER" : "NORMAL");
|
||||||
if (!isTransactional()) {
|
if (!isTransactional) {
|
||||||
if (metrics != null) {
|
|
||||||
metrics.incrementAttempts();
|
metrics.incrementAttempts();
|
||||||
}
|
|
||||||
return createAndInitFlow(clock.nowUtc()).run();
|
return createAndInitFlow(clock.nowUtc()).run();
|
||||||
}
|
}
|
||||||
// We log the command in a structured format. Note that we do this before the transaction;
|
// We log the command in a structured format. Note that we do this before the transaction;
|
||||||
|
@ -107,9 +90,7 @@ public class FlowRunner {
|
||||||
EppOutput flowResult = ofy().transact(new Work<EppOutput>() {
|
EppOutput flowResult = ofy().transact(new Work<EppOutput>() {
|
||||||
@Override
|
@Override
|
||||||
public EppOutput run() {
|
public EppOutput run() {
|
||||||
if (metrics != null) {
|
|
||||||
metrics.incrementAttempts();
|
metrics.incrementAttempts();
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
EppOutput output = createAndInitFlow(ofy().getTransactionTime()).run();
|
EppOutput output = createAndInitFlow(ofy().getTransactionTime()).run();
|
||||||
if (isDryRun) {
|
if (isDryRun) {
|
||||||
|
@ -137,7 +118,7 @@ public class FlowRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Flow createAndInitFlow(DateTime now) throws EppException {
|
private Flow createAndInitFlow(DateTime now) throws EppException {
|
||||||
return TypeUtils.<Flow>instantiate(flowClass).init(
|
return flowProvider.get().init(
|
||||||
eppInput,
|
eppInput,
|
||||||
trid,
|
trid,
|
||||||
sessionMetadata,
|
sessionMetadata,
|
||||||
|
@ -148,10 +129,6 @@ public class FlowRunner {
|
||||||
inputXmlBytes);
|
inputXmlBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTransactional() {
|
|
||||||
return TransactionalFlow.class.isAssignableFrom(flowClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper for logging in json format.
|
* Helper for logging in json format.
|
||||||
*
|
*
|
||||||
|
|
35
java/google/registry/flows/FlowScope.java
Normal file
35
java/google/registry/flows/FlowScope.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2016 The Domain Registry 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.flows;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.inject.Scope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dagger annotation for flow-scoped components.
|
||||||
|
*
|
||||||
|
* <p>Note that this scope survives across transactional retries of a flow. That is, it is scoped to
|
||||||
|
* the overall execution of a flow, and not to a specific attempt.
|
||||||
|
*/
|
||||||
|
@Scope
|
||||||
|
@Documented
|
||||||
|
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface FlowScope {}
|
|
@ -27,12 +27,17 @@ import google.registry.model.eppoutput.CheckData.ContactCheckData;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that checks whether a contact can be provisioned.
|
* An EPP flow that checks whether a contact can be provisioned.
|
||||||
*
|
*
|
||||||
* @error {@link google.registry.flows.ResourceCheckFlow.TooManyResourceChecksException}
|
* @error {@link google.registry.flows.ResourceCheckFlow.TooManyResourceChecksException}
|
||||||
*/
|
*/
|
||||||
public class ContactCheckFlow extends ResourceCheckFlow<ContactResource, Check> {
|
public class ContactCheckFlow extends ResourceCheckFlow<ContactResource, Check> {
|
||||||
|
|
||||||
|
@Inject ContactCheckFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CheckData getCheckData() {
|
protected CheckData getCheckData() {
|
||||||
Set<String> existingIds = checkResourcesExist(resourceClass, targetIds, now);
|
Set<String> existingIds = checkResourcesExist(resourceClass, targetIds, now);
|
||||||
|
|
|
@ -29,6 +29,8 @@ import google.registry.model.eppoutput.EppOutput;
|
||||||
import google.registry.model.ofy.ObjectifyService;
|
import google.registry.model.ofy.ObjectifyService;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that creates a new contact resource.
|
* An EPP flow that creates a new contact resource.
|
||||||
*
|
*
|
||||||
|
@ -37,6 +39,9 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
* @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException}
|
* @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException}
|
||||||
*/
|
*/
|
||||||
public class ContactCreateFlow extends ResourceCreateFlow<ContactResource, Builder, Create> {
|
public class ContactCreateFlow extends ResourceCreateFlow<ContactResource, Builder, Create> {
|
||||||
|
|
||||||
|
@Inject ContactCreateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected EppOutput getOutput() {
|
protected EppOutput getOutput() {
|
||||||
return createOutput(Success, ContactCreateData.create(newResource.getContactId(), now));
|
return createOutput(Success, ContactCreateData.create(newResource.getContactId(), now));
|
||||||
|
|
|
@ -36,6 +36,8 @@ import google.registry.model.contact.ContactResource.Builder;
|
||||||
import google.registry.model.domain.DomainBase;
|
import google.registry.model.domain.DomainBase;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that deletes a contact resource.
|
* An EPP flow that deletes a contact resource.
|
||||||
*
|
*
|
||||||
|
@ -49,6 +51,8 @@ public class ContactDeleteFlow extends ResourceAsyncDeleteFlow<ContactResource,
|
||||||
/** In {@link #isLinkedForFailfast}, check this (arbitrary) number of resources from the query. */
|
/** In {@link #isLinkedForFailfast}, check this (arbitrary) number of resources from the query. */
|
||||||
private static final int FAILFAST_CHECK_COUNT = 5;
|
private static final int FAILFAST_CHECK_COUNT = 5;
|
||||||
|
|
||||||
|
@Inject ContactDeleteFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isLinkedForFailfast(final Ref<ContactResource> ref) {
|
protected boolean isLinkedForFailfast(final Ref<ContactResource> ref) {
|
||||||
// Query for the first few linked domains, and if found, actually load them. The query is
|
// Query for the first few linked domains, and if found, actually load them. The query is
|
||||||
|
|
|
@ -18,10 +18,14 @@ import google.registry.flows.ResourceInfoFlow;
|
||||||
import google.registry.model.contact.ContactCommand.Info;
|
import google.registry.model.contact.ContactCommand.Info;
|
||||||
import google.registry.model.contact.ContactResource;
|
import google.registry.model.contact.ContactResource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that reads a contact.
|
* An EPP flow that reads a contact.
|
||||||
*
|
*
|
||||||
* @error {@link google.registry.flows.ResourceQueryFlow.ResourceToQueryDoesNotExistException}
|
* @error {@link google.registry.flows.ResourceQueryFlow.ResourceToQueryDoesNotExistException}
|
||||||
*/
|
*/
|
||||||
public class ContactInfoFlow extends ResourceInfoFlow<ContactResource, Info> {}
|
public class ContactInfoFlow extends ResourceInfoFlow<ContactResource, Info> {
|
||||||
|
@Inject ContactInfoFlow() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ import google.registry.model.contact.ContactResource;
|
||||||
import google.registry.model.contact.ContactResource.Builder;
|
import google.registry.model.contact.ContactResource.Builder;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that approves a pending transfer on a {@link ContactResource}.
|
* An EPP flow that approves a pending transfer on a {@link ContactResource}.
|
||||||
*
|
*
|
||||||
|
@ -30,6 +32,9 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
*/
|
*/
|
||||||
public class ContactTransferApproveFlow
|
public class ContactTransferApproveFlow
|
||||||
extends ResourceTransferApproveFlow<ContactResource, Builder, Transfer> {
|
extends ResourceTransferApproveFlow<ContactResource, Builder, Transfer> {
|
||||||
|
|
||||||
|
@Inject ContactTransferApproveFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final HistoryEntry.Type getHistoryEntryType() {
|
protected final HistoryEntry.Type getHistoryEntryType() {
|
||||||
return HistoryEntry.Type.CONTACT_TRANSFER_APPROVE;
|
return HistoryEntry.Type.CONTACT_TRANSFER_APPROVE;
|
||||||
|
|
|
@ -20,6 +20,8 @@ import google.registry.model.contact.ContactResource;
|
||||||
import google.registry.model.contact.ContactResource.Builder;
|
import google.registry.model.contact.ContactResource.Builder;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that cancels a pending transfer on a {@link ContactResource}.
|
* An EPP flow that cancels a pending transfer on a {@link ContactResource}.
|
||||||
*
|
*
|
||||||
|
@ -30,6 +32,9 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
*/
|
*/
|
||||||
public class ContactTransferCancelFlow
|
public class ContactTransferCancelFlow
|
||||||
extends ResourceTransferCancelFlow<ContactResource, Builder, Transfer> {
|
extends ResourceTransferCancelFlow<ContactResource, Builder, Transfer> {
|
||||||
|
|
||||||
|
@Inject ContactTransferCancelFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final HistoryEntry.Type getHistoryEntryType() {
|
protected final HistoryEntry.Type getHistoryEntryType() {
|
||||||
return HistoryEntry.Type.CONTACT_TRANSFER_CANCEL;
|
return HistoryEntry.Type.CONTACT_TRANSFER_CANCEL;
|
||||||
|
|
|
@ -18,6 +18,8 @@ import google.registry.flows.ResourceTransferQueryFlow;
|
||||||
import google.registry.model.contact.ContactCommand.Transfer;
|
import google.registry.model.contact.ContactCommand.Transfer;
|
||||||
import google.registry.model.contact.ContactResource;
|
import google.registry.model.contact.ContactResource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that queries a pending transfer on a {@link ContactResource}.
|
* An EPP flow that queries a pending transfer on a {@link ContactResource}.
|
||||||
*
|
*
|
||||||
|
@ -27,4 +29,5 @@ import google.registry.model.contact.ContactResource;
|
||||||
* @error {@link google.registry.flows.ResourceTransferQueryFlow.NotAuthorizedToViewTransferException}
|
* @error {@link google.registry.flows.ResourceTransferQueryFlow.NotAuthorizedToViewTransferException}
|
||||||
*/
|
*/
|
||||||
public class ContactTransferQueryFlow extends ResourceTransferQueryFlow<ContactResource, Transfer> {
|
public class ContactTransferQueryFlow extends ResourceTransferQueryFlow<ContactResource, Transfer> {
|
||||||
|
@Inject ContactTransferQueryFlow() {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import google.registry.model.contact.ContactResource;
|
||||||
import google.registry.model.contact.ContactResource.Builder;
|
import google.registry.model.contact.ContactResource.Builder;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that rejects a pending transfer on a {@link ContactResource}.
|
* An EPP flow that rejects a pending transfer on a {@link ContactResource}.
|
||||||
*
|
*
|
||||||
|
@ -30,6 +32,9 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
*/
|
*/
|
||||||
public class ContactTransferRejectFlow
|
public class ContactTransferRejectFlow
|
||||||
extends ResourceTransferRejectFlow<ContactResource, Builder, Transfer> {
|
extends ResourceTransferRejectFlow<ContactResource, Builder, Transfer> {
|
||||||
|
|
||||||
|
@Inject ContactTransferRejectFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final HistoryEntry.Type getHistoryEntryType() {
|
protected final HistoryEntry.Type getHistoryEntryType() {
|
||||||
return HistoryEntry.Type.CONTACT_TRANSFER_REJECT;
|
return HistoryEntry.Type.CONTACT_TRANSFER_REJECT;
|
||||||
|
|
|
@ -22,6 +22,8 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
import org.joda.time.Duration;
|
import org.joda.time.Duration;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that requests a transfer on a {@link ContactResource}.
|
* An EPP flow that requests a transfer on a {@link ContactResource}.
|
||||||
*
|
*
|
||||||
|
@ -34,6 +36,8 @@ import org.joda.time.Duration;
|
||||||
public class ContactTransferRequestFlow
|
public class ContactTransferRequestFlow
|
||||||
extends ResourceTransferRequestFlow<ContactResource, Transfer> {
|
extends ResourceTransferRequestFlow<ContactResource, Transfer> {
|
||||||
|
|
||||||
|
@Inject ContactTransferRequestFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final HistoryEntry.Type getHistoryEntryType() {
|
protected final HistoryEntry.Type getHistoryEntryType() {
|
||||||
return HistoryEntry.Type.CONTACT_TRANSFER_REQUEST;
|
return HistoryEntry.Type.CONTACT_TRANSFER_REQUEST;
|
||||||
|
|
|
@ -24,6 +24,8 @@ import google.registry.model.contact.ContactResource;
|
||||||
import google.registry.model.contact.ContactResource.Builder;
|
import google.registry.model.contact.ContactResource.Builder;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that updates a contact resource.
|
* An EPP flow that updates a contact resource.
|
||||||
*
|
*
|
||||||
|
@ -36,6 +38,9 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
* @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException}
|
* @error {@link ContactFlowUtils.DeclineContactDisclosureFieldDisallowedPolicyException}
|
||||||
*/
|
*/
|
||||||
public class ContactUpdateFlow extends ResourceUpdateFlow<ContactResource, Builder, Update> {
|
public class ContactUpdateFlow extends ResourceUpdateFlow<ContactResource, Builder, Update> {
|
||||||
|
|
||||||
|
@Inject ContactUpdateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void verifyNewUpdatedStateIsAllowed() throws EppException {
|
protected void verifyNewUpdatedStateIsAllowed() throws EppException {
|
||||||
validateAsciiPostalInfo(newResource.getInternationalizedPostalInfo());
|
validateAsciiPostalInfo(newResource.getInternationalizedPostalInfo());
|
||||||
|
|
|
@ -35,6 +35,8 @@ import google.registry.model.tmch.ClaimsListShard;
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that checks whether strings are trademarked.
|
* An EPP flow that checks whether strings are trademarked.
|
||||||
*
|
*
|
||||||
|
@ -48,6 +50,8 @@ public class ClaimsCheckFlow extends BaseDomainCheckFlow {
|
||||||
public static final ImmutableSet<TldState> DISALLOWED_TLD_STATES = Sets.immutableEnumSet(
|
public static final ImmutableSet<TldState> DISALLOWED_TLD_STATES = Sets.immutableEnumSet(
|
||||||
TldState.PREDELEGATION, TldState.SUNRISE);
|
TldState.PREDELEGATION, TldState.SUNRISE);
|
||||||
|
|
||||||
|
@Inject ClaimsCheckFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDomainCheckFlow() throws EppException {
|
protected void initDomainCheckFlow() throws EppException {
|
||||||
registerExtensions(LaunchCheckExtension.class);
|
registerExtensions(LaunchCheckExtension.class);
|
||||||
|
|
|
@ -48,6 +48,8 @@ import google.registry.model.registry.label.ReservationType;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.tmch.LordnTask;
|
import google.registry.tmch.LordnTask;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that allocates a new domain resource from a domain application.
|
* An EPP flow that allocates a new domain resource from a domain application.
|
||||||
*
|
*
|
||||||
|
@ -62,6 +64,8 @@ public class DomainAllocateFlow extends DomainCreateOrAllocateFlow {
|
||||||
protected AllocateCreateExtension allocateCreate;
|
protected AllocateCreateExtension allocateCreate;
|
||||||
protected DomainApplication application;
|
protected DomainApplication application;
|
||||||
|
|
||||||
|
@Inject DomainAllocateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void initDomainCreateOrAllocateFlow() {
|
protected final void initDomainCreateOrAllocateFlow() {
|
||||||
registerExtensions(AllocateCreateExtension.class);
|
registerExtensions(AllocateCreateExtension.class);
|
||||||
|
|
|
@ -51,6 +51,8 @@ import google.registry.model.smd.EncodedSignedMark;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that creates a new application for a domain resource.
|
* An EPP flow that creates a new application for a domain resource.
|
||||||
*
|
*
|
||||||
|
@ -114,6 +116,8 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class DomainApplicationCreateFlow extends BaseDomainCreateFlow<DomainApplication, Builder> {
|
public class DomainApplicationCreateFlow extends BaseDomainCreateFlow<DomainApplication, Builder> {
|
||||||
|
|
||||||
|
@Inject DomainApplicationCreateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDomainCreateFlow() {
|
protected void initDomainCreateFlow() {
|
||||||
registerExtensions(FeeCreateExtension.class, LaunchCreateExtension.class);
|
registerExtensions(FeeCreateExtension.class, LaunchCreateExtension.class);
|
||||||
|
|
|
@ -36,6 +36,8 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that deletes a domain application.
|
* An EPP flow that deletes a domain application.
|
||||||
*
|
*
|
||||||
|
@ -51,6 +53,8 @@ import java.util.Set;
|
||||||
public class DomainApplicationDeleteFlow
|
public class DomainApplicationDeleteFlow
|
||||||
extends ResourceSyncDeleteFlow<DomainApplication, Builder, Delete> {
|
extends ResourceSyncDeleteFlow<DomainApplication, Builder, Delete> {
|
||||||
|
|
||||||
|
@Inject DomainApplicationDeleteFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initResourceCreateOrMutateFlow() throws EppException {
|
protected void initResourceCreateOrMutateFlow() throws EppException {
|
||||||
registerExtensions(LaunchDeleteExtension.class);
|
registerExtensions(LaunchDeleteExtension.class);
|
||||||
|
|
|
@ -32,6 +32,8 @@ import google.registry.model.mark.Mark;
|
||||||
import google.registry.model.smd.EncodedSignedMark;
|
import google.registry.model.smd.EncodedSignedMark;
|
||||||
import google.registry.model.smd.SignedMark;
|
import google.registry.model.smd.SignedMark;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that reads a domain application.
|
* An EPP flow that reads a domain application.
|
||||||
*
|
*
|
||||||
|
@ -45,6 +47,8 @@ public class DomainApplicationInfoFlow extends BaseDomainInfoFlow<DomainApplicat
|
||||||
|
|
||||||
private boolean includeMarks;
|
private boolean includeMarks;
|
||||||
|
|
||||||
|
@Inject DomainApplicationInfoFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void initSingleResourceFlow() throws EppException {
|
protected final void initSingleResourceFlow() throws EppException {
|
||||||
registerExtensions(LaunchInfoExtension.class);
|
registerExtensions(LaunchInfoExtension.class);
|
||||||
|
|
|
@ -30,6 +30,8 @@ import google.registry.model.domain.secdns.SecDnsUpdateExtension;
|
||||||
import google.registry.model.registry.Registry.TldState;
|
import google.registry.model.registry.Registry.TldState;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that updates a domain resource.
|
* An EPP flow that updates a domain resource.
|
||||||
*
|
*
|
||||||
|
@ -59,6 +61,8 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
public class DomainApplicationUpdateFlow
|
public class DomainApplicationUpdateFlow
|
||||||
extends BaseDomainUpdateFlow<DomainApplication, Builder> {
|
extends BaseDomainUpdateFlow<DomainApplication, Builder> {
|
||||||
|
|
||||||
|
@Inject DomainApplicationUpdateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDomainUpdateFlow() throws EppException {
|
protected void initDomainUpdateFlow() throws EppException {
|
||||||
registerExtensions(LaunchUpdateExtension.class, SecDnsUpdateExtension.class);
|
registerExtensions(LaunchUpdateExtension.class, SecDnsUpdateExtension.class);
|
||||||
|
|
|
@ -48,6 +48,8 @@ import google.registry.model.registry.label.ReservationType;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that checks whether a domain can be provisioned.
|
* An EPP flow that checks whether a domain can be provisioned.
|
||||||
*
|
*
|
||||||
|
@ -81,6 +83,8 @@ public class DomainCheckFlow extends BaseDomainCheckFlow {
|
||||||
|
|
||||||
protected RegTypeCheckExtension regTypeExtension;
|
protected RegTypeCheckExtension regTypeExtension;
|
||||||
|
|
||||||
|
@Inject DomainCheckFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDomainCheckFlow() throws EppException {
|
protected void initDomainCheckFlow() throws EppException {
|
||||||
registerExtensions(
|
registerExtensions(
|
||||||
|
|
|
@ -41,6 +41,8 @@ import google.registry.tmch.LordnTask;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that creates a new domain resource.
|
* An EPP flow that creates a new domain resource.
|
||||||
*
|
*
|
||||||
|
@ -101,6 +103,8 @@ public class DomainCreateFlow extends DomainCreateOrAllocateFlow {
|
||||||
|
|
||||||
protected RegTypeCreateExtension regTypeExtension;
|
protected RegTypeCreateExtension regTypeExtension;
|
||||||
|
|
||||||
|
@Inject DomainCreateFlow() {}
|
||||||
|
|
||||||
private boolean isAnchorTenant() {
|
private boolean isAnchorTenant() {
|
||||||
return isAnchorTenantViaReservation || isAnchorTenantViaExtension;
|
return isAnchorTenantViaReservation || isAnchorTenantViaExtension;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,8 @@ import org.joda.money.CurrencyUnit;
|
||||||
import org.joda.money.Money;
|
import org.joda.money.Money;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that deletes a domain resource.
|
* An EPP flow that deletes a domain resource.
|
||||||
*
|
*
|
||||||
|
@ -73,6 +75,8 @@ public class DomainDeleteFlow extends ResourceSyncDeleteFlow<DomainResource, Bui
|
||||||
|
|
||||||
ImmutableList<Credit> credits;
|
ImmutableList<Credit> credits;
|
||||||
|
|
||||||
|
@Inject DomainDeleteFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initResourceCreateOrMutateFlow() throws EppException {
|
protected void initResourceCreateOrMutateFlow() throws EppException {
|
||||||
registerExtensions(SecDnsUpdateExtension.class);
|
registerExtensions(SecDnsUpdateExtension.class);
|
||||||
|
|
|
@ -31,6 +31,8 @@ import google.registry.model.eppoutput.EppResponse.ResponseExtension;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that reads a domain.
|
* An EPP flow that reads a domain.
|
||||||
*
|
*
|
||||||
|
@ -45,6 +47,8 @@ public class DomainInfoFlow extends BaseDomainInfoFlow<DomainResource, Builder>
|
||||||
|
|
||||||
protected List<String> registrationTypes;
|
protected List<String> registrationTypes;
|
||||||
|
|
||||||
|
@Inject DomainInfoFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initSingleResourceFlow() throws EppException {
|
protected void initSingleResourceFlow() throws EppException {
|
||||||
registerExtensions(FeeInfoExtension.class);
|
registerExtensions(FeeInfoExtension.class);
|
||||||
|
|
|
@ -59,6 +59,8 @@ import org.joda.time.DateTime;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that updates a domain resource.
|
* An EPP flow that updates a domain resource.
|
||||||
*
|
*
|
||||||
|
@ -86,6 +88,8 @@ public class DomainRenewFlow extends OwnedResourceMutateFlow<DomainResource, Ren
|
||||||
protected FeeRenewExtension feeRenew;
|
protected FeeRenewExtension feeRenew;
|
||||||
protected Money renewCost;
|
protected Money renewCost;
|
||||||
|
|
||||||
|
@Inject DomainRenewFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Set<StatusValue> getDisallowedStatuses() {
|
protected Set<StatusValue> getDisallowedStatuses() {
|
||||||
return RENEW_DISALLOWED_STATUSES;
|
return RENEW_DISALLOWED_STATUSES;
|
||||||
|
|
|
@ -54,6 +54,8 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
import org.joda.money.Money;
|
import org.joda.money.Money;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that requests that a deleted domain be restored.
|
* An EPP flow that requests that a deleted domain be restored.
|
||||||
*
|
*
|
||||||
|
@ -77,6 +79,8 @@ public class DomainRestoreRequestFlow extends OwnedResourceMutateFlow<DomainReso
|
||||||
protected Money restoreCost;
|
protected Money restoreCost;
|
||||||
protected Money renewCost;
|
protected Money renewCost;
|
||||||
|
|
||||||
|
@Inject DomainRestoreRequestFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void initResourceCreateOrMutateFlow() throws EppException {
|
protected final void initResourceCreateOrMutateFlow() throws EppException {
|
||||||
registerExtensions(FeeUpdateExtension.class, RgpUpdateExtension.class);
|
registerExtensions(FeeUpdateExtension.class, RgpUpdateExtension.class);
|
||||||
|
|
|
@ -45,6 +45,8 @@ import google.registry.model.transfer.TransferData;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that approves a pending transfer on a {@link DomainResource}.
|
* An EPP flow that approves a pending transfer on a {@link DomainResource}.
|
||||||
*
|
*
|
||||||
|
@ -60,6 +62,8 @@ import org.joda.time.DateTime;
|
||||||
public class DomainTransferApproveFlow extends
|
public class DomainTransferApproveFlow extends
|
||||||
ResourceTransferApproveFlow<DomainResource, Builder, Transfer> {
|
ResourceTransferApproveFlow<DomainResource, Builder, Transfer> {
|
||||||
|
|
||||||
|
@Inject DomainTransferApproveFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void verifyOwnedResourcePendingTransferMutationAllowed() throws EppException {
|
protected void verifyOwnedResourcePendingTransferMutationAllowed() throws EppException {
|
||||||
checkAllowedAccessToTld(getAllowedTlds(), existingResource.getTld());
|
checkAllowedAccessToTld(getAllowedTlds(), existingResource.getTld());
|
||||||
|
|
|
@ -25,6 +25,8 @@ import google.registry.model.domain.DomainResource;
|
||||||
import google.registry.model.domain.DomainResource.Builder;
|
import google.registry.model.domain.DomainResource.Builder;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that cancels a pending transfer on a {@link DomainResource}.
|
* An EPP flow that cancels a pending transfer on a {@link DomainResource}.
|
||||||
*
|
*
|
||||||
|
@ -37,6 +39,8 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
public class DomainTransferCancelFlow
|
public class DomainTransferCancelFlow
|
||||||
extends ResourceTransferCancelFlow<DomainResource, Builder, Transfer> {
|
extends ResourceTransferCancelFlow<DomainResource, Builder, Transfer> {
|
||||||
|
|
||||||
|
@Inject DomainTransferCancelFlow() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reopen the autorenew event and poll message that we closed for the implicit transfer.
|
* Reopen the autorenew event and poll message that we closed for the implicit transfer.
|
||||||
* This may end up recreating the autorenew poll message if it was deleted when the transfer
|
* This may end up recreating the autorenew poll message if it was deleted when the transfer
|
||||||
|
|
|
@ -18,6 +18,8 @@ import google.registry.flows.ResourceTransferQueryFlow;
|
||||||
import google.registry.model.domain.DomainCommand.Transfer;
|
import google.registry.model.domain.DomainCommand.Transfer;
|
||||||
import google.registry.model.domain.DomainResource;
|
import google.registry.model.domain.DomainResource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that queries a pending transfer on a {@link DomainResource}.
|
* An EPP flow that queries a pending transfer on a {@link DomainResource}.
|
||||||
*
|
*
|
||||||
|
@ -26,4 +28,6 @@ import google.registry.model.domain.DomainResource;
|
||||||
* @error {@link google.registry.flows.ResourceTransferQueryFlow.NoTransferHistoryToQueryException}
|
* @error {@link google.registry.flows.ResourceTransferQueryFlow.NoTransferHistoryToQueryException}
|
||||||
* @error {@link google.registry.flows.ResourceTransferQueryFlow.NotAuthorizedToViewTransferException}
|
* @error {@link google.registry.flows.ResourceTransferQueryFlow.NotAuthorizedToViewTransferException}
|
||||||
*/
|
*/
|
||||||
public class DomainTransferQueryFlow extends ResourceTransferQueryFlow<DomainResource, Transfer> {}
|
public class DomainTransferQueryFlow extends ResourceTransferQueryFlow<DomainResource, Transfer> {
|
||||||
|
@Inject DomainTransferQueryFlow() {}
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ import google.registry.model.domain.DomainResource;
|
||||||
import google.registry.model.domain.DomainResource.Builder;
|
import google.registry.model.domain.DomainResource.Builder;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that rejects a pending transfer on a {@link DomainResource}.
|
* An EPP flow that rejects a pending transfer on a {@link DomainResource}.
|
||||||
*
|
*
|
||||||
|
@ -37,6 +39,8 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
public class DomainTransferRejectFlow
|
public class DomainTransferRejectFlow
|
||||||
extends ResourceTransferRejectFlow<DomainResource, Builder, Transfer> {
|
extends ResourceTransferRejectFlow<DomainResource, Builder, Transfer> {
|
||||||
|
|
||||||
|
@Inject DomainTransferRejectFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void verifyOwnedResourcePendingTransferMutationAllowed() throws EppException {
|
protected void verifyOwnedResourcePendingTransferMutationAllowed() throws EppException {
|
||||||
checkAllowedAccessToTld(getAllowedTlds(), existingResource.getTld());
|
checkAllowedAccessToTld(getAllowedTlds(), existingResource.getTld());
|
||||||
|
|
|
@ -56,6 +56,8 @@ import org.joda.time.Duration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that requests a transfer on a {@link DomainResource}.
|
* An EPP flow that requests a transfer on a {@link DomainResource}.
|
||||||
*
|
*
|
||||||
|
@ -97,6 +99,8 @@ public class DomainTransferRequestFlow
|
||||||
*/
|
*/
|
||||||
private FeeTransferExtension feeTransfer;
|
private FeeTransferExtension feeTransfer;
|
||||||
|
|
||||||
|
@Inject DomainTransferRequestFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Duration getAutomaticTransferLength() {
|
protected Duration getAutomaticTransferLength() {
|
||||||
return Registry.get(existingResource.getTld()).getAutomaticTransferLength();
|
return Registry.get(existingResource.getTld()).getAutomaticTransferLength();
|
||||||
|
|
|
@ -39,6 +39,8 @@ import org.joda.time.DateTime;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that updates a domain resource.
|
* An EPP flow that updates a domain resource.
|
||||||
*
|
*
|
||||||
|
@ -70,6 +72,8 @@ public class DomainUpdateFlow extends BaseDomainUpdateFlow<DomainResource, Build
|
||||||
|
|
||||||
protected RegTypeUpdateExtension regTypeExtension;
|
protected RegTypeUpdateExtension regTypeExtension;
|
||||||
|
|
||||||
|
@Inject DomainUpdateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDomainUpdateFlow() {
|
protected void initDomainUpdateFlow() {
|
||||||
registerExtensions(SecDnsUpdateExtension.class, RegTypeUpdateExtension.class);
|
registerExtensions(SecDnsUpdateExtension.class, RegTypeUpdateExtension.class);
|
||||||
|
|
|
@ -27,12 +27,17 @@ import google.registry.model.host.HostResource;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that checks whether a host can be provisioned.
|
* An EPP flow that checks whether a host can be provisioned.
|
||||||
*
|
*
|
||||||
* @error {@link google.registry.flows.ResourceCheckFlow.TooManyResourceChecksException}
|
* @error {@link google.registry.flows.ResourceCheckFlow.TooManyResourceChecksException}
|
||||||
*/
|
*/
|
||||||
public class HostCheckFlow extends ResourceCheckFlow<HostResource, Check> {
|
public class HostCheckFlow extends ResourceCheckFlow<HostResource, Check> {
|
||||||
|
|
||||||
|
@Inject HostCheckFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CheckData getCheckData() {
|
protected CheckData getCheckData() {
|
||||||
Set<String> existingIds = checkResourcesExist(resourceClass, targetIds, now);
|
Set<String> existingIds = checkResourcesExist(resourceClass, targetIds, now);
|
||||||
|
|
|
@ -40,6 +40,8 @@ import google.registry.model.host.HostResource.Builder;
|
||||||
import google.registry.model.ofy.ObjectifyService;
|
import google.registry.model.ofy.ObjectifyService;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that creates a new host resource.
|
* An EPP flow that creates a new host resource.
|
||||||
*
|
*
|
||||||
|
@ -67,6 +69,8 @@ public class HostCreateFlow extends ResourceCreateFlow<HostResource, Builder, Cr
|
||||||
*/
|
*/
|
||||||
private Optional<Ref<DomainResource>> superordinateDomain;
|
private Optional<Ref<DomainResource>> superordinateDomain;
|
||||||
|
|
||||||
|
@Inject HostCreateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initResourceCreateOrMutateFlow() throws EppException {
|
protected void initResourceCreateOrMutateFlow() throws EppException {
|
||||||
superordinateDomain = Optional.fromNullable(lookupSuperordinateDomain(
|
superordinateDomain = Optional.fromNullable(lookupSuperordinateDomain(
|
||||||
|
|
|
@ -36,6 +36,8 @@ import google.registry.model.host.HostResource;
|
||||||
import google.registry.model.host.HostResource.Builder;
|
import google.registry.model.host.HostResource.Builder;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that deletes a host resource.
|
* An EPP flow that deletes a host resource.
|
||||||
*
|
*
|
||||||
|
@ -49,6 +51,8 @@ public class HostDeleteFlow extends ResourceAsyncDeleteFlow<HostResource, Builde
|
||||||
/** In {@link #isLinkedForFailfast}, check this (arbitrary) number of resources from the query. */
|
/** In {@link #isLinkedForFailfast}, check this (arbitrary) number of resources from the query. */
|
||||||
private static final int FAILFAST_CHECK_COUNT = 5;
|
private static final int FAILFAST_CHECK_COUNT = 5;
|
||||||
|
|
||||||
|
@Inject HostDeleteFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isLinkedForFailfast(final Ref<HostResource> ref) {
|
protected boolean isLinkedForFailfast(final Ref<HostResource> ref) {
|
||||||
// Query for the first few linked domains, and if found, actually load them. The query is
|
// Query for the first few linked domains, and if found, actually load them. The query is
|
||||||
|
|
|
@ -18,9 +18,13 @@ import google.registry.flows.ResourceInfoFlow;
|
||||||
import google.registry.model.host.HostCommand;
|
import google.registry.model.host.HostCommand;
|
||||||
import google.registry.model.host.HostResource;
|
import google.registry.model.host.HostResource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that reads a host.
|
* An EPP flow that reads a host.
|
||||||
*
|
*
|
||||||
* @error {@link google.registry.flows.ResourceQueryFlow.ResourceToQueryDoesNotExistException}
|
* @error {@link google.registry.flows.ResourceQueryFlow.ResourceToQueryDoesNotExistException}
|
||||||
*/
|
*/
|
||||||
public class HostInfoFlow extends ResourceInfoFlow<HostResource, HostCommand.Info> {}
|
public class HostInfoFlow extends ResourceInfoFlow<HostResource, HostCommand.Info> {
|
||||||
|
@Inject HostInfoFlow() {}
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ import org.joda.time.Duration;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow that updates a host resource.
|
* An EPP flow that updates a host resource.
|
||||||
*
|
*
|
||||||
|
@ -72,6 +74,8 @@ public class HostUpdateFlow extends ResourceUpdateFlow<HostResource, Builder, Up
|
||||||
private String newHostName;
|
private String newHostName;
|
||||||
private boolean isHostRename;
|
private boolean isHostRename;
|
||||||
|
|
||||||
|
@Inject HostUpdateFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initResourceCreateOrMutateFlow() throws EppException {
|
protected void initResourceCreateOrMutateFlow() throws EppException {
|
||||||
String suppliedNewHostName = command.getInnerChange().getFullyQualifiedHostName();
|
String suppliedNewHostName = command.getInnerChange().getFullyQualifiedHostName();
|
||||||
|
|
|
@ -35,6 +35,8 @@ import google.registry.model.poll.PollMessageExternalKeyConverter.PollMessageExt
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow for acknowledging poll messages.
|
* An EPP flow for acknowledging poll messages.
|
||||||
*
|
*
|
||||||
|
@ -45,6 +47,8 @@ import org.joda.time.DateTime;
|
||||||
*/
|
*/
|
||||||
public class PollAckFlow extends PollFlow implements TransactionalFlow {
|
public class PollAckFlow extends PollFlow implements TransactionalFlow {
|
||||||
|
|
||||||
|
@Inject PollAckFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final EppOutput run() throws EppException {
|
public final EppOutput run() throws EppException {
|
||||||
if (command.getMessageId() == null) {
|
if (command.getMessageId() == null) {
|
||||||
|
|
|
@ -29,6 +29,8 @@ import google.registry.model.poll.PollMessage;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow for requesting poll messages.
|
* An EPP flow for requesting poll messages.
|
||||||
*
|
*
|
||||||
|
@ -36,6 +38,8 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class PollRequestFlow extends PollFlow {
|
public class PollRequestFlow extends PollFlow {
|
||||||
|
|
||||||
|
@Inject PollRequestFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final EppOutput run() throws EppException {
|
public final EppOutput run() throws EppException {
|
||||||
if (command.getMessageId() != null) {
|
if (command.getMessageId() != null) {
|
||||||
|
|
|
@ -18,8 +18,13 @@ import google.registry.flows.Flow;
|
||||||
import google.registry.model.eppoutput.EppOutput;
|
import google.registry.model.eppoutput.EppOutput;
|
||||||
import google.registry.model.eppoutput.Greeting;
|
import google.registry.model.eppoutput.Greeting;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/** A flow for an Epp "hello". */
|
/** A flow for an Epp "hello". */
|
||||||
public class HelloFlow extends Flow {
|
public class HelloFlow extends Flow {
|
||||||
|
|
||||||
|
@Inject HelloFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EppOutput run() {
|
public EppOutput run() {
|
||||||
return EppOutput.create(Greeting.create(now));
|
return EppOutput.create(Greeting.create(now));
|
||||||
|
|
|
@ -41,6 +41,8 @@ import google.registry.util.FormattingLogger;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow for login.
|
* An EPP flow for login.
|
||||||
*
|
*
|
||||||
|
@ -68,6 +70,8 @@ public class LoginFlow extends Flow {
|
||||||
/** Maximum number of failed login attempts allowed per connection. */
|
/** Maximum number of failed login attempts allowed per connection. */
|
||||||
private static final int MAX_FAILED_LOGIN_ATTEMPTS_PER_CONNECTION = 3;
|
private static final int MAX_FAILED_LOGIN_ATTEMPTS_PER_CONNECTION = 3;
|
||||||
|
|
||||||
|
@Inject LoginFlow() {}
|
||||||
|
|
||||||
/** Run the flow and log errors. */
|
/** Run the flow and log errors. */
|
||||||
@Override
|
@Override
|
||||||
public final EppOutput run() throws EppException {
|
public final EppOutput run() throws EppException {
|
||||||
|
|
|
@ -20,12 +20,17 @@ import google.registry.flows.EppException;
|
||||||
import google.registry.flows.LoggedInFlow;
|
import google.registry.flows.LoggedInFlow;
|
||||||
import google.registry.model.eppoutput.EppOutput;
|
import google.registry.model.eppoutput.EppOutput;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An EPP flow for logout.
|
* An EPP flow for logout.
|
||||||
*
|
*
|
||||||
* @error {@link google.registry.flows.LoggedInFlow.NotLoggedInException}
|
* @error {@link google.registry.flows.LoggedInFlow.NotLoggedInException}
|
||||||
*/
|
*/
|
||||||
public class LogoutFlow extends LoggedInFlow {
|
public class LogoutFlow extends LoggedInFlow {
|
||||||
|
|
||||||
|
@Inject LogoutFlow() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final EppOutput run() throws EppException {
|
public final EppOutput run() throws EppException {
|
||||||
sessionMetadata.invalidate();
|
sessionMetadata.invalidate();
|
||||||
|
|
|
@ -20,6 +20,7 @@ import google.registry.flows.CheckApiAction;
|
||||||
import google.registry.flows.CheckApiAction.CheckApiModule;
|
import google.registry.flows.CheckApiAction.CheckApiModule;
|
||||||
import google.registry.flows.EppConsoleAction;
|
import google.registry.flows.EppConsoleAction;
|
||||||
import google.registry.flows.EppTlsAction;
|
import google.registry.flows.EppTlsAction;
|
||||||
|
import google.registry.flows.FlowComponent;
|
||||||
import google.registry.flows.TlsCredentials.EppTlsModule;
|
import google.registry.flows.TlsCredentials.EppTlsModule;
|
||||||
import google.registry.rdap.RdapAutnumAction;
|
import google.registry.rdap.RdapAutnumAction;
|
||||||
import google.registry.rdap.RdapDomainAction;
|
import google.registry.rdap.RdapDomainAction;
|
||||||
|
@ -57,6 +58,7 @@ interface FrontendRequestComponent {
|
||||||
ConsoleUiAction consoleUiAction();
|
ConsoleUiAction consoleUiAction();
|
||||||
EppConsoleAction eppConsoleAction();
|
EppConsoleAction eppConsoleAction();
|
||||||
EppTlsAction eppTlsAction();
|
EppTlsAction eppTlsAction();
|
||||||
|
FlowComponent.Builder flowComponentBuilder();
|
||||||
RdapAutnumAction rdapAutnumAction();
|
RdapAutnumAction rdapAutnumAction();
|
||||||
RegistrarPaymentAction registrarPaymentAction();
|
RegistrarPaymentAction registrarPaymentAction();
|
||||||
RegistrarPaymentSetupAction registrarPaymentSetupAction();
|
RegistrarPaymentSetupAction registrarPaymentSetupAction();
|
||||||
|
|
|
@ -19,6 +19,7 @@ import dagger.Subcomponent;
|
||||||
import google.registry.export.PublishDetailReportAction;
|
import google.registry.export.PublishDetailReportAction;
|
||||||
import google.registry.flows.EppToolAction;
|
import google.registry.flows.EppToolAction;
|
||||||
import google.registry.flows.EppToolAction.EppToolModule;
|
import google.registry.flows.EppToolAction.EppToolModule;
|
||||||
|
import google.registry.flows.FlowComponent;
|
||||||
import google.registry.loadtest.LoadTestAction;
|
import google.registry.loadtest.LoadTestAction;
|
||||||
import google.registry.loadtest.LoadTestModule;
|
import google.registry.loadtest.LoadTestModule;
|
||||||
import google.registry.mapreduce.MapreduceModule;
|
import google.registry.mapreduce.MapreduceModule;
|
||||||
|
@ -62,6 +63,7 @@ interface ToolsRequestComponent {
|
||||||
DeleteEntityAction deleteEntityAction();
|
DeleteEntityAction deleteEntityAction();
|
||||||
DeleteProberDataAction deleteProberDataAction();
|
DeleteProberDataAction deleteProberDataAction();
|
||||||
EppToolAction eppToolAction();
|
EppToolAction eppToolAction();
|
||||||
|
FlowComponent.Builder flowComponentBuilder();
|
||||||
GenerateZoneFilesAction generateZoneFilesAction();
|
GenerateZoneFilesAction generateZoneFilesAction();
|
||||||
KillAllCommitLogsAction killAllCommitLogsAction();
|
KillAllCommitLogsAction killAllCommitLogsAction();
|
||||||
KillAllEppResourcesAction killAllEppResourcesAction();
|
KillAllEppResourcesAction killAllEppResourcesAction();
|
||||||
|
|
|
@ -31,6 +31,7 @@ java_library(
|
||||||
"//java/com/google/common/net",
|
"//java/com/google/common/net",
|
||||||
"//third_party/java/appengine:appengine-api-testonly",
|
"//third_party/java/appengine:appengine-api-testonly",
|
||||||
"//third_party/java/appengine:appengine-testing",
|
"//third_party/java/appengine:appengine-testing",
|
||||||
|
"//third_party/java/dagger",
|
||||||
"//third_party/java/joda_money",
|
"//third_party/java/joda_money",
|
||||||
"//third_party/java/joda_time",
|
"//third_party/java/joda_time",
|
||||||
"//third_party/java/json_simple",
|
"//third_party/java/json_simple",
|
||||||
|
|
|
@ -19,17 +19,16 @@ import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
||||||
import static google.registry.testing.DatastoreHelper.persistReservedList;
|
import static google.registry.testing.DatastoreHelper.persistReservedList;
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
import google.registry.config.RegistryEnvironment;
|
import google.registry.config.RegistryEnvironment;
|
||||||
|
import google.registry.flows.EppTestComponent.FakesAndMocksModule;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.model.registry.Registry;
|
import google.registry.model.registry.Registry;
|
||||||
import google.registry.monitoring.whitebox.EppMetrics;
|
|
||||||
import google.registry.testing.AppEngineRule;
|
import google.registry.testing.AppEngineRule;
|
||||||
|
import google.registry.testing.FakeClock;
|
||||||
import google.registry.testing.FakeResponse;
|
import google.registry.testing.FakeResponse;
|
||||||
import google.registry.util.SystemClock;
|
|
||||||
|
|
||||||
import org.json.simple.JSONValue;
|
import org.json.simple.JSONValue;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -66,9 +65,11 @@ public class CheckApiActionTest {
|
||||||
action.domain = domain;
|
action.domain = domain;
|
||||||
action.response = new FakeResponse();
|
action.response = new FakeResponse();
|
||||||
action.config = RegistryEnvironment.UNITTEST.config();
|
action.config = RegistryEnvironment.UNITTEST.config();
|
||||||
action.eppController = new EppController();
|
action.eppController = DaggerEppTestComponent.builder()
|
||||||
action.eppController.clock = new SystemClock();
|
.fakesAndMocksModule(new FakesAndMocksModule(new FakeClock()))
|
||||||
action.eppController.metrics = mock(EppMetrics.class);
|
.build()
|
||||||
|
.startRequest()
|
||||||
|
.eppController();
|
||||||
action.run();
|
action.run();
|
||||||
return (Map<String, Object>) JSONValue.parse(((FakeResponse) action.response).getPayload());
|
return (Map<String, Object>) JSONValue.parse(((FakeResponse) action.response).getPayload());
|
||||||
}
|
}
|
||||||
|
|
171
javatests/google/registry/flows/EppCommitLogsTest.java
Normal file
171
javatests/google/registry/flows/EppCommitLogsTest.java
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
// Copyright 2016 The Domain Registry 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.flows;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static google.registry.model.EppResourceUtils.loadAtPointInTime;
|
||||||
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
|
import static google.registry.testing.DatastoreHelper.persistActiveContact;
|
||||||
|
import static google.registry.testing.DatastoreHelper.persistActiveHost;
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
|
import static org.joda.time.Duration.standardDays;
|
||||||
|
|
||||||
|
import com.googlecode.objectify.Key;
|
||||||
|
|
||||||
|
import google.registry.flows.EppTestComponent.FakesAndMocksModule;
|
||||||
|
import google.registry.model.domain.DomainResource;
|
||||||
|
import google.registry.model.ofy.Ofy;
|
||||||
|
import google.registry.testing.AppEngineRule;
|
||||||
|
import google.registry.testing.EppLoader;
|
||||||
|
import google.registry.testing.ExceptionRule;
|
||||||
|
import google.registry.testing.FakeClock;
|
||||||
|
import google.registry.testing.FakeHttpSession;
|
||||||
|
import google.registry.testing.InjectRule;
|
||||||
|
import google.registry.testing.ShardableTestCase;
|
||||||
|
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
/** Test that domain flows create the commit logs needed to reload at points in the past. */
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class EppCommitLogsTest extends ShardableTestCase {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final AppEngineRule appEngine = AppEngineRule.builder()
|
||||||
|
.withDatastore()
|
||||||
|
.withTaskQueue()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final ExceptionRule thrown = new ExceptionRule();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final InjectRule inject = new InjectRule();
|
||||||
|
|
||||||
|
private final FakeClock clock = new FakeClock(DateTime.now(UTC));
|
||||||
|
private EppLoader eppLoader;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() throws Exception {
|
||||||
|
createTld("tld");
|
||||||
|
inject.setStaticField(Ofy.class, "clock", clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runFlow() throws Exception {
|
||||||
|
SessionMetadata sessionMetadata = new HttpSessionMetadata(new FakeHttpSession());
|
||||||
|
sessionMetadata.setClientId("TheRegistrar");
|
||||||
|
DaggerEppTestComponent.builder()
|
||||||
|
.fakesAndMocksModule(new FakesAndMocksModule(clock))
|
||||||
|
.build()
|
||||||
|
.startRequest()
|
||||||
|
.flowComponentBuilder()
|
||||||
|
.flowModule(new FlowModule.Builder()
|
||||||
|
.setSessionMetadata(sessionMetadata)
|
||||||
|
.setCredentials(new PasswordOnlyTransportCredentials())
|
||||||
|
.setEppRequestSource(EppRequestSource.UNIT_TEST)
|
||||||
|
.setIsDryRun(false)
|
||||||
|
.setIsSuperuser(false)
|
||||||
|
.setInputXmlBytes(eppLoader.getEppXml().getBytes(UTF_8))
|
||||||
|
.setEppInput(eppLoader.getEpp())
|
||||||
|
.build())
|
||||||
|
.build()
|
||||||
|
.flowRunner()
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadAtPointInTime() throws Exception {
|
||||||
|
clock.setTo(DateTime.parse("1984-12-18T12:30Z")); // not midnight
|
||||||
|
|
||||||
|
persistActiveHost("ns1.example.net");
|
||||||
|
persistActiveHost("ns2.example.net");
|
||||||
|
persistActiveContact("jd1234");
|
||||||
|
persistActiveContact("sh8013");
|
||||||
|
|
||||||
|
clock.advanceBy(standardDays(1));
|
||||||
|
DateTime timeAtCreate = clock.nowUtc();
|
||||||
|
clock.setTo(timeAtCreate);
|
||||||
|
eppLoader = new EppLoader(this, "domain_create.xml");
|
||||||
|
runFlow();
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
Key<DomainResource> key = Key.create(ofy().load().type(DomainResource.class).first().now());
|
||||||
|
DomainResource domainAfterCreate = ofy().load().key(key).now();
|
||||||
|
assertThat(domainAfterCreate.getFullyQualifiedDomainName()).isEqualTo("example.tld");
|
||||||
|
|
||||||
|
clock.advanceBy(standardDays(2));
|
||||||
|
DateTime timeAtFirstUpdate = clock.nowUtc();
|
||||||
|
eppLoader = new EppLoader(this, "domain_update_dsdata_add.xml");
|
||||||
|
runFlow();
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
|
||||||
|
DomainResource domainAfterFirstUpdate = ofy().load().key(key).now();
|
||||||
|
assertThat(domainAfterCreate).isNotEqualTo(domainAfterFirstUpdate);
|
||||||
|
|
||||||
|
clock.advanceOneMilli(); // same day as first update
|
||||||
|
DateTime timeAtSecondUpdate = clock.nowUtc();
|
||||||
|
eppLoader = new EppLoader(this, "domain_update_dsdata_rem.xml");
|
||||||
|
runFlow();
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
DomainResource domainAfterSecondUpdate = ofy().load().key(key).now();
|
||||||
|
|
||||||
|
clock.advanceBy(standardDays(2));
|
||||||
|
DateTime timeAtDelete = clock.nowUtc(); // before 'add' grace period ends
|
||||||
|
eppLoader = new EppLoader(this, "domain_delete.xml");
|
||||||
|
runFlow();
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
|
||||||
|
assertThat(domainAfterFirstUpdate).isNotEqualTo(domainAfterSecondUpdate);
|
||||||
|
|
||||||
|
// Point-in-time can only rewind an object from the current version, not roll forward.
|
||||||
|
DomainResource latest = ofy().load().key(key).now();
|
||||||
|
|
||||||
|
// Creation time has millisecond granularity due to isActive() check.
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtCreate.minusMillis(1)).now()).isNull();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtCreate).now()).isNotNull();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtCreate.plusMillis(1)).now()).isNotNull();
|
||||||
|
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtCreate.plusDays(1)).now())
|
||||||
|
.isEqualTo(domainAfterCreate);
|
||||||
|
|
||||||
|
// Both updates happened on the same day. Since the revisions field has day granularity, the
|
||||||
|
// reference to the first update should have been overwritten by the second, and its timestamp
|
||||||
|
// rolled forward. So we have to fall back to the last revision before midnight.
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtFirstUpdate).now())
|
||||||
|
.isEqualTo(domainAfterCreate);
|
||||||
|
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtSecondUpdate).now())
|
||||||
|
.isEqualTo(domainAfterSecondUpdate);
|
||||||
|
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtSecondUpdate.plusDays(1)).now())
|
||||||
|
.isEqualTo(domainAfterSecondUpdate);
|
||||||
|
|
||||||
|
// Deletion time has millisecond granularity due to isActive() check.
|
||||||
|
ofy().clearSessionCache();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtDelete.minusMillis(1)).now()).isNotNull();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtDelete).now()).isNull();
|
||||||
|
assertThat(loadAtPointInTime(latest, timeAtDelete.plusMillis(1)).now()).isNull();
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@
|
||||||
package google.registry.flows;
|
package google.registry.flows;
|
||||||
|
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
|
import static google.registry.testing.DatastoreHelper.createTlds;
|
||||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -44,7 +45,7 @@ public class EppLifecycleDomainTest extends EppTestCase {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void initTld() {
|
public void initTld() {
|
||||||
createTld("example");
|
createTlds("example", "tld");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create the two administrative contacts and two hosts. */
|
/** Create the two administrative contacts and two hosts. */
|
||||||
|
@ -129,7 +130,7 @@ public class EppLifecycleDomainTest extends EppTestCase {
|
||||||
"domain_create_response.xml",
|
"domain_create_response.xml",
|
||||||
DateTime.parse("2000-06-01T00:02:00Z"));
|
DateTime.parse("2000-06-01T00:02:00Z"));
|
||||||
|
|
||||||
// Delete domain example.com after its add grace period has expired.
|
// Delete domain example.tld after its add grace period has expired.
|
||||||
assertCommandAndResponse(
|
assertCommandAndResponse(
|
||||||
"domain_delete.xml",
|
"domain_delete.xml",
|
||||||
"generic_success_action_pending_response.xml",
|
"generic_success_action_pending_response.xml",
|
||||||
|
@ -338,7 +339,7 @@ public class EppLifecycleDomainTest extends EppTestCase {
|
||||||
DateTime.parse("2001-01-01T00:01:00Z"));
|
DateTime.parse("2001-01-01T00:01:00Z"));
|
||||||
assertCommandAndResponse(
|
assertCommandAndResponse(
|
||||||
"poll_ack.xml",
|
"poll_ack.xml",
|
||||||
ImmutableMap.of("ID", "1-A-EXAMPLE-16-20"),
|
ImmutableMap.of("ID", "1-B-EXAMPLE-17-21"),
|
||||||
"poll_ack_response_empty.xml",
|
"poll_ack_response_empty.xml",
|
||||||
null,
|
null,
|
||||||
DateTime.parse("2001-01-01T00:01:00Z"));
|
DateTime.parse("2001-01-01T00:01:00Z"));
|
||||||
|
@ -350,7 +351,7 @@ public class EppLifecycleDomainTest extends EppTestCase {
|
||||||
DateTime.parse("2001-01-06T00:01:00Z"));
|
DateTime.parse("2001-01-06T00:01:00Z"));
|
||||||
assertCommandAndResponse(
|
assertCommandAndResponse(
|
||||||
"poll_ack.xml",
|
"poll_ack.xml",
|
||||||
ImmutableMap.of("ID", "1-A-EXAMPLE-16-22"),
|
ImmutableMap.of("ID", "1-B-EXAMPLE-17-23"),
|
||||||
"poll_ack_response_empty.xml",
|
"poll_ack_response_empty.xml",
|
||||||
null,
|
null,
|
||||||
DateTime.parse("2001-01-06T00:01:00Z"));
|
DateTime.parse("2001-01-06T00:01:00Z"));
|
||||||
|
@ -366,7 +367,7 @@ public class EppLifecycleDomainTest extends EppTestCase {
|
||||||
DateTime.parse("2001-01-06T00:02:00Z"));
|
DateTime.parse("2001-01-06T00:02:00Z"));
|
||||||
assertCommandAndResponse(
|
assertCommandAndResponse(
|
||||||
"poll_ack.xml",
|
"poll_ack.xml",
|
||||||
ImmutableMap.of("ID", "1-A-EXAMPLE-16-21"),
|
ImmutableMap.of("ID", "1-B-EXAMPLE-17-22"),
|
||||||
"poll_ack_response_empty.xml",
|
"poll_ack_response_empty.xml",
|
||||||
null,
|
null,
|
||||||
DateTime.parse("2001-01-06T00:02:00Z"));
|
DateTime.parse("2001-01-06T00:02:00Z"));
|
||||||
|
|
|
@ -21,12 +21,11 @@ import static google.registry.xml.XmlTestUtils.assertXmlEqualsWithMessage;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||||
import static org.joda.time.DateTimeZone.UTC;
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
import com.google.common.net.MediaType;
|
import com.google.common.net.MediaType;
|
||||||
|
|
||||||
|
import google.registry.flows.EppTestComponent.FakesAndMocksModule;
|
||||||
import google.registry.model.ofy.Ofy;
|
import google.registry.model.ofy.Ofy;
|
||||||
import google.registry.monitoring.whitebox.EppMetrics;
|
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
import google.registry.testing.FakeHttpSession;
|
import google.registry.testing.FakeHttpSession;
|
||||||
import google.registry.testing.FakeResponse;
|
import google.registry.testing.FakeResponse;
|
||||||
|
@ -100,8 +99,7 @@ public class EppTestCase extends ShardableTestCase {
|
||||||
// When a session is invalidated, reset the sessionMetadata field.
|
// When a session is invalidated, reset the sessionMetadata field.
|
||||||
super.invalidate();
|
super.invalidate();
|
||||||
EppTestCase.this.sessionMetadata = null;
|
EppTestCase.this.sessionMetadata = null;
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
String actualOutput = executeXmlCommand(input);
|
String actualOutput = executeXmlCommand(input);
|
||||||
assertXmlEqualsWithMessage(
|
assertXmlEqualsWithMessage(
|
||||||
|
@ -118,14 +116,16 @@ public class EppTestCase extends ShardableTestCase {
|
||||||
EppRequestHandler handler = new EppRequestHandler();
|
EppRequestHandler handler = new EppRequestHandler();
|
||||||
FakeResponse response = new FakeResponse();
|
FakeResponse response = new FakeResponse();
|
||||||
handler.response = response;
|
handler.response = response;
|
||||||
handler.eppController = new EppController();
|
handler.eppController = DaggerEppTestComponent.builder()
|
||||||
handler.eppController.clock = clock;
|
.fakesAndMocksModule(new FakesAndMocksModule(clock))
|
||||||
handler.eppController.metrics = mock(EppMetrics.class);
|
.build()
|
||||||
|
.startRequest()
|
||||||
|
.eppController();
|
||||||
handler.executeEpp(
|
handler.executeEpp(
|
||||||
sessionMetadata,
|
sessionMetadata,
|
||||||
credentials,
|
credentials,
|
||||||
EppRequestSource.UNIT_TEST,
|
EppRequestSource.UNIT_TEST,
|
||||||
false,
|
false, // Not dryRun.
|
||||||
isSuperuser,
|
isSuperuser,
|
||||||
inputXml.getBytes(UTF_8));
|
inputXml.getBytes(UTF_8));
|
||||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||||
|
|
70
javatests/google/registry/flows/EppTestComponent.java
Normal file
70
javatests/google/registry/flows/EppTestComponent.java
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2016 The Domain Registry 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.flows;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import dagger.Component;
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
import dagger.Subcomponent;
|
||||||
|
|
||||||
|
import google.registry.monitoring.whitebox.EppMetrics;
|
||||||
|
import google.registry.request.RequestScope;
|
||||||
|
import google.registry.testing.FakeClock;
|
||||||
|
import google.registry.util.Clock;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
/** Dagger component for running EPP tests. */
|
||||||
|
@Singleton
|
||||||
|
@Component(
|
||||||
|
modules = {
|
||||||
|
EppTestComponent.FakesAndMocksModule.class
|
||||||
|
})
|
||||||
|
interface EppTestComponent {
|
||||||
|
|
||||||
|
RequestComponent startRequest();
|
||||||
|
|
||||||
|
/** Module for injecting fakes and mocks. */
|
||||||
|
@Module
|
||||||
|
static class FakesAndMocksModule {
|
||||||
|
final FakeClock clock;
|
||||||
|
final EppMetrics metrics;
|
||||||
|
|
||||||
|
FakesAndMocksModule(FakeClock clock) {
|
||||||
|
this.clock = clock;
|
||||||
|
this.metrics = mock(EppMetrics.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
Clock provideClock() {
|
||||||
|
return clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
EppMetrics provideMetrics() {
|
||||||
|
return metrics;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Subcomponent for request scoped injections. */
|
||||||
|
@RequestScope
|
||||||
|
@Subcomponent
|
||||||
|
interface RequestComponent {
|
||||||
|
EppController eppController();
|
||||||
|
FlowComponent.Builder flowComponentBuilder();
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,13 +34,12 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import google.registry.flows.EppTestComponent.FakesAndMocksModule;
|
||||||
import google.registry.flows.picker.FlowPicker;
|
import google.registry.flows.picker.FlowPicker;
|
||||||
import google.registry.model.billing.BillingEvent;
|
import google.registry.model.billing.BillingEvent;
|
||||||
import google.registry.model.domain.GracePeriod;
|
import google.registry.model.domain.GracePeriod;
|
||||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||||
import google.registry.model.eppcommon.ProtocolDefinition;
|
import google.registry.model.eppcommon.ProtocolDefinition;
|
||||||
import google.registry.model.eppcommon.Trid;
|
|
||||||
import google.registry.model.eppinput.EppInput;
|
|
||||||
import google.registry.model.eppoutput.EppOutput;
|
import google.registry.model.eppoutput.EppOutput;
|
||||||
import google.registry.model.ofy.Ofy;
|
import google.registry.model.ofy.Ofy;
|
||||||
import google.registry.model.poll.PollMessage;
|
import google.registry.model.poll.PollMessage;
|
||||||
|
@ -86,8 +85,6 @@ public abstract class FlowTestCase<F extends Flow> {
|
||||||
@Rule
|
@Rule
|
||||||
public final InjectRule inject = new InjectRule();
|
public final InjectRule inject = new InjectRule();
|
||||||
|
|
||||||
private Class<? extends Flow> flowClass;
|
|
||||||
|
|
||||||
protected EppLoader eppLoader;
|
protected EppLoader eppLoader;
|
||||||
protected SessionMetadata sessionMetadata;
|
protected SessionMetadata sessionMetadata;
|
||||||
protected FakeClock clock = new FakeClock(DateTime.now(UTC));
|
protected FakeClock clock = new FakeClock(DateTime.now(UTC));
|
||||||
|
@ -120,29 +117,8 @@ public abstract class FlowTestCase<F extends Flow> {
|
||||||
return readResourceUtf8(getClass(), "testdata/" + filename);
|
return readResourceUtf8(getClass(), "testdata/" + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Load a flow from an epp object. */
|
protected String getClientTrid() throws Exception {
|
||||||
private FlowRunner getFlowRunner(CommitMode commitMode, UserPrivileges userPrivileges)
|
return eppLoader.getEpp().getCommandWrapper().getClTrid();
|
||||||
throws Exception {
|
|
||||||
EppInput eppInput = eppLoader.getEpp();
|
|
||||||
flowClass = firstNonNull(flowClass, FlowPicker.getFlowClass(eppInput));
|
|
||||||
Class<?> expectedFlowClass = new TypeInstantiator<F>(getClass()){}.getExactType();
|
|
||||||
assertThat(flowClass).isEqualTo(expectedFlowClass);
|
|
||||||
return new FlowRunner(
|
|
||||||
flowClass,
|
|
||||||
eppInput,
|
|
||||||
getTrid(),
|
|
||||||
sessionMetadata,
|
|
||||||
credentials,
|
|
||||||
eppRequestSource,
|
|
||||||
commitMode.equals(CommitMode.DRY_RUN),
|
|
||||||
userPrivileges.equals(UserPrivileges.SUPERUSER),
|
|
||||||
"<xml></xml>".getBytes(),
|
|
||||||
null,
|
|
||||||
clock);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Trid getTrid() throws Exception {
|
|
||||||
return Trid.create(eppLoader.getEpp().getCommandWrapper().getClTrid(), "server-trid");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the client ID that the flow will run as. */
|
/** Gets the client ID that the flow will run as. */
|
||||||
|
@ -156,8 +132,15 @@ public abstract class FlowTestCase<F extends Flow> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertTransactionalFlow(boolean isTransactional) throws Exception {
|
public void assertTransactionalFlow(boolean isTransactional) throws Exception {
|
||||||
assertThat(getFlowRunner(CommitMode.LIVE, UserPrivileges.NORMAL).isTransactional())
|
Class<? extends Flow> flowClass = FlowPicker.getFlowClass(eppLoader.getEpp());
|
||||||
.isEqualTo(isTransactional);
|
if (isTransactional) {
|
||||||
|
assertThat(flowClass).isAssignableTo(TransactionalFlow.class);
|
||||||
|
} else {
|
||||||
|
// There's no "isNotAssignableTo" in Truth.
|
||||||
|
assertThat(TransactionalFlow.class.isAssignableFrom(flowClass))
|
||||||
|
.named(flowClass.getSimpleName() + " implements TransactionalFlow")
|
||||||
|
.isFalse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertNoHistory() throws Exception {
|
public void assertNoHistory() throws Exception {
|
||||||
|
@ -273,36 +256,67 @@ public abstract class FlowTestCase<F extends Flow> {
|
||||||
.containsExactlyElementsIn(FluentIterable.from(asList(expected)).transform(idStripper));
|
.containsExactlyElementsIn(FluentIterable.from(asList(expected)).transform(idStripper));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Run a flow, and attempt to marshal the result to EPP or throw if it doesn't validate. */
|
private EppOutput runFlowInternal(CommitMode commitMode, UserPrivileges userPrivileges)
|
||||||
|
throws Exception {
|
||||||
|
// Assert that the xml triggers the flow we expect.
|
||||||
|
assertThat(FlowPicker.getFlowClass(eppLoader.getEpp()))
|
||||||
|
.isEqualTo(new TypeInstantiator<F>(getClass()){}.getExactType());
|
||||||
|
// Run the flow.
|
||||||
|
return DaggerEppTestComponent.builder()
|
||||||
|
.fakesAndMocksModule(new FakesAndMocksModule(clock))
|
||||||
|
.build()
|
||||||
|
.startRequest()
|
||||||
|
.flowComponentBuilder()
|
||||||
|
.flowModule(new FlowModule.Builder()
|
||||||
|
.setSessionMetadata(sessionMetadata)
|
||||||
|
.setCredentials(credentials)
|
||||||
|
.setEppRequestSource(eppRequestSource)
|
||||||
|
.setIsDryRun(commitMode.equals(CommitMode.DRY_RUN))
|
||||||
|
.setIsSuperuser(userPrivileges.equals(UserPrivileges.SUPERUSER))
|
||||||
|
.setInputXmlBytes(eppLoader.getEppXml().getBytes(UTF_8))
|
||||||
|
.setEppInput(eppLoader.getEpp())
|
||||||
|
.build())
|
||||||
|
.build()
|
||||||
|
.flowRunner()
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Run a flow and marshal the result to EPP, or throw if it doesn't validate. */
|
||||||
public EppOutput runFlow(CommitMode commitMode, UserPrivileges userPrivileges) throws Exception {
|
public EppOutput runFlow(CommitMode commitMode, UserPrivileges userPrivileges) throws Exception {
|
||||||
EppOutput output = getFlowRunner(commitMode, userPrivileges).run();
|
EppOutput output = runFlowInternal(commitMode, userPrivileges);
|
||||||
marshal(output, ValidationMode.STRICT);
|
marshal(output, ValidationMode.STRICT);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shortcut to call {@link #runFlow(CommitMode, UserPrivileges)} as normal user and live run. */
|
||||||
public EppOutput runFlow() throws Exception {
|
public EppOutput runFlow() throws Exception {
|
||||||
return runFlow(CommitMode.LIVE, UserPrivileges.NORMAL);
|
return runFlow(CommitMode.LIVE, UserPrivileges.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Run a flow, marshal the result to EPP, and assert that the output is as expected. */
|
||||||
public void runFlowAssertResponse(
|
public void runFlowAssertResponse(
|
||||||
CommitMode commitMode, UserPrivileges userPrivileges, String xml, String... ignoredPaths)
|
CommitMode commitMode, UserPrivileges userPrivileges, String xml, String... ignoredPaths)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
EppOutput eppOutput = getFlowRunner(commitMode, userPrivileges).run();
|
// Always ignore the server trid, since it's generated and meaningless to flow correctness.
|
||||||
if (eppOutput.isResponse()) {
|
String[] ignoredPathsPlusTrid = FluentIterable.from(ignoredPaths)
|
||||||
assertThat(eppOutput.isSuccess()).isTrue();
|
.append("epp.response.trID.svTRID")
|
||||||
|
.toArray(String.class);
|
||||||
|
EppOutput output = runFlowInternal(commitMode, userPrivileges);
|
||||||
|
if (output.isResponse()) {
|
||||||
|
assertThat(output.isSuccess()).isTrue();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
assertXmlEquals(
|
assertXmlEquals(
|
||||||
xml, new String(marshal(eppOutput, ValidationMode.STRICT), UTF_8), ignoredPaths);
|
xml, new String(marshal(output, ValidationMode.STRICT), UTF_8), ignoredPathsPlusTrid);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
assertXmlEquals(
|
assertXmlEquals(
|
||||||
xml, new String(marshal(eppOutput, ValidationMode.LENIENT), UTF_8), ignoredPaths);
|
xml, new String(marshal(output, ValidationMode.LENIENT), UTF_8), ignoredPathsPlusTrid);
|
||||||
// If it was a marshaling error, augment the output.
|
// If it was a marshaling error, augment the output.
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
String.format(
|
String.format(
|
||||||
"Invalid xml.\nExpected:\n%s\n\nActual:\n%s\n",
|
"Invalid xml.\nExpected:\n%s\n\nActual:\n%s\n",
|
||||||
xml,
|
xml,
|
||||||
marshal(eppOutput, ValidationMode.LENIENT)),
|
marshal(output, ValidationMode.LENIENT)),
|
||||||
e);
|
e);
|
||||||
}
|
}
|
||||||
// Clear the cache so that we don't see stale results in tests.
|
// Clear the cache so that we don't see stale results in tests.
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class ContactTransferRequestFlowTest
|
||||||
.hasTransferStatus(TransferStatus.PENDING).and()
|
.hasTransferStatus(TransferStatus.PENDING).and()
|
||||||
.hasTransferGainingClientId("NewRegistrar").and()
|
.hasTransferGainingClientId("NewRegistrar").and()
|
||||||
.hasTransferLosingClientId("TheRegistrar").and()
|
.hasTransferLosingClientId("TheRegistrar").and()
|
||||||
.hasTransferRequestTrid(getTrid()).and()
|
.hasTransferRequestClientTrid(getClientTrid()).and()
|
||||||
.hasCurrentSponsorClientId("TheRegistrar").and()
|
.hasCurrentSponsorClientId("TheRegistrar").and()
|
||||||
.hasPendingTransferExpirationTime(afterTransfer).and()
|
.hasPendingTransferExpirationTime(afterTransfer).and()
|
||||||
.hasOnlyOneHistoryEntryWhich()
|
.hasOnlyOneHistoryEntryWhich()
|
||||||
|
|
|
@ -64,7 +64,6 @@ import google.registry.model.domain.GracePeriod;
|
||||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||||
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||||
import google.registry.model.eppcommon.StatusValue;
|
import google.registry.model.eppcommon.StatusValue;
|
||||||
import google.registry.model.eppcommon.Trid;
|
|
||||||
import google.registry.model.poll.PendingActionNotificationResponse;
|
import google.registry.model.poll.PendingActionNotificationResponse;
|
||||||
import google.registry.model.poll.PollMessage;
|
import google.registry.model.poll.PollMessage;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
|
@ -95,7 +94,7 @@ public class DomainTransferRequestFlowTest
|
||||||
.hasTransferStatus(TransferStatus.PENDING).and()
|
.hasTransferStatus(TransferStatus.PENDING).and()
|
||||||
.hasTransferGainingClientId("NewRegistrar").and()
|
.hasTransferGainingClientId("NewRegistrar").and()
|
||||||
.hasTransferLosingClientId("TheRegistrar").and()
|
.hasTransferLosingClientId("TheRegistrar").and()
|
||||||
.hasTransferRequestTrid(getTrid()).and()
|
.hasTransferRequestClientTrid(getClientTrid()).and()
|
||||||
.hasCurrentSponsorClientId("TheRegistrar").and()
|
.hasCurrentSponsorClientId("TheRegistrar").and()
|
||||||
.hasPendingTransferExpirationTime(
|
.hasPendingTransferExpirationTime(
|
||||||
clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength())).and()
|
clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength())).and()
|
||||||
|
@ -228,8 +227,7 @@ public class DomainTransferRequestFlowTest
|
||||||
PendingActionNotificationResponse panData = Iterables.getOnlyElement(FluentIterable
|
PendingActionNotificationResponse panData = Iterables.getOnlyElement(FluentIterable
|
||||||
.from(transferApprovedPollMessage.getResponseData())
|
.from(transferApprovedPollMessage.getResponseData())
|
||||||
.filter(PendingActionNotificationResponse.class));
|
.filter(PendingActionNotificationResponse.class));
|
||||||
assertThat(panData.getTrid())
|
assertThat(panData.getTrid().getClientTransactionId()).isEqualTo("ABC-12345");
|
||||||
.isEqualTo(Trid.create("ABC-12345", "server-trid"));
|
|
||||||
assertThat(panData.getActionResult()).isTrue();
|
assertThat(panData.getActionResult()).isTrue();
|
||||||
|
|
||||||
// Two poll messages on the losing registrar's side at the implicit transfer time: a
|
// Two poll messages on the losing registrar's side at the implicit transfer time: a
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<create>
|
<create>
|
||||||
<domain:create
|
<domain:create
|
||||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
<domain:name>example.example</domain:name>
|
<domain:name>example.tld</domain:name>
|
||||||
<domain:period unit="y">2</domain:period>
|
<domain:period unit="y">2</domain:period>
|
||||||
<domain:registrant>jd1234</domain:registrant>
|
<domain:registrant>jd1234</domain:registrant>
|
||||||
<domain:contact type="admin">sh8013</domain:contact>
|
<domain:contact type="admin">sh8013</domain:contact>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<resData>
|
<resData>
|
||||||
<domain:creData
|
<domain:creData
|
||||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
<domain:name>example.example</domain:name>
|
<domain:name>example.tld</domain:name>
|
||||||
<domain:crDate>2000-06-01T00:02:00.0Z</domain:crDate>
|
<domain:crDate>2000-06-01T00:02:00.0Z</domain:crDate>
|
||||||
<domain:exDate>2002-06-01T00:02:00.0Z</domain:exDate>
|
<domain:exDate>2002-06-01T00:02:00.0Z</domain:exDate>
|
||||||
</domain:creData>
|
</domain:creData>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<delete>
|
<delete>
|
||||||
<domain:delete
|
<domain:delete
|
||||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
<domain:name>example.example</domain:name>
|
<domain:name>example.tld</domain:name>
|
||||||
</domain:delete>
|
</domain:delete>
|
||||||
</delete>
|
</delete>
|
||||||
<clTRID>ABC-12345</clTRID>
|
<clTRID>ABC-12345</clTRID>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<info>
|
<info>
|
||||||
<domain:info
|
<domain:info
|
||||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
<domain:name hosts="all">example.example</domain:name>
|
<domain:name hosts="all">example.tld</domain:name>
|
||||||
</domain:info>
|
</domain:info>
|
||||||
</info>
|
</info>
|
||||||
<clTRID>ABC-12345</clTRID>
|
<clTRID>ABC-12345</clTRID>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<resData>
|
<resData>
|
||||||
<domain:infData
|
<domain:infData
|
||||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
<domain:name>example.example</domain:name>
|
<domain:name>example.tld</domain:name>
|
||||||
<domain:roid>%ROID%</domain:roid>
|
<domain:roid>%ROID%</domain:roid>
|
||||||
<domain:status s="inactive"/>
|
<domain:status s="inactive"/>
|
||||||
<domain:status s="pendingDelete"/>
|
<domain:status s="pendingDelete"/>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<update>
|
<update>
|
||||||
<domain:update
|
<domain:update
|
||||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
<domain:name>example.example</domain:name>
|
<domain:name>example.tld</domain:name>
|
||||||
<domain:chg/>
|
<domain:chg/>
|
||||||
</domain:update>
|
</domain:update>
|
||||||
</update>
|
</update>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<result code="1301">
|
<result code="1301">
|
||||||
<msg>Command completed successfully; ack to dequeue</msg>
|
<msg>Command completed successfully; ack to dequeue</msg>
|
||||||
</result>
|
</result>
|
||||||
<msgQ count="1" id="1-A-EXAMPLE-16-20">
|
<msgQ count="1" id="1-B-EXAMPLE-17-21">
|
||||||
<qDate>2001-01-01T00:00:00Z</qDate>
|
<qDate>2001-01-01T00:00:00Z</qDate>
|
||||||
<msg>Transfer requested.</msg>
|
<msg>Transfer requested.</msg>
|
||||||
</msgQ>
|
</msgQ>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<result code="1301">
|
<result code="1301">
|
||||||
<msg>Command completed successfully; ack to dequeue</msg>
|
<msg>Command completed successfully; ack to dequeue</msg>
|
||||||
</result>
|
</result>
|
||||||
<msgQ count="1" id="1-A-EXAMPLE-16-22">
|
<msgQ count="1" id="1-B-EXAMPLE-17-23">
|
||||||
<qDate>2001-01-06T00:00:00Z</qDate>
|
<qDate>2001-01-06T00:00:00Z</qDate>
|
||||||
<msg>Transfer approved.</msg>
|
<msg>Transfer approved.</msg>
|
||||||
</msgQ>
|
</msgQ>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<result code="1301">
|
<result code="1301">
|
||||||
<msg>Command completed successfully; ack to dequeue</msg>
|
<msg>Command completed successfully; ack to dequeue</msg>
|
||||||
</result>
|
</result>
|
||||||
<msgQ count="1" id="1-A-EXAMPLE-16-21">
|
<msgQ count="1" id="1-B-EXAMPLE-17-22">
|
||||||
<qDate>2001-01-06T00:00:00Z</qDate>
|
<qDate>2001-01-06T00:00:00Z</qDate>
|
||||||
<msg>Transfer approved.</msg>
|
<msg>Transfer approved.</msg>
|
||||||
</msgQ>
|
</msgQ>
|
||||||
|
|
|
@ -15,35 +15,19 @@
|
||||||
package google.registry.model;
|
package google.registry.model;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.flows.picker.FlowPicker.getFlowClass;
|
|
||||||
import static google.registry.model.EppResourceUtils.loadAtPointInTime;
|
import static google.registry.model.EppResourceUtils.loadAtPointInTime;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.newHostResource;
|
import static google.registry.testing.DatastoreHelper.newHostResource;
|
||||||
import static google.registry.testing.DatastoreHelper.persistActiveContact;
|
|
||||||
import static google.registry.testing.DatastoreHelper.persistActiveHost;
|
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||||
import static google.registry.testing.DatastoreHelper.persistResourceWithCommitLog;
|
import static google.registry.testing.DatastoreHelper.persistResourceWithCommitLog;
|
||||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
import static org.joda.time.DateTimeZone.UTC;
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
import static org.joda.time.Duration.standardDays;
|
|
||||||
|
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
|
|
||||||
import google.registry.flows.EppRequestSource;
|
|
||||||
import google.registry.flows.FlowRunner;
|
|
||||||
import google.registry.flows.HttpSessionMetadata;
|
|
||||||
import google.registry.flows.PasswordOnlyTransportCredentials;
|
|
||||||
import google.registry.flows.SessionMetadata;
|
|
||||||
import google.registry.model.domain.DomainResource;
|
|
||||||
import google.registry.model.eppcommon.Trid;
|
|
||||||
import google.registry.model.host.HostResource;
|
import google.registry.model.host.HostResource;
|
||||||
import google.registry.model.ofy.Ofy;
|
import google.registry.model.ofy.Ofy;
|
||||||
import google.registry.testing.AppEngineRule;
|
import google.registry.testing.AppEngineRule;
|
||||||
import google.registry.testing.EppLoader;
|
|
||||||
import google.registry.testing.ExceptionRule;
|
import google.registry.testing.ExceptionRule;
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
import google.registry.testing.FakeHttpSession;
|
|
||||||
import google.registry.testing.InjectRule;
|
import google.registry.testing.InjectRule;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
@ -71,7 +55,6 @@ public class EppResourceUtilsTest {
|
||||||
public final InjectRule inject = new InjectRule();
|
public final InjectRule inject = new InjectRule();
|
||||||
|
|
||||||
private final FakeClock clock = new FakeClock(DateTime.now(UTC));
|
private final FakeClock clock = new FakeClock(DateTime.now(UTC));
|
||||||
private EppLoader eppLoader;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
|
@ -79,103 +62,6 @@ public class EppResourceUtilsTest {
|
||||||
inject.setStaticField(Ofy.class, "clock", clock);
|
inject.setStaticField(Ofy.class, "clock", clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runFlow() throws Exception {
|
|
||||||
SessionMetadata sessionMetadata = new HttpSessionMetadata(new FakeHttpSession());
|
|
||||||
sessionMetadata.setClientId("TheRegistrar");
|
|
||||||
new FlowRunner(
|
|
||||||
getFlowClass(eppLoader.getEpp()),
|
|
||||||
eppLoader.getEpp(),
|
|
||||||
Trid.create(null, "server-trid"),
|
|
||||||
sessionMetadata,
|
|
||||||
new PasswordOnlyTransportCredentials(),
|
|
||||||
EppRequestSource.UNIT_TEST,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
"<xml></xml>".getBytes(),
|
|
||||||
null,
|
|
||||||
clock)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test that update flow creates commit logs needed to reload at any arbitrary time. */
|
|
||||||
@Test
|
|
||||||
public void testLoadAtPointInTime() throws Exception {
|
|
||||||
clock.setTo(DateTime.parse("1984-12-18T12:30Z")); // not midnight
|
|
||||||
|
|
||||||
persistActiveHost("ns1.example.net");
|
|
||||||
persistActiveHost("ns2.example.net");
|
|
||||||
persistActiveContact("jd1234");
|
|
||||||
persistActiveContact("sh8013");
|
|
||||||
|
|
||||||
clock.advanceBy(standardDays(1));
|
|
||||||
DateTime timeAtCreate = clock.nowUtc();
|
|
||||||
clock.setTo(timeAtCreate);
|
|
||||||
eppLoader = new EppLoader(this, "domain_create.xml");
|
|
||||||
runFlow();
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
Key<DomainResource> key = Key.create(ofy().load().type(DomainResource.class).first().now());
|
|
||||||
DomainResource domainAfterCreate = ofy().load().key(key).now();
|
|
||||||
assertThat(domainAfterCreate.getFullyQualifiedDomainName()).isEqualTo("example.tld");
|
|
||||||
|
|
||||||
clock.advanceBy(standardDays(2));
|
|
||||||
DateTime timeAtFirstUpdate = clock.nowUtc();
|
|
||||||
eppLoader = new EppLoader(this, "domain_update_dsdata_add.xml");
|
|
||||||
runFlow();
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
|
|
||||||
DomainResource domainAfterFirstUpdate = ofy().load().key(key).now();
|
|
||||||
assertThat(domainAfterCreate).isNotEqualTo(domainAfterFirstUpdate);
|
|
||||||
|
|
||||||
clock.advanceOneMilli(); // same day as first update
|
|
||||||
DateTime timeAtSecondUpdate = clock.nowUtc();
|
|
||||||
eppLoader = new EppLoader(this, "domain_update_dsdata_rem.xml");
|
|
||||||
runFlow();
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
DomainResource domainAfterSecondUpdate = ofy().load().key(key).now();
|
|
||||||
|
|
||||||
clock.advanceBy(standardDays(2));
|
|
||||||
DateTime timeAtDelete = clock.nowUtc(); // before 'add' grace period ends
|
|
||||||
eppLoader = new EppLoader(this, "domain_delete.xml");
|
|
||||||
runFlow();
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
|
|
||||||
assertThat(domainAfterFirstUpdate).isNotEqualTo(domainAfterSecondUpdate);
|
|
||||||
|
|
||||||
// Point-in-time can only rewind an object from the current version, not roll forward.
|
|
||||||
DomainResource latest = ofy().load().key(key).now();
|
|
||||||
|
|
||||||
// Creation time has millisecond granularity due to isActive() check.
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtCreate.minusMillis(1)).now()).isNull();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtCreate).now()).isNotNull();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtCreate.plusMillis(1)).now()).isNotNull();
|
|
||||||
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtCreate.plusDays(1)).now())
|
|
||||||
.isEqualTo(domainAfterCreate);
|
|
||||||
|
|
||||||
// Both updates happened on the same day. Since the revisions field has day granularity, the
|
|
||||||
// reference to the first update should have been overwritten by the second, and its timestamp
|
|
||||||
// rolled forward. So we have to fall back to the last revision before midnight.
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtFirstUpdate).now())
|
|
||||||
.isEqualTo(domainAfterCreate);
|
|
||||||
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtSecondUpdate).now())
|
|
||||||
.isEqualTo(domainAfterSecondUpdate);
|
|
||||||
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtSecondUpdate.plusDays(1)).now())
|
|
||||||
.isEqualTo(domainAfterSecondUpdate);
|
|
||||||
|
|
||||||
// Deletion time has millisecond granularity due to isActive() check.
|
|
||||||
ofy().clearSessionCache();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtDelete.minusMillis(1)).now()).isNotNull();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtDelete).now()).isNull();
|
|
||||||
assertThat(loadAtPointInTime(latest, timeAtDelete.plusMillis(1)).now()).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLoadAtPointInTime_beforeCreated_returnsNull() throws Exception {
|
public void testLoadAtPointInTime_beforeCreated_returnsNull() throws Exception {
|
||||||
clock.advanceOneMilli();
|
clock.advanceOneMilli();
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
|
||||||
<command>
|
|
||||||
<delete>
|
|
||||||
<domain:delete
|
|
||||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
|
||||||
<domain:name>example.tld</domain:name>
|
|
||||||
</domain:delete>
|
|
||||||
</delete>
|
|
||||||
<clTRID>ABC-12345</clTRID>
|
|
||||||
</command>
|
|
||||||
</epp>
|
|
|
@ -26,7 +26,6 @@ import com.google.common.truth.Subject;
|
||||||
|
|
||||||
import google.registry.model.EppResource;
|
import google.registry.model.EppResource;
|
||||||
import google.registry.model.eppcommon.StatusValue;
|
import google.registry.model.eppcommon.StatusValue;
|
||||||
import google.registry.model.eppcommon.Trid;
|
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.model.transfer.TransferStatus;
|
import google.registry.model.transfer.TransferStatus;
|
||||||
import google.registry.testing.TruthChainer.And;
|
import google.registry.testing.TruthChainer.And;
|
||||||
|
@ -205,10 +204,10 @@ abstract class AbstractEppResourceSubject
|
||||||
"has transferStatus");
|
"has transferStatus");
|
||||||
}
|
}
|
||||||
|
|
||||||
public And<S> hasTransferRequestTrid(Trid trid) {
|
public And<S> hasTransferRequestClientTrid(String clTrid) {
|
||||||
return hasValue(
|
return hasValue(
|
||||||
trid,
|
clTrid,
|
||||||
getSubject().getTransferData().getTransferRequestTrid(),
|
getSubject().getTransferData().getTransferRequestTrid().getClientTransactionId(),
|
||||||
"has trid");
|
"has trid");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue