mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 12:07:51 +02:00
292 lines
8.2 KiB
Java
292 lines
8.2 KiB
Java
// Copyright 2016 The Nomulus Authors. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package google.registry.flows;
|
|
|
|
import static com.google.common.base.Preconditions.checkState;
|
|
import static com.google.common.base.Strings.nullToEmpty;
|
|
|
|
import com.google.common.base.Optional;
|
|
import com.google.common.base.Strings;
|
|
import dagger.Module;
|
|
import dagger.Provides;
|
|
import google.registry.flows.exceptions.OnlyToolCanPassMetadataException;
|
|
import google.registry.flows.picker.FlowPicker;
|
|
import google.registry.model.domain.launch.ApplicationIdTargetExtension;
|
|
import google.registry.model.domain.metadata.MetadataExtension;
|
|
import google.registry.model.eppcommon.AuthInfo;
|
|
import google.registry.model.eppcommon.Trid;
|
|
import google.registry.model.eppinput.EppInput;
|
|
import google.registry.model.eppinput.EppInput.Poll;
|
|
import google.registry.model.eppinput.EppInput.ResourceCommandWrapper;
|
|
import google.registry.model.eppinput.ResourceCommand;
|
|
import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand;
|
|
import google.registry.model.reporting.HistoryEntry;
|
|
import java.lang.annotation.Documented;
|
|
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
|
|
@ClientId
|
|
static String provideClientId(SessionMetadata sessionMetadata) {
|
|
// Treat a missing clientId as null so we can always inject a non-null value. All we do with the
|
|
// clientId is log it (as "") or detect its absence, both of which work fine with empty.
|
|
return Strings.nullToEmpty(sessionMetadata.getClientId());
|
|
}
|
|
|
|
@Provides
|
|
@FlowScope
|
|
static Trid provideTrid(EppInput eppInput) {
|
|
return Trid.create(eppInput.getCommandWrapper().getClTrid());
|
|
}
|
|
|
|
@Provides
|
|
@FlowScope
|
|
static Class<? extends Flow> provideFlowClass(EppInput eppInput) {
|
|
try {
|
|
return FlowPicker.getFlowClass(eppInput);
|
|
} catch (EppException e) {
|
|
throw new EppExceptionInProviderException(e);
|
|
}
|
|
}
|
|
|
|
@Provides
|
|
@FlowScope
|
|
static ResourceCommand provideResourceCommand(EppInput eppInput) {
|
|
return ((ResourceCommandWrapper) eppInput.getCommandWrapper().getCommand())
|
|
.getResourceCommand();
|
|
}
|
|
|
|
@Provides
|
|
@FlowScope
|
|
static Optional<AuthInfo> provideAuthInfo(ResourceCommand resourceCommand) {
|
|
return Optional.fromNullable(((SingleResourceCommand) resourceCommand).getAuthInfo());
|
|
}
|
|
|
|
@Provides
|
|
@FlowScope
|
|
@TargetId
|
|
static String provideTargetId(ResourceCommand resourceCommand) {
|
|
return ((SingleResourceCommand) resourceCommand).getTargetId();
|
|
}
|
|
|
|
@Provides
|
|
@FlowScope
|
|
@ApplicationId
|
|
static String provideApplicationId(EppInput eppInput) {
|
|
// Treat a missing application id as empty so we can always inject a non-null value.
|
|
return nullToEmpty(
|
|
eppInput.getSingleExtension(ApplicationIdTargetExtension.class).getApplicationId());
|
|
}
|
|
|
|
@Provides
|
|
@FlowScope
|
|
@PollMessageId
|
|
static String providePollMessageId(EppInput eppInput) {
|
|
return Strings.nullToEmpty(((Poll) eppInput.getCommandWrapper().getCommand()).getMessageId());
|
|
}
|
|
|
|
/**
|
|
* Provides a partially filled in {@link HistoryEntry} builder.
|
|
*
|
|
* <p>This is not marked with {@link FlowScope} so that each retry gets a fresh one. Otherwise,
|
|
* the fact that the builder is one-use would cause NPEs.
|
|
*/
|
|
@Provides
|
|
static HistoryEntry.Builder provideHistoryEntryBuilder(
|
|
Trid trid,
|
|
@InputXml byte[] inputXmlBytes,
|
|
@Superuser boolean isSuperuser,
|
|
@ClientId String clientId,
|
|
EppRequestSource eppRequestSource,
|
|
EppInput eppInput) {
|
|
HistoryEntry.Builder historyBuilder = new HistoryEntry.Builder()
|
|
.setTrid(trid)
|
|
.setXmlBytes(inputXmlBytes)
|
|
.setBySuperuser(isSuperuser)
|
|
.setClientId(clientId);
|
|
MetadataExtension metadataExtension = eppInput.getSingleExtension(MetadataExtension.class);
|
|
if (metadataExtension != null) {
|
|
if (!eppRequestSource.equals(EppRequestSource.TOOL)) {
|
|
throw new EppExceptionInProviderException(new OnlyToolCanPassMetadataException());
|
|
}
|
|
historyBuilder
|
|
.setReason(metadataExtension.getReason())
|
|
.setRequestedByRegistrar(metadataExtension.getRequestedByRegistrar());
|
|
}
|
|
return historyBuilder;
|
|
}
|
|
|
|
/** 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 the target id (foreign key) for single resource flows. */
|
|
@Qualifier
|
|
@Documented
|
|
public @interface TargetId {}
|
|
|
|
/** Dagger qualifier for the application id for domain application flows. */
|
|
@Qualifier
|
|
@Documented
|
|
public @interface ApplicationId {}
|
|
|
|
/** Dagger qualifier for the message id for poll flows. */
|
|
@Qualifier
|
|
@Documented
|
|
public @interface PollMessageId {}
|
|
|
|
/** 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 {}
|
|
}
|